@intentic/sandbox-contract 1.322.0 → 1.324.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/README.md +7 -0
- package/dist/contracts/agent.contract.d.ts +109 -6
- package/dist/contracts/agent.contract.d.ts.map +1 -1
- package/dist/contracts/agent.contract.js +13 -3
- package/dist/contracts/agent.contract.js.map +1 -1
- package/dist/contracts/agents.contract.d.ts +124 -0
- package/dist/contracts/agents.contract.d.ts.map +1 -1
- package/dist/contracts/approvals.contract.d.ts +31 -0
- package/dist/contracts/approvals.contract.d.ts.map +1 -1
- package/dist/contracts/approvals.contract.js +2 -2
- package/dist/contracts/approvals.contract.js.map +1 -1
- package/dist/contracts/capabilities.contract.d.ts +2 -0
- package/dist/contracts/capabilities.contract.d.ts.map +1 -1
- package/dist/contracts/loops.contract.d.ts +2 -0
- package/dist/contracts/loops.contract.d.ts.map +1 -1
- package/dist/contracts/needs.contract.d.ts +4 -0
- package/dist/contracts/needs.contract.d.ts.map +1 -1
- package/dist/contracts/privacy.contract.d.ts +187 -0
- package/dist/contracts/privacy.contract.d.ts.map +1 -0
- package/dist/contracts/privacy.contract.js +76 -0
- package/dist/contracts/privacy.contract.js.map +1 -0
- package/dist/contracts/runner.contract.d.ts +167 -122
- package/dist/contracts/runner.contract.d.ts.map +1 -1
- package/dist/contracts/sessions.contract.d.ts +11 -0
- package/dist/contracts/sessions.contract.d.ts.map +1 -1
- package/dist/contracts/settings.contract.d.ts +74 -0
- package/dist/contracts/settings.contract.d.ts.map +1 -1
- package/dist/contracts/system.contract.d.ts +90 -32
- package/dist/contracts/system.contract.d.ts.map +1 -1
- package/dist/contracts/system.contract.js +11 -1
- package/dist/contracts/system.contract.js.map +1 -1
- package/dist/contracts/usage.contract.d.ts +1 -0
- package/dist/contracts/usage.contract.d.ts.map +1 -1
- package/dist/contracts/workflows.contract.d.ts +3 -0
- package/dist/contracts/workflows.contract.d.ts.map +1 -1
- package/dist/events/agent-events.d.ts +53 -1
- package/dist/events/agent-events.d.ts.map +1 -1
- package/dist/events/agent-events.js +6 -0
- package/dist/events/agent-events.js.map +1 -1
- package/dist/events/agent-ui.d.ts +33 -0
- package/dist/events/agent-ui.d.ts.map +1 -0
- package/dist/events/agent-ui.js +24 -0
- package/dist/events/agent-ui.js.map +1 -0
- package/dist/events/requests.d.ts +3 -0
- package/dist/events/requests.d.ts.map +1 -1
- package/dist/events/requests.js +4 -0
- package/dist/events/requests.js.map +1 -1
- package/dist/events/resume.d.ts +1 -0
- package/dist/events/resume.d.ts.map +1 -1
- package/dist/events/resume.js +7 -1
- package/dist/events/resume.js.map +1 -1
- package/dist/events/sandbox-notice.d.ts +2 -0
- package/dist/events/sandbox-notice.d.ts.map +1 -1
- package/dist/events/sandbox-notice.js +1 -1
- package/dist/events/sandbox-notice.js.map +1 -1
- package/dist/events/system-events.d.ts +15 -0
- package/dist/events/system-events.d.ts.map +1 -1
- package/dist/events/system-events.js +1 -0
- package/dist/events/system-events.js.map +1 -1
- package/dist/events/transcript.d.ts +70 -0
- package/dist/events/transcript.d.ts.map +1 -1
- package/dist/events/transcript.js +44 -14
- package/dist/events/transcript.js.map +1 -1
- package/dist/front/generated/browser-wire.d.ts +4 -0
- package/dist/front/generated/browser-wire.d.ts.map +1 -1
- package/dist/index.d.ts +640 -38
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/models/agent-runtimes.d.ts +1 -0
- package/dist/models/agent-runtimes.d.ts.map +1 -1
- package/dist/models/agent-runtimes.js +6 -0
- package/dist/models/agent-runtimes.js.map +1 -1
- package/dist/policy/request-status.d.ts.map +1 -1
- package/dist/policy/request-status.js +16 -7
- package/dist/policy/request-status.js.map +1 -1
- package/dist/policy/turned-away.d.ts.map +1 -1
- package/dist/policy/turned-away.js +1 -0
- package/dist/policy/turned-away.js.map +1 -1
- package/dist/protocol/raw-routes.d.ts +12 -0
- package/dist/protocol/raw-routes.d.ts.map +1 -1
- package/dist/protocol/raw-routes.js +3 -0
- package/dist/protocol/raw-routes.js.map +1 -1
- package/dist/schemas/agent.d.ts +97 -0
- package/dist/schemas/agent.d.ts.map +1 -1
- package/dist/schemas/agent.js +20 -2
- package/dist/schemas/agent.js.map +1 -1
- package/dist/schemas/agents.d.ts +18 -0
- package/dist/schemas/agents.d.ts.map +1 -1
- package/dist/schemas/agents.js +9 -2
- package/dist/schemas/agents.js.map +1 -1
- package/dist/schemas/approvals.d.ts +102 -0
- package/dist/schemas/approvals.d.ts.map +1 -1
- package/dist/schemas/approvals.js +45 -4
- package/dist/schemas/approvals.js.map +1 -1
- package/dist/schemas/automations.d.ts +6 -0
- package/dist/schemas/automations.d.ts.map +1 -1
- package/dist/schemas/capabilities.d.ts +2 -0
- package/dist/schemas/capabilities.d.ts.map +1 -1
- package/dist/schemas/capabilities.js +10 -1
- package/dist/schemas/capabilities.js.map +1 -1
- package/dist/schemas/git/git.d.ts.map +1 -1
- package/dist/schemas/git/git.js.map +1 -1
- package/dist/schemas/logs.d.ts +1 -0
- package/dist/schemas/logs.d.ts.map +1 -1
- package/dist/schemas/logs.js +4 -0
- package/dist/schemas/logs.js.map +1 -1
- package/dist/schemas/loops.d.ts +3 -0
- package/dist/schemas/loops.d.ts.map +1 -1
- package/dist/schemas/loops.js +1 -1
- package/dist/schemas/loops.js.map +1 -1
- package/dist/schemas/needs.d.ts +6 -0
- package/dist/schemas/needs.d.ts.map +1 -1
- package/dist/schemas/needs.js +13 -3
- package/dist/schemas/needs.js.map +1 -1
- package/dist/schemas/platform-link.d.ts +50 -0
- package/dist/schemas/platform-link.d.ts.map +1 -0
- package/dist/schemas/platform-link.js +19 -0
- package/dist/schemas/platform-link.js.map +1 -0
- package/dist/schemas/privacy.d.ts +277 -0
- package/dist/schemas/privacy.d.ts.map +1 -0
- package/dist/schemas/privacy.js +127 -0
- package/dist/schemas/privacy.js.map +1 -0
- package/dist/schemas/providers/plan-limits.d.ts +8 -0
- package/dist/schemas/providers/plan-limits.d.ts.map +1 -1
- package/dist/schemas/providers/plan-limits.js +25 -4
- package/dist/schemas/providers/plan-limits.js.map +1 -1
- package/dist/schemas/providers/usage.d.ts +4 -0
- package/dist/schemas/providers/usage.d.ts.map +1 -1
- package/dist/schemas/providers/usage.js +5 -2
- package/dist/schemas/providers/usage.js.map +1 -1
- package/dist/schemas/push.d.ts +1 -0
- package/dist/schemas/push.d.ts.map +1 -1
- package/dist/schemas/push.js +4 -0
- package/dist/schemas/push.js.map +1 -1
- package/dist/schemas/settings.d.ts +80 -0
- package/dist/schemas/settings.d.ts.map +1 -1
- package/dist/schemas/settings.js +14 -3
- package/dist/schemas/settings.js.map +1 -1
- package/dist/schemas/system.d.ts +17 -0
- package/dist/schemas/system.d.ts.map +1 -1
- package/dist/schemas/system.js +2 -1
- package/dist/schemas/system.js.map +1 -1
- package/dist/schemas/updates.d.ts +30 -0
- package/dist/schemas/updates.d.ts.map +1 -1
- package/dist/schemas/updates.js +37 -0
- package/dist/schemas/updates.js.map +1 -1
- package/dist/schemas/workflows.d.ts +5 -0
- package/dist/schemas/workflows.d.ts.map +1 -1
- package/dist/state/definition.d.ts +10 -0
- package/dist/state/definition.d.ts.map +1 -1
- package/dist/state/history-state.d.ts.map +1 -1
- package/dist/state/history-state.js +1 -0
- package/dist/state/history-state.js.map +1 -1
- package/dist/state/runtime-state.d.ts +3 -0
- package/dist/state/runtime-state.d.ts.map +1 -1
- package/dist/state/runtime-state.js +1 -0
- package/dist/state/runtime-state.js.map +1 -1
- package/dist/state/workspace-state.d.ts +17 -1
- package/dist/state/workspace-state.d.ts.map +1 -1
- package/dist/state/workspace-state.js +20 -1
- package/dist/state/workspace-state.js.map +1 -1
- package/dist/text/transcript-fold.d.ts.map +1 -1
- package/dist/text/transcript-fold.js +9 -0
- package/dist/text/transcript-fold.js.map +1 -1
- package/package.json +5 -5
- package/src/contracts/agent.contract.ts +16 -3
- package/src/contracts/approvals.contract.ts +2 -2
- package/src/contracts/privacy.contract.ts +95 -0
- package/src/contracts/system.contract.ts +14 -1
- package/src/events/agent-events.ts +11 -0
- package/src/events/agent-ui.ts +40 -0
- package/src/events/requests.ts +6 -0
- package/src/events/resume.test.ts +13 -0
- package/src/events/resume.ts +11 -2
- package/src/events/sandbox-notice.ts +1 -1
- package/src/events/system-events.ts +2 -0
- package/src/events/transcript.ts +84 -20
- package/src/front/generated/browser-wire.json +27 -0
- package/src/front/generated/browser-wire.ts +1 -1
- package/src/index.ts +6 -0
- package/src/models/agent-catalog.test.ts +1 -0
- package/src/models/agent-runtimes.ts +17 -0
- package/src/models/capability-ledger.test.ts +3 -0
- package/src/policy/request-status.ts +19 -9
- package/src/policy/turned-away.ts +2 -0
- package/src/protocol/raw-routes.ts +9 -0
- package/src/schemas/agent.ts +36 -4
- package/src/schemas/agents.ts +17 -4
- package/src/schemas/approvals.ts +59 -4
- package/src/schemas/automations.ts +4 -4
- package/src/schemas/capabilities.ts +15 -2
- package/src/schemas/ci.ts +1 -1
- package/src/schemas/git/git.ts +1 -0
- package/src/schemas/logs.ts +6 -0
- package/src/schemas/loops.ts +2 -1
- package/src/schemas/needs.ts +18 -3
- package/src/schemas/platform-link.ts +42 -0
- package/src/schemas/privacy.ts +204 -0
- package/src/schemas/providers/plan-limits.ts +38 -5
- package/src/schemas/providers/usage.ts +13 -2
- package/src/schemas/push.ts +7 -0
- package/src/schemas/settings-history.ts +3 -3
- package/src/schemas/settings.test.ts +5 -5
- package/src/schemas/settings.ts +47 -19
- package/src/schemas/system.ts +6 -1
- package/src/schemas/updates.ts +71 -0
- package/src/state/history-state.ts +3 -0
- package/src/state/runtime-state.ts +4 -0
- package/src/state/workspace-state.test.ts +8 -2
- package/src/state/workspace-state.ts +32 -2
- package/src/text/transcript-fold.test.ts +15 -0
- package/src/text/transcript-fold.ts +10 -0
package/src/events/transcript.ts
CHANGED
|
@@ -6,8 +6,27 @@ import { SubagentKindSchema, SubagentStatusSchema, SubagentVerificationSchema }
|
|
|
6
6
|
import { NeedSchema } from "../schemas/needs.js";
|
|
7
7
|
import { HeldEndingSchema, RetryLadderSchema } from "../schemas/turn-break.js";
|
|
8
8
|
import { NoticeCodeSchema } from "./sandbox-notice.js";
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
9
|
+
import { TranscriptAgentNoticeSchema } from "./agent-ui.js";
|
|
10
|
+
import type { ToolCallContent, ToolCallLocation, ToolCallStatus, ToolKind } from "./requests.js";
|
|
11
|
+
import {
|
|
12
|
+
browserHelpRequest,
|
|
13
|
+
capabilityOfferRequest,
|
|
14
|
+
CapabilityOutcomeSchema,
|
|
15
|
+
credentialOfferRequest,
|
|
16
|
+
CredentialReceiptSchema,
|
|
17
|
+
paymentOfferRequest,
|
|
18
|
+
PaymentReceiptSchema,
|
|
19
|
+
PermissionAskSchema,
|
|
20
|
+
permissionRequest,
|
|
21
|
+
planRequest,
|
|
22
|
+
questionRequest,
|
|
23
|
+
terminalHelpRequest,
|
|
24
|
+
TodoItemSchema,
|
|
25
|
+
ToolCallContentSchema,
|
|
26
|
+
ToolCallLocationSchema,
|
|
27
|
+
ToolCallStatusSchema,
|
|
28
|
+
ToolKindSchema,
|
|
29
|
+
} from "./requests.js";
|
|
11
30
|
|
|
12
31
|
// A conversation as recorded and replayed: the rows, the cards they carry, and the patches that change them while a
|
|
13
32
|
// turn runs. One shape for the live row and the recorded one, since they're the same row.
|
|
@@ -19,7 +38,8 @@ export const PlanStatusSchema = z.enum(["pending", "approved", "rejected", "canc
|
|
|
19
38
|
export type PlanStatus = z.infer<typeof PlanStatusSchema>;
|
|
20
39
|
export const QuestionStatusSchema = z.enum(["pending", "answered", "cancelled"]);
|
|
21
40
|
export type QuestionStatus = z.infer<typeof QuestionStatusSchema>;
|
|
22
|
-
|
|
41
|
+
// `everything`: allowed by a conversation-wide yes, the one given on this card or one already standing.
|
|
42
|
+
export const PermissionStatusSchema = z.enum(["pending", "allowed", "always", "everything", "denied", "cancelled"]);
|
|
23
43
|
export type PermissionStatus = z.infer<typeof PermissionStatusSchema>;
|
|
24
44
|
export const HelpStatusSchema = z.enum(["pending", "helped", "declined", "cancelled"]);
|
|
25
45
|
export type HelpStatus = z.infer<typeof HelpStatusSchema>;
|
|
@@ -38,10 +58,17 @@ export const TranscriptQuestionSchema = z.object({
|
|
|
38
58
|
.record(z.string(), z.array(z.string()))
|
|
39
59
|
.optional()
|
|
40
60
|
.describe("What was chosen, keyed by the question, with the chosen labels or the user's own words."),
|
|
61
|
+
attachments: z
|
|
62
|
+
.record(z.string(), z.array(z.string()))
|
|
63
|
+
.optional()
|
|
64
|
+
.describe("Files the user attached to their own-words answer, keyed by the question, as workspace-relative paths."),
|
|
41
65
|
});
|
|
42
66
|
export type TranscriptQuestion = z.infer<typeof TranscriptQuestionSchema>;
|
|
43
67
|
// `explain`, the judge's sentence, arrives via PermissionAskSchema at raise time; nothing patches it in after.
|
|
44
|
-
export const TranscriptPermissionSchema = PermissionAskSchema.extend({
|
|
68
|
+
export const TranscriptPermissionSchema = PermissionAskSchema.extend({
|
|
69
|
+
...permissionRequest,
|
|
70
|
+
status: PermissionStatusSchema.describe("Where the decision stands."),
|
|
71
|
+
});
|
|
45
72
|
export type TranscriptPermission = z.infer<typeof TranscriptPermissionSchema>;
|
|
46
73
|
export const TranscriptBrowserHelpSchema = z.object({ ...browserHelpRequest, status: HelpStatusSchema.describe("How the hand-over ended.") });
|
|
47
74
|
export type TranscriptBrowserHelp = z.infer<typeof TranscriptBrowserHelpSchema>;
|
|
@@ -297,15 +324,16 @@ export const TranscriptRowSchema = z.object({
|
|
|
297
324
|
.optional()
|
|
298
325
|
.describe("The wait this notice describes, by name, so a reader can say whether it is still on."),
|
|
299
326
|
// Which one, for a wait whose kind can have several in flight at once; without it two armed watches settle together.
|
|
300
|
-
noticeWaitId: z
|
|
301
|
-
.string()
|
|
302
|
-
.optional()
|
|
303
|
-
.describe("Which instance of the wait this notice names, for a kind that can have several running at once."),
|
|
327
|
+
noticeWaitId: z.string().optional().describe("Which instance of the wait this notice names, for a kind that can have several running at once."),
|
|
304
328
|
// The sandbox's own notice by name, beside its English `text` (sandbox-notice.ts); absent on every other row, and
|
|
305
329
|
// on the notices written before rows carried it, which a reader draws from `text` as it always did.
|
|
306
330
|
noticeCode: NoticeCodeSchema.optional().describe(
|
|
307
331
|
"Which of the sandbox's own notices this row is, and the facts it was worded from, so a reader can say it in the reader's own language. The text stays the English sentence.",
|
|
308
332
|
),
|
|
333
|
+
// A notice a runtime's own extension or loop said (events/agent-ui.ts), the words in `text`; absent on every other row.
|
|
334
|
+
agentNotice: TranscriptAgentNoticeSchema.optional().describe(
|
|
335
|
+
"This notice was said by the agent's runtime or one of its extensions rather than by the sandbox: how loud, and who said it.",
|
|
336
|
+
),
|
|
309
337
|
// At most one card per row; a card closes its bubble. One field per kind, so a reader reaches it by name.
|
|
310
338
|
plan: TranscriptPlanSchema.optional().describe("The plan this row asked approval for, and the answer."),
|
|
311
339
|
question: TranscriptQuestionSchema.optional().describe("The questions this row asked, and the picks that answered them."),
|
|
@@ -321,7 +349,9 @@ export const TranscriptRowSchema = z.object({
|
|
|
321
349
|
"Something the agent asked a person for, as it was when raised. Its live state (answered, met) is read by its id, since it outlives the turn.",
|
|
322
350
|
),
|
|
323
351
|
needWake: TranscriptNeedWakeSchema.optional().describe("The answered need that reached this conversation, and the prompt it came as."),
|
|
324
|
-
agentWords: TranscriptAgentWordsSchema.optional().describe(
|
|
352
|
+
agentWords: TranscriptAgentWordsSchema.optional().describe(
|
|
353
|
+
"Another agent's words that reached this conversation, whose they are, and the prompt they came as.",
|
|
354
|
+
),
|
|
325
355
|
backgroundJob: TranscriptBackgroundJobSchema.optional().describe("The background job this row marks the start of."),
|
|
326
356
|
credentialOffer: TranscriptCredentialOfferSchema.optional().describe(
|
|
327
357
|
"The gated credential this row asked to use, who may release it, and who did.",
|
|
@@ -352,10 +382,25 @@ export const isAwaitingDecision = (row: TranscriptRequests): boolean => REQUEST_
|
|
|
352
382
|
// everything else replaces its row; `drop` removes a row that opened and never wrote.
|
|
353
383
|
export const TranscriptPatchSchema = z.discriminatedUnion("op", [
|
|
354
384
|
z.object({ op: z.literal("append").describe("A new row at the end."), row: TranscriptRowSchema }),
|
|
355
|
-
z.object({
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
385
|
+
z.object({
|
|
386
|
+
op: z.literal("replace").describe("This row, whole, in place of the one at that index."),
|
|
387
|
+
index: z.number().int().nonnegative(),
|
|
388
|
+
row: TranscriptRowSchema,
|
|
389
|
+
}),
|
|
390
|
+
z.object({
|
|
391
|
+
op: z.literal("drop").describe("The row at that index is gone: it was opened and never written into."),
|
|
392
|
+
index: z.number().int().nonnegative(),
|
|
393
|
+
}),
|
|
394
|
+
z.object({
|
|
395
|
+
op: z.literal("text").describe("More of the agent's prose, onto that row's text."),
|
|
396
|
+
index: z.number().int().nonnegative(),
|
|
397
|
+
text: z.string(),
|
|
398
|
+
}),
|
|
399
|
+
z.object({
|
|
400
|
+
op: z.literal("thinking").describe("More of the agent's reasoning, onto that row's thinking."),
|
|
401
|
+
index: z.number().int().nonnegative(),
|
|
402
|
+
text: z.string(),
|
|
403
|
+
}),
|
|
359
404
|
z.object({
|
|
360
405
|
op: z.literal("toolThinking").describe("More of a delegated subagent's reasoning, onto the thinking of the card that started it."),
|
|
361
406
|
index: z.number().int().nonnegative(),
|
|
@@ -391,26 +436,41 @@ export const TurnEndingSchema = z.object({
|
|
|
391
436
|
resetsAt: z
|
|
392
437
|
.number()
|
|
393
438
|
.optional()
|
|
394
|
-
.describe(
|
|
439
|
+
.describe(
|
|
440
|
+
"When the spent allowance reopens, in epoch seconds. Absent for every ending that names no instant, and for a provider that publishes none.",
|
|
441
|
+
),
|
|
395
442
|
held: z
|
|
396
443
|
.object({
|
|
397
|
-
ran: z
|
|
444
|
+
ran: z
|
|
445
|
+
.boolean()
|
|
446
|
+
.describe("Whether the held turn got anywhere before it was refused, which is a different sentence from one refused at the door."),
|
|
398
447
|
contextTokens: z
|
|
399
448
|
.number()
|
|
400
449
|
.optional()
|
|
401
|
-
.describe(
|
|
450
|
+
.describe(
|
|
451
|
+
"How much context a press that keeps the session re-reads once, on this account at the reset or carried to another. Absent when no usage frame measured it.",
|
|
452
|
+
),
|
|
402
453
|
handoffTokens: z
|
|
403
454
|
.number()
|
|
404
455
|
.optional()
|
|
405
|
-
.describe(
|
|
406
|
-
|
|
456
|
+
.describe(
|
|
457
|
+
"What a press that opens a fresh session pays instead: the capped record plus the sandbox's measured brief, counted at the failure.",
|
|
458
|
+
),
|
|
459
|
+
moving: z
|
|
460
|
+
.string()
|
|
461
|
+
.optional()
|
|
462
|
+
.describe(
|
|
463
|
+
"The account the owner's policy is already moving this turn to, when it is; the surface then reports the move rather than offering a press.",
|
|
464
|
+
),
|
|
407
465
|
})
|
|
408
466
|
.optional()
|
|
409
467
|
.describe("Present when the daemon still holds the refused turn whole, so a press re-runs it rather than appending a message after it."),
|
|
410
468
|
scheduled: z
|
|
411
469
|
.boolean()
|
|
412
470
|
.optional()
|
|
413
|
-
.describe(
|
|
471
|
+
.describe(
|
|
472
|
+
"Whether something other than the user is already booked to send this turn again, so the surface reports the wait instead of offering a press.",
|
|
473
|
+
),
|
|
414
474
|
// `resetsAt` is the provider's fact about the allowance; this is the daemon's own appointment, and the two differ
|
|
415
475
|
// whenever a ladder rung falls short of the reset, or an ending with no allowance at all is armed.
|
|
416
476
|
nextAt: z
|
|
@@ -440,7 +500,11 @@ export const AgentTranscriptSchema = SessionTranscriptSchema.extend({
|
|
|
440
500
|
"How the last turn ended, when it left work behind that one press finishes. Absent for a conversation whose last turn ended on its own, and for the failures that name something to repair first.",
|
|
441
501
|
),
|
|
442
502
|
// `from` offsets every `rewindIndex` here, and is the `before` for the page above; `more` flags older messages.
|
|
443
|
-
from: z
|
|
503
|
+
from: z
|
|
504
|
+
.number()
|
|
505
|
+
.int()
|
|
506
|
+
.nonnegative()
|
|
507
|
+
.describe("Where the first message sits in the whole record, and the `before` that asks for the page above this one."),
|
|
444
508
|
more: z.boolean().describe("Whether older messages precede this page."),
|
|
445
509
|
});
|
|
446
510
|
|
|
@@ -90,6 +90,33 @@
|
|
|
90
90
|
"server": {
|
|
91
91
|
"description": "What a terminal socket sends as JSON text; the pane's own bytes travel as binary messages.",
|
|
92
92
|
"oneOf": [
|
|
93
|
+
{
|
|
94
|
+
"description": "The shared pane's grid. Viewport resize requests remain the viewer's own available size.",
|
|
95
|
+
"properties": {
|
|
96
|
+
"cols": {
|
|
97
|
+
"format": "uint16",
|
|
98
|
+
"maximum": 65535,
|
|
99
|
+
"minimum": 0,
|
|
100
|
+
"type": "integer"
|
|
101
|
+
},
|
|
102
|
+
"rows": {
|
|
103
|
+
"format": "uint16",
|
|
104
|
+
"maximum": 65535,
|
|
105
|
+
"minimum": 0,
|
|
106
|
+
"type": "integer"
|
|
107
|
+
},
|
|
108
|
+
"type": {
|
|
109
|
+
"const": "grid",
|
|
110
|
+
"type": "string"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"required": [
|
|
114
|
+
"type",
|
|
115
|
+
"cols",
|
|
116
|
+
"rows"
|
|
117
|
+
],
|
|
118
|
+
"type": "object"
|
|
119
|
+
},
|
|
93
120
|
{
|
|
94
121
|
"description": "The session is over, and the browser must not reconnect; `reason` is tmux's own words when it had any.",
|
|
95
122
|
"properties": {
|
|
@@ -49,4 +49,4 @@ export type TerminalClientMessage = { "type": "input", data: string, } | { "type
|
|
|
49
49
|
/**
|
|
50
50
|
* What a terminal socket sends as JSON text; the pane's own bytes travel as binary messages.
|
|
51
51
|
*/
|
|
52
|
-
export type TerminalServerMessage = { "type": "exit", code: number, reason?: string, } | { "type": "pong" };
|
|
52
|
+
export type TerminalServerMessage = { "type": "grid", cols: number, rows: number, } | { "type": "exit", code: number, reason?: string, } | { "type": "pong" };
|
package/src/index.ts
CHANGED
|
@@ -31,6 +31,7 @@ import { publicContract } from "./contracts/public.contract.js";
|
|
|
31
31
|
import { netdiskContract } from "./contracts/netdisk.contract.js";
|
|
32
32
|
import { providersContract } from "./contracts/providers.contract.js";
|
|
33
33
|
import { pushContract } from "./contracts/push.contract.js";
|
|
34
|
+
import { privacyContract } from "./contracts/privacy.contract.js";
|
|
34
35
|
import { safetyContract } from "./contracts/safety.contract.js";
|
|
35
36
|
import { needsContract } from "./contracts/needs.contract.js";
|
|
36
37
|
import { secretsContract } from "./contracts/secrets.contract.js";
|
|
@@ -95,6 +96,7 @@ export { portsContract } from "./contracts/ports.contract.js";
|
|
|
95
96
|
export { publicContract } from "./contracts/public.contract.js";
|
|
96
97
|
export { providersContract, type RunnableProviders, RunnableProvidersSchema } from "./contracts/providers.contract.js";
|
|
97
98
|
export { pushContract } from "./contracts/push.contract.js";
|
|
99
|
+
export { privacyContract } from "./contracts/privacy.contract.js";
|
|
98
100
|
export { safetyContract } from "./contracts/safety.contract.js";
|
|
99
101
|
export { needsContract } from "./contracts/needs.contract.js";
|
|
100
102
|
export { secretsContract } from "./contracts/secrets.contract.js";
|
|
@@ -111,6 +113,7 @@ export { vpnContract } from "./contracts/vpn.contract.js";
|
|
|
111
113
|
export { workflowsContract } from "./contracts/workflows.contract.js";
|
|
112
114
|
export { workspaceContract } from "./contracts/workspace.contract.js";
|
|
113
115
|
export * from "./events/agent-events.js";
|
|
116
|
+
export * from "./events/agent-ui.js";
|
|
114
117
|
export * from "./events/agent-words.js";
|
|
115
118
|
export * from "./events/requests.js";
|
|
116
119
|
export * from "./events/resume.js";
|
|
@@ -216,7 +219,9 @@ export * from "./schemas/marketplace.js";
|
|
|
216
219
|
export * from "./schemas/metrics.js";
|
|
217
220
|
export * from "./schemas/panels.js";
|
|
218
221
|
export * from "./schemas/personas.js";
|
|
222
|
+
export * from "./schemas/privacy.js";
|
|
219
223
|
export * from "./schemas/providers/plan-limits.js";
|
|
224
|
+
export * from "./schemas/platform-link.js";
|
|
220
225
|
export * from "./schemas/ports.js";
|
|
221
226
|
export * from "./schemas/providers/provider-oauth.js";
|
|
222
227
|
export * from "./schemas/providers/provider-subscriptions.js";
|
|
@@ -277,6 +282,7 @@ export const sandboxContract = {
|
|
|
277
282
|
endpoints: endpointsContract,
|
|
278
283
|
extensions: extensionsContract,
|
|
279
284
|
personas: personasContract,
|
|
285
|
+
privacy: privacyContract,
|
|
280
286
|
safety: safetyContract,
|
|
281
287
|
sessions: sessionsContract,
|
|
282
288
|
settings: settingsContract,
|
|
@@ -162,6 +162,7 @@ test("every axis a record can lack has words for it", () => {
|
|
|
162
162
|
skillDiscovery: "prompt",
|
|
163
163
|
rulebook: "none",
|
|
164
164
|
secrets: "none",
|
|
165
|
+
privacy: "none",
|
|
165
166
|
};
|
|
166
167
|
|
|
167
168
|
// Thirteen disclosable axes, thirteen sentences; `fastMode` is disclosed via fastAllowed, and `warm` (keep-warm, off by
|
|
@@ -51,6 +51,11 @@ export interface AgentCapabilities {
|
|
|
51
51
|
readonly rulebook: "hooks" | "approval" | "refuse-only" | "none";
|
|
52
52
|
// Whether a credential is masked; "none" is structural, only the Claude Code loop can rewrite a model's read.
|
|
53
53
|
readonly secrets: "masked" | "none";
|
|
54
|
+
// Whether the privacy shield can stand between this loop and its provider: `gateway` when the daemon names the base
|
|
55
|
+
// URL the loop sends its model requests to (so the gateway reads and masks every byte of them), `none` when the loop
|
|
56
|
+
// talks to its provider on a wire or a configuration the daemon does not own. A `none` loop on an untrusted provider
|
|
57
|
+
// is refused while the shield is on.
|
|
58
|
+
readonly privacy: "gateway" | "none";
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
// The Claude Code Agent SDK loop, the ceiling every other runtime is measured against: the only one that owns the whole
|
|
@@ -75,6 +80,8 @@ export const CLAUDE_CODE: AgentCapabilities = {
|
|
|
75
80
|
// The only runtime with its own pre-execution hook, so the only one where a hold can park instead of refusing.
|
|
76
81
|
rulebook: "hooks",
|
|
77
82
|
secrets: "masked",
|
|
83
|
+
// Every request goes to ANTHROPIC_BASE_URL, which the daemon sets per turn.
|
|
84
|
+
privacy: "gateway",
|
|
78
85
|
};
|
|
79
86
|
|
|
80
87
|
// Codex app-server: item-level events, the turn's remote MCP servers over http, and four seams (steer, a question
|
|
@@ -100,6 +107,8 @@ export const CODEX: AgentCapabilities = {
|
|
|
100
107
|
// Asked only when the owner has written command rules; an unconfigured workspace pays nothing for it.
|
|
101
108
|
rulebook: "approval",
|
|
102
109
|
secrets: "none",
|
|
110
|
+
// Its model provider's base_url is the daemon's, written into the per-thread config.
|
|
111
|
+
privacy: "gateway",
|
|
103
112
|
};
|
|
104
113
|
|
|
105
114
|
// OpenCode (the Grok runtime): its own agentic loop and tools, with the turn's remote MCP servers mounted on the shared
|
|
@@ -126,6 +135,8 @@ export const OPENCODE: AgentCapabilities = {
|
|
|
126
135
|
// hold parked on a card while the turn's inactivity watchdog is held.
|
|
127
136
|
rulebook: "approval",
|
|
128
137
|
secrets: "none",
|
|
138
|
+
// The shared server's provider baseURLs are written by the daemon at spawn.
|
|
139
|
+
privacy: "gateway",
|
|
129
140
|
};
|
|
130
141
|
|
|
131
142
|
// The same OpenCode loop, serving Gemini instead of xAI, identical abilities. The Claude Code loop announces itself in
|
|
@@ -157,6 +168,8 @@ export const ACP: AgentCapabilities = {
|
|
|
157
168
|
// In the protocol floor, so every agent has it; which calls it asks about is entirely its own choice.
|
|
158
169
|
rulebook: "approval",
|
|
159
170
|
secrets: "none",
|
|
171
|
+
// The agent picks its own provider and endpoint from its own login and environment.
|
|
172
|
+
privacy: "none",
|
|
160
173
|
};
|
|
161
174
|
|
|
162
175
|
// Pi driven over its RPC mode: above the ACP floor and below the Claude Code ceiling. Real mid-turn steering, an effort
|
|
@@ -181,6 +194,8 @@ export const PI: AgentCapabilities = {
|
|
|
181
194
|
// The one runtime with no seam at all: bash runs in-process, and no rule the owner writes can apply.
|
|
182
195
|
rulebook: "none",
|
|
183
196
|
secrets: "none",
|
|
197
|
+
// Pi calls its provider from its own login; the daemon names no endpoint.
|
|
198
|
+
privacy: "none",
|
|
184
199
|
};
|
|
185
200
|
|
|
186
201
|
// Cursor's own runtime, driven through `@cursor/sdk` from this daemon's process; an embedding surface, so most seams
|
|
@@ -219,4 +234,6 @@ export const CURSOR: AgentCapabilities = {
|
|
|
219
234
|
rulebook: "hooks",
|
|
220
235
|
// none, structurally: its hooks only allow/deny or are discarded, nothing here to substitute a reference into.
|
|
221
236
|
secrets: "none",
|
|
237
|
+
// Cursor's own RPC to its own servers, which then reach the model: redirectable, not readable.
|
|
238
|
+
privacy: "none",
|
|
222
239
|
};
|
|
@@ -34,6 +34,9 @@ const LEDGER: Record<keyof AgentCapabilities, Backing> = {
|
|
|
34
34
|
rulebook: "enforced",
|
|
35
35
|
// agent/run/turn/cache-keepwarm.ts files nothing to keep warm for a turn whose runtime lacks it.
|
|
36
36
|
warm: "enforced",
|
|
37
|
+
// agent/run/decide/turn-decision.ts refuses a "none" runtime on an untrusted provider while the privacy shield is
|
|
38
|
+
// on; "gateway" runtimes get the daemon's gateway as their base URL (privacy/gateway).
|
|
39
|
+
privacy: "enforced",
|
|
37
40
|
|
|
38
41
|
// Descriptive: true of the runtime but nothing consults these; wiring one up moves it to enforced.
|
|
39
42
|
questions: "descriptive",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { REQUEST_FIELDS, type RequestField, type TranscriptRequests, type TranscriptRow } from "../events/transcript.js";
|
|
1
|
+
import { type PermissionStatus, REQUEST_FIELDS, type RequestField, type TranscriptRequests, type TranscriptRow } from "../events/transcript.js";
|
|
2
2
|
import type { AgentReply } from "../schemas/providers/plan-limits.js";
|
|
3
3
|
import { startedChildCard } from "../events/child-run.js";
|
|
4
4
|
|
|
@@ -7,6 +7,21 @@ import { startedChildCard } from "../events/child-run.js";
|
|
|
7
7
|
// of the wrong kind cannot settle a card of another, since requestId is what matches them.
|
|
8
8
|
type Cards = { -readonly [K in RequestField]?: TranscriptRow[K] };
|
|
9
9
|
|
|
10
|
+
// A permission card's ending, from the reply that released it: each kind of yes keeps its own word.
|
|
11
|
+
const permissionStatusOf = (reply: AgentReply | undefined): PermissionStatus => {
|
|
12
|
+
if (reply?.kind !== "permission") {
|
|
13
|
+
return "cancelled";
|
|
14
|
+
}
|
|
15
|
+
switch (reply.decision) {
|
|
16
|
+
case "deny":
|
|
17
|
+
return "denied";
|
|
18
|
+
case "once":
|
|
19
|
+
return "allowed";
|
|
20
|
+
default:
|
|
21
|
+
return reply.decision;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
10
25
|
export const settledRequests = (cards: TranscriptRequests, reply: AgentReply | undefined): TranscriptRequests => {
|
|
11
26
|
const out: Cards = {};
|
|
12
27
|
const { plan, question, permission, browserHelp, terminalHelp, capabilityOffer, paymentOffer, credentialOffer } = cards;
|
|
@@ -15,23 +30,18 @@ export const settledRequests = (cards: TranscriptRequests, reply: AgentReply | u
|
|
|
15
30
|
}
|
|
16
31
|
if (question !== undefined) {
|
|
17
32
|
const answers = reply?.kind === "question" ? reply.answers : undefined;
|
|
33
|
+
const attachments = reply?.kind === "question" ? reply.attachments : undefined;
|
|
18
34
|
out.question = {
|
|
19
35
|
...question,
|
|
20
36
|
status: reply?.kind === "question" && reply.cancelled !== true ? "answered" : "cancelled",
|
|
21
37
|
...(answers === undefined ? {} : { answers }),
|
|
38
|
+
...(attachments === undefined ? {} : { attachments }),
|
|
22
39
|
};
|
|
23
40
|
}
|
|
24
41
|
if (permission !== undefined) {
|
|
25
42
|
out.permission = {
|
|
26
43
|
...startedChildCard(permission, reply),
|
|
27
|
-
status:
|
|
28
|
-
reply?.kind !== "permission"
|
|
29
|
-
? "cancelled"
|
|
30
|
-
: reply.decision === "deny"
|
|
31
|
-
? "denied"
|
|
32
|
-
: reply.decision === "always"
|
|
33
|
-
? "always"
|
|
34
|
-
: "allowed",
|
|
44
|
+
status: permissionStatusOf(reply),
|
|
35
45
|
};
|
|
36
46
|
}
|
|
37
47
|
if (browserHelp !== undefined) {
|
|
@@ -11,6 +11,8 @@ const TURNED_AWAY: ReadonlySet<string> = new Set([
|
|
|
11
11
|
"unknown-command",
|
|
12
12
|
"context-window-too-small",
|
|
13
13
|
"model-helper-only",
|
|
14
|
+
// The privacy shield refused an untrusted provider on a runtime it cannot stand in front of.
|
|
15
|
+
"privacy-unshielded",
|
|
14
16
|
"sandbox-memory-low",
|
|
15
17
|
"trial-unavailable",
|
|
16
18
|
"trial-model-unavailable",
|
|
@@ -8,6 +8,9 @@ import { runnerTranslatorPath } from "./runner-protocol.js";
|
|
|
8
8
|
export const RAW_ROUTES = {
|
|
9
9
|
// The "is a daemon there" probe every flow uses; it names the sandbox and says whether it is still converging.
|
|
10
10
|
"GET /health": { auth: "door", beforeBoot: true },
|
|
11
|
+
// A person opening this sandbox's own address in a browser: sent to the app's /open on it, the address being what
|
|
12
|
+
// they may still hold when the platform has lost the rest. Anything else gets the same 401 as before it existed.
|
|
13
|
+
"GET /": { auth: "door", beforeBoot: true },
|
|
11
14
|
"GET /diff/raw": { lane: "bulk" },
|
|
12
15
|
// Arming the dictation model is a read any tier makes; dictating is writing a message, the collaborator's grant.
|
|
13
16
|
"GET /speech/status": { guest: true },
|
|
@@ -59,6 +62,8 @@ export const RAW_ROUTES = {
|
|
|
59
62
|
"POST /members": { control: "never" },
|
|
60
63
|
"DELETE /members": { control: "never" },
|
|
61
64
|
"DELETE /members/self": { floor: "viewer", guest: true, control: "never" },
|
|
65
|
+
// The owner's Reconnect: register with the platform now, having it adopt the sandbox first when it holds no record.
|
|
66
|
+
"POST /platform/relink": { control: "never" },
|
|
62
67
|
"GET /environment": {},
|
|
63
68
|
"GET /environment/contents": {},
|
|
64
69
|
"POST /environment/approve": {},
|
|
@@ -153,6 +158,10 @@ export const RAW_ROUTES = {
|
|
|
153
158
|
"POST /system/runners/credentials": { auth: "door", control: "never" },
|
|
154
159
|
"POST /system/runners/credentials/refresh": { auth: "door", control: "never" },
|
|
155
160
|
[`ALL ${runnerTranslatorPath}/*` as const]: { auth: "door", control: "never" },
|
|
161
|
+
// The privacy shield's gateway: every shielded runtime's model requests, on the signed session its base URL carries
|
|
162
|
+
// (privacy/gateway/session-token.ts), which names the provider and the only upstream it may forward to. Held open
|
|
163
|
+
// while a model streams its answer.
|
|
164
|
+
"ALL /privacy/gateway/{session}/*": { auth: "door", control: "never", stream: true },
|
|
156
165
|
"POST /system/control/tokens": { control: "never" },
|
|
157
166
|
"GET /system/control/tokens": { control: "never" },
|
|
158
167
|
"DELETE /system/control/tokens/{id}": { control: "never" },
|
package/src/schemas/agent.ts
CHANGED
|
@@ -304,15 +304,28 @@ const AgentTurnFieldsSchema = z.object({
|
|
|
304
304
|
editorContext: EditorContextSchema.optional().describe(
|
|
305
305
|
'What the user has open in their editor, folded into the prompt so that pointing words like "this" resolve.',
|
|
306
306
|
),
|
|
307
|
-
// The composer's scheduled send: a
|
|
308
|
-
//
|
|
307
|
+
// The composer's scheduled send: a time the person chose, or a spent account's reopen they would rather wait for than
|
|
308
|
+
// send into a refusal. Held in the conversation's queue, never started early; the queue's `until` is this.
|
|
309
309
|
sendAt: z
|
|
310
310
|
.number()
|
|
311
311
|
.int()
|
|
312
312
|
.positive()
|
|
313
313
|
.optional()
|
|
314
314
|
.describe(
|
|
315
|
-
"Hold this message until then (epoch milliseconds) instead of starting a turn now,
|
|
315
|
+
"Hold this message until then (epoch milliseconds) instead of starting a turn now: a time you chose, or the reopen of an allowance you know is spent. It waits in the conversation's queue, where it can be sent early, reworded, rescheduled or removed, and goes by itself at that instant, even for a conversation this message opens or one whose turn is running now. Ignored when already past; at most a month ahead.",
|
|
316
|
+
),
|
|
317
|
+
// The other scheduled send: work that builds on another agent's, held until that agent's work is in the workspace.
|
|
318
|
+
// Held in the queue like `sendAt`; the queue's `after` is this. Never both: a hold waits on exactly one thing.
|
|
319
|
+
sendAfter: ConversationIdSchema.optional().describe(
|
|
320
|
+
"Hold this message until the conversation named here has finished and all of its work has landed in the workspace, instead of starting a turn now: for work that builds on another agent's. It waits in this conversation's queue, where it can be sent early, reworded, rescheduled or removed. Sent at once when that conversation has nothing running and nothing left to land.",
|
|
321
|
+
),
|
|
322
|
+
// Decided like `isolated`: the opening turn's answer, latched on the entry it opens. A maintainer's alone, since the
|
|
323
|
+
// standing answer it sets is what `agents.autoLand` sets, and that route is a maintainer's.
|
|
324
|
+
conversationAutoLand: z
|
|
325
|
+
.boolean()
|
|
326
|
+
.optional()
|
|
327
|
+
.describe(
|
|
328
|
+
"Whether this conversation's finished work merges into the workspace by itself from now on: its own answer to the sandbox-wide setting, the one `agents.autoLand` changes later. Read only from the message that opens the conversation, and only from a maintainer. Unlike `autoLand`, it holds for every later turn.",
|
|
316
329
|
),
|
|
317
330
|
});
|
|
318
331
|
export const AgentTurnSchema = AgentTurnFieldsSchema
|
|
@@ -335,8 +348,24 @@ export const AgentTurnSchema = AgentTurnFieldsSchema
|
|
|
335
348
|
// "then" needs a checkout of its own; rolling back the shared tree under everyone else is what it must never mean.
|
|
336
349
|
.refine((turn) => turn.forkOf?.files !== "then" || turn.isolated === true, {
|
|
337
350
|
message: 'forkOf.files "then" requires isolated',
|
|
351
|
+
})
|
|
352
|
+
.refine((turn) => turn.sendAt === undefined || turn.sendAfter === undefined, {
|
|
353
|
+
message: "sendAt and sendAfter are two different holds: name one",
|
|
354
|
+
})
|
|
355
|
+
.refine((turn) => turn.sendAfter === undefined || turn.sendAfter !== turn.conversationId, {
|
|
356
|
+
message: "a conversation cannot wait for its own work to land",
|
|
338
357
|
});
|
|
339
358
|
export type AgentTurn = z.infer<typeof AgentTurnSchema>;
|
|
359
|
+
// What `agent.run` takes: a turn, plus the one field only a request carries and no stored turn keeps. A daemon from before
|
|
360
|
+
// `continues` reads past it and takes `prompt` as the words, which is why a client still sends some.
|
|
361
|
+
export const AgentRunSchema = AgentTurnSchema.safeExtend({
|
|
362
|
+
continues: z
|
|
363
|
+
.literal(true)
|
|
364
|
+
.optional()
|
|
365
|
+
.describe(
|
|
366
|
+
"Carry the conversation on from where its last turn stopped instead of saying anything: nothing of yours is added to the conversation, and `prompt` is ignored. A turn the sandbox still holds runs again as it was; otherwise the agent is told to continue in its own session. Refused while a turn is running.",
|
|
367
|
+
),
|
|
368
|
+
});
|
|
340
369
|
// What a turn naming no provider or loop runs on, stated once. Applied where a request comes in (the daemon's turn port),
|
|
341
370
|
// so nothing downstream defaults them again: the engine takes a turn with both named (withRuntimeDefaults).
|
|
342
371
|
/** A turn with its provider and loop named, as the engine takes it past the door. */
|
|
@@ -491,12 +520,15 @@ export const ConversationQueueSchema = z.object({
|
|
|
491
520
|
items: z.array(QueuedMessageSchema).describe("What waits, in the order it goes out."),
|
|
492
521
|
revision: z.number().int().nonnegative().describe("Moves with every change to the queue, so of two copies the higher is the newer."),
|
|
493
522
|
paused: QueuePauseSchema.optional().describe(
|
|
494
|
-
"Why nothing goes out by itself: somebody stopped the turn, the turn these messages started was refused before it ran, or they were scheduled for
|
|
523
|
+
"Why nothing goes out by itself: somebody stopped the turn, the turn these messages started was refused before it ran, or they were scheduled for a time or for after another conversation's work lands. Resuming lets them go, and so does sending another message.",
|
|
495
524
|
),
|
|
496
525
|
until: z
|
|
497
526
|
.number()
|
|
498
527
|
.optional()
|
|
499
528
|
.describe("When scheduled messages go out by themselves, in milliseconds. Only on a queue paused as `scheduled`."),
|
|
529
|
+
after: ConversationIdSchema.optional().describe(
|
|
530
|
+
"The conversation whose finished work must land before scheduled messages go out by themselves. Only on a queue paused as `scheduled`, in place of `until`.",
|
|
531
|
+
),
|
|
500
532
|
});
|
|
501
533
|
export type ConversationQueue = z.infer<typeof ConversationQueueSchema>;
|
|
502
534
|
// What resuming a queue did: started a turn with what waited, when nothing else ran.
|
package/src/schemas/agents.ts
CHANGED
|
@@ -89,12 +89,14 @@ export const UnfinishedWorkSchema = z.object({
|
|
|
89
89
|
})
|
|
90
90
|
.optional()
|
|
91
91
|
.describe("The agent's own checklist where that turn left it. Absent for a conversation that kept no list."),
|
|
92
|
-
// Name of the `turn.ending` check still failing when the turn ended
|
|
93
|
-
// it stays so entries written before still read.
|
|
92
|
+
// Name of the `turn.ending` check still failing when the turn ended, from when a failing one left the work unfinished.
|
|
93
|
+
// Nothing writes it now, and it stays so entries written before still read.
|
|
94
94
|
check: z
|
|
95
95
|
.string()
|
|
96
96
|
.optional()
|
|
97
|
-
.describe(
|
|
97
|
+
.describe(
|
|
98
|
+
"The end-of-turn check that was still failing when the turn ended, by name. No longer written: what a check finds as a turn ends is said back to the model and never leaves its work unfinished.",
|
|
99
|
+
),
|
|
98
100
|
});
|
|
99
101
|
export type UnfinishedWork = z.infer<typeof UnfinishedWorkSchema>;
|
|
100
102
|
// What the last turn showed of its own work, read off its tool calls and never asked of the model: the record a card
|
|
@@ -357,7 +359,7 @@ export const AgentSummarySchema = z.object({
|
|
|
357
359
|
// Root repo's short base sha; per-repo bases stay daemon-internal.
|
|
358
360
|
base: z.string().optional().describe("The commit its private copy started from, shortened."),
|
|
359
361
|
costUsd: z.number().optional().describe("What it has cost so far, in dollars. A subagent's spend is its own and is not folded in here."),
|
|
360
|
-
inputTokens: z.number().optional().describe("
|
|
362
|
+
inputTokens: z.number().optional().describe("Uncached input tokens, excluding cache reads and cache writes."),
|
|
361
363
|
outputTokens: z.number().optional().describe("Tokens received."),
|
|
362
364
|
contextTokens: z.number().optional().describe("How much of the window the conversation currently fills."),
|
|
363
365
|
contextWindow: z.number().optional().describe("How large that window is."),
|
|
@@ -616,6 +618,17 @@ export const AgentSummarySchema = z.object({
|
|
|
616
618
|
.describe(
|
|
617
619
|
"Who stopped it: the sandbox, when the turn that used it ended without handing it over; a person; or the agent itself. Present from the moment the stop is asked. Absent for a job that exited by itself.",
|
|
618
620
|
),
|
|
621
|
+
// agent/tools/jobs/input-wait.ts: told from /proc, never from what it printed, since a prompt can go
|
|
622
|
+
// straight to the terminal or sit in a pipe.
|
|
623
|
+
inputWait: z
|
|
624
|
+
.object({
|
|
625
|
+
since: z.number().describe("When it went still, in milliseconds."),
|
|
626
|
+
program: z.string().describe("The process blocked reading the terminal, as its command line."),
|
|
627
|
+
})
|
|
628
|
+
.optional()
|
|
629
|
+
.describe(
|
|
630
|
+
"Present while it sits blocked reading its terminal with nothing moving: a prompt nobody in the sandbox will answer, which only stopping it or a person typing into its terminal ends. Absent while it runs on, and once it ends.",
|
|
631
|
+
),
|
|
619
632
|
}),
|
|
620
633
|
)
|
|
621
634
|
.optional()
|