@yaklabs-ai/plugin-sdk 0.15.3 → 0.27.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 +25 -5
- package/THIRD-PARTY-INVENTORY.json +9 -9
- package/THIRD-PARTY-NOTICES.md +8 -8
- package/dist/agent-conversation.d.ts +1 -1
- package/dist/canonical-transcript.d.ts +133 -123
- package/dist/canonical-transcript.js +119 -44
- package/dist/disclosure.d.ts +1588 -744
- package/dist/disclosure.js +48 -59
- package/dist/kay-agent-testing.d.ts +2577 -590
- package/dist/kay-agent-testing.js +96 -3
- package/dist/kay-agent.d.ts +1791 -1710
- package/dist/kay-agent.js +310 -310
- package/dist/kay-app-session-summary.d.ts +999 -144
- package/dist/kay-app-session-summary.js +15 -15
- package/dist/kay-app.d.ts +3303 -837
- package/dist/kay-app.js +233 -6
- package/dist/phase-shift.d.ts +4 -4
- package/dist/system-one.d.ts +13 -0
- package/dist/time.d.ts +2 -4
- package/dist/transcript-review.d.ts +10 -0
- package/dist/transcript-review.js +104 -31
- package/dist/transcript.d.ts +8 -6
- package/dist/vendored-mcp.d.ts +434 -305
- package/dist/vendored-mcp.js +278 -101
- package/dist/whiteboard.d.ts +82 -0
- package/dist/whiteboard.js +174 -0
- package/package.json +5 -1
package/dist/kay-app.js
CHANGED
|
@@ -163,6 +163,94 @@ function invalidObservation(input) {
|
|
|
163
163
|
};
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
// packages/herd-transcript/dist/record-kinds.js
|
|
167
|
+
var STORED_TRANSCRIPT_MESSAGE_KINDS = [
|
|
168
|
+
"user",
|
|
169
|
+
"assistant",
|
|
170
|
+
"tool_result",
|
|
171
|
+
"custom_message:*",
|
|
172
|
+
"compaction",
|
|
173
|
+
"branch_summary"
|
|
174
|
+
];
|
|
175
|
+
var NAMED_KINDS = /* @__PURE__ */ new Set([
|
|
176
|
+
"user",
|
|
177
|
+
"assistant",
|
|
178
|
+
"tool_result",
|
|
179
|
+
"compaction",
|
|
180
|
+
"branch_summary",
|
|
181
|
+
"other",
|
|
182
|
+
"unreadable"
|
|
183
|
+
]);
|
|
184
|
+
var ROLE_KINDS = {
|
|
185
|
+
user: "user",
|
|
186
|
+
assistant: "assistant",
|
|
187
|
+
toolResult: "tool_result"
|
|
188
|
+
};
|
|
189
|
+
function storedTranscriptKindOf(record) {
|
|
190
|
+
if (!("entry" in record))
|
|
191
|
+
return "unreadable";
|
|
192
|
+
const entry = record.entry;
|
|
193
|
+
switch (entry.type) {
|
|
194
|
+
case "message": {
|
|
195
|
+
const message = entry.message;
|
|
196
|
+
if (message.role === "custom") {
|
|
197
|
+
return `custom_message:${typeof message.customType === "string" ? message.customType : ""}`;
|
|
198
|
+
}
|
|
199
|
+
return (typeof message.role === "string" ? ROLE_KINDS[message.role] : void 0) ?? "other";
|
|
200
|
+
}
|
|
201
|
+
case "custom":
|
|
202
|
+
return `custom:${entry.customType}`;
|
|
203
|
+
case "compaction":
|
|
204
|
+
return "compaction";
|
|
205
|
+
case "branch_summary":
|
|
206
|
+
return "branch_summary";
|
|
207
|
+
default:
|
|
208
|
+
return "other";
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function parseStoredTranscriptKindFilter(tokens) {
|
|
212
|
+
const exact = /* @__PURE__ */ new Set();
|
|
213
|
+
const families = /* @__PURE__ */ new Set();
|
|
214
|
+
let all = false;
|
|
215
|
+
for (const raw of tokens) {
|
|
216
|
+
const token = raw.trim();
|
|
217
|
+
if (token === "all") {
|
|
218
|
+
all = true;
|
|
219
|
+
} else if (token === "messages") {
|
|
220
|
+
for (const kind of STORED_TRANSCRIPT_MESSAGE_KINDS)
|
|
221
|
+
addToken(kind);
|
|
222
|
+
} else if (!addToken(token)) {
|
|
223
|
+
return { ok: false, invalid: raw };
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
ok: true,
|
|
228
|
+
filter: {
|
|
229
|
+
includes: (kind) => all || exact.has(kind) || families.has(kind.slice(0, kind.indexOf(":") + 1))
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
function addToken(token) {
|
|
233
|
+
if (NAMED_KINDS.has(token)) {
|
|
234
|
+
exact.add(token);
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
const family = /^(custom|custom_message):(.+)$/.exec(token);
|
|
238
|
+
if (family === null)
|
|
239
|
+
return false;
|
|
240
|
+
if (family[2] === "*")
|
|
241
|
+
families.add(`${family[1]}:`);
|
|
242
|
+
else
|
|
243
|
+
exact.add(token);
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
var STORED_TRANSCRIPT_MESSAGE_FILTER = (() => {
|
|
248
|
+
const parsed = parseStoredTranscriptKindFilter(STORED_TRANSCRIPT_MESSAGE_KINDS);
|
|
249
|
+
if (!parsed.ok)
|
|
250
|
+
throw new Error(`invalid default kinds: ${parsed.invalid}`);
|
|
251
|
+
return parsed.filter;
|
|
252
|
+
})();
|
|
253
|
+
|
|
166
254
|
// packages/plugin-sdk/dist/kay-app/index.js
|
|
167
255
|
import { pathToFileURL } from "node:url";
|
|
168
256
|
|
|
@@ -190,6 +278,15 @@ var UriValidationError = class extends UriError {
|
|
|
190
278
|
this.name = "UriValidationError";
|
|
191
279
|
}
|
|
192
280
|
};
|
|
281
|
+
function requireWriteContent(payload2, uri) {
|
|
282
|
+
if (payload2 === void 0) {
|
|
283
|
+
throw new UriValidationError(`Writing ${uri} needs \`content\` (or a \`source\` to copy from): pass the payload this address takes, which its help names.`);
|
|
284
|
+
}
|
|
285
|
+
if (payload2 instanceof Uint8Array) {
|
|
286
|
+
throw new UriValidationError(`${uri} stores text only, so it cannot take raw bytes. Copy the file to an address that accepts bytes.`);
|
|
287
|
+
}
|
|
288
|
+
return payload2;
|
|
289
|
+
}
|
|
193
290
|
var UriProviderError = class extends UriError {
|
|
194
291
|
_tag = "UriProviderError";
|
|
195
292
|
moduleId;
|
|
@@ -202,6 +299,8 @@ var UriProviderError = class extends UriError {
|
|
|
202
299
|
retryAfterMs;
|
|
203
300
|
/** See {@link UriProviderErrorOptions.effect}. */
|
|
204
301
|
effect;
|
|
302
|
+
/** See {@link UriProviderErrorOptions.refusalMessage}. */
|
|
303
|
+
refusalMessage;
|
|
205
304
|
constructor(options) {
|
|
206
305
|
super(options.message);
|
|
207
306
|
this.name = "UriProviderError";
|
|
@@ -222,6 +321,12 @@ var UriProviderError = class extends UriError {
|
|
|
222
321
|
}
|
|
223
322
|
if (options.effect !== void 0)
|
|
224
323
|
this.effect = options.effect;
|
|
324
|
+
if (options.refusalMessage !== void 0) {
|
|
325
|
+
if (options.effect !== "none") {
|
|
326
|
+
throw new TypeError('refusalMessage requires effect: "none".');
|
|
327
|
+
}
|
|
328
|
+
this.refusalMessage = options.refusalMessage;
|
|
329
|
+
}
|
|
225
330
|
}
|
|
226
331
|
};
|
|
227
332
|
var UriNotFoundError = class extends UriError {
|
|
@@ -400,7 +505,7 @@ function toJsonSchema(schema) {
|
|
|
400
505
|
// `io: "input"` describes what a caller may SEND, which is what a parameter and an
|
|
401
506
|
// `accepts` payload advertise: a field with a Zod default is optional on the wire even
|
|
402
507
|
// though the parsed value always carries it. Strictness still survives where the validator
|
|
403
|
-
// really enforces it
|
|
508
|
+
// really enforces it - `z.strictObject` emits `additionalProperties: false`, while a plain
|
|
404
509
|
// `z.object` correctly does not, because it TOLERATES unknown keys and silently strips
|
|
405
510
|
// them. A `returns` payload derived from a Zod schema is described in the same input terms;
|
|
406
511
|
// no module does that today, and a faithful output projection would need its own seam.
|
|
@@ -440,6 +545,28 @@ function isRetryable(result) {
|
|
|
440
545
|
return result.status === "not-ready";
|
|
441
546
|
}
|
|
442
547
|
|
|
548
|
+
// packages/plugin-sdk/dist/kay-app/auth.js
|
|
549
|
+
var KayAppCredentialRejectedError = class extends Error {
|
|
550
|
+
name = "KayAppCredentialRejectedError";
|
|
551
|
+
};
|
|
552
|
+
async function withCredential(auth, request, use) {
|
|
553
|
+
const candidates = await auth.resolveCandidates(request);
|
|
554
|
+
let rejection;
|
|
555
|
+
for (const credential of candidates) {
|
|
556
|
+
try {
|
|
557
|
+
const result = await use(credential);
|
|
558
|
+
await auth.reportWorked(request, credential.schemeId).catch(() => {
|
|
559
|
+
});
|
|
560
|
+
return result;
|
|
561
|
+
} catch (error) {
|
|
562
|
+
if (!(error instanceof KayAppCredentialRejectedError))
|
|
563
|
+
throw error;
|
|
564
|
+
rejection = error;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
throw rejection ?? new Error(`No credential is resolvable for '${request.serviceId}'.`);
|
|
568
|
+
}
|
|
569
|
+
|
|
443
570
|
// packages/plugin-sdk/dist/kay-app/automations.js
|
|
444
571
|
var KAY_APP_AUTOMATION_CONDITION_KINDS = [
|
|
445
572
|
"time",
|
|
@@ -449,6 +576,46 @@ var KAY_APP_AUTOMATION_CONDITION_KINDS = [
|
|
|
449
576
|
"delayed-occurrence"
|
|
450
577
|
];
|
|
451
578
|
|
|
579
|
+
// packages/plugin-sdk/dist/log.js
|
|
580
|
+
function createKayPluginLog(write, bound = {}) {
|
|
581
|
+
const at = (level) => (name, message, details) => {
|
|
582
|
+
try {
|
|
583
|
+
write({
|
|
584
|
+
level,
|
|
585
|
+
name,
|
|
586
|
+
message,
|
|
587
|
+
...details?.error === void 0 ? {} : { error: details.error },
|
|
588
|
+
...details?.sessionId === void 0 ? {} : { sessionId: details.sessionId },
|
|
589
|
+
attributes: { ...bound, ...details?.attributes }
|
|
590
|
+
});
|
|
591
|
+
} catch {
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
return {
|
|
595
|
+
debug: at("debug"),
|
|
596
|
+
info: at("info"),
|
|
597
|
+
warn: at("warn"),
|
|
598
|
+
error: at("error"),
|
|
599
|
+
child: (attributes) => createKayPluginLog(write, { ...bound, ...attributes })
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
function createConsoleKayPluginLog(pluginId) {
|
|
603
|
+
const prefix = pluginId === void 0 ? "" : `${pluginId}.`;
|
|
604
|
+
return createKayPluginLog((line) => {
|
|
605
|
+
const args = [`[${prefix}${line.name}] ${line.message}`];
|
|
606
|
+
if (Object.keys(line.attributes).length > 0)
|
|
607
|
+
args.push(line.attributes);
|
|
608
|
+
if (line.error !== void 0)
|
|
609
|
+
args.push(line.error);
|
|
610
|
+
console[line.level](...args);
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// packages/plugin-sdk/dist/kay-app/model-selection.js
|
|
615
|
+
var KAY_APP_MODEL_SELECTION_START_BOUND_MS = 2e3;
|
|
616
|
+
var KAY_APP_MODEL_SELECTION_RESPONSE_BOUND_MS = 6e3;
|
|
617
|
+
var KAY_APP_MODEL_SELECTION_SEND_BOUND_MS = 4e3;
|
|
618
|
+
|
|
452
619
|
// packages/plugin-sdk/dist/kay-app/poller.js
|
|
453
620
|
function accountCursors(state) {
|
|
454
621
|
if (state === void 0)
|
|
@@ -482,7 +649,7 @@ function plainText(value, max) {
|
|
|
482
649
|
return text;
|
|
483
650
|
}
|
|
484
651
|
function definePoller(app, localId, options) {
|
|
485
|
-
const { workflows, auth, events } = app;
|
|
652
|
+
const { workflows, auth, backgroundAuth, events } = app;
|
|
486
653
|
if (!workflows)
|
|
487
654
|
throw new Error("Poller requires workflows");
|
|
488
655
|
if (!Number.isSafeInteger(options.every) || options.every <= 0) {
|
|
@@ -498,6 +665,8 @@ function definePoller(app, localId, options) {
|
|
|
498
665
|
async run(ctx) {
|
|
499
666
|
if (!auth)
|
|
500
667
|
throw new Error("Poller requires account listing");
|
|
668
|
+
if (!backgroundAuth)
|
|
669
|
+
throw new Error("Poller requires background auth");
|
|
501
670
|
const previous = accountCursors(ctx.state);
|
|
502
671
|
const accounts = await ctx.runStep(async () => {
|
|
503
672
|
const listed = await auth.listAccounts({
|
|
@@ -523,7 +692,12 @@ function definePoller(app, localId, options) {
|
|
|
523
692
|
}
|
|
524
693
|
let credential;
|
|
525
694
|
try {
|
|
526
|
-
credential = await
|
|
695
|
+
credential = await backgroundAuth.resolveCredential({
|
|
696
|
+
serviceId: options.serviceId,
|
|
697
|
+
schemeId: account.schemeId,
|
|
698
|
+
accountId: account.accountId,
|
|
699
|
+
jobId: ctx.runId
|
|
700
|
+
});
|
|
527
701
|
} catch {
|
|
528
702
|
throw new Error("Poller credential resolution failed");
|
|
529
703
|
}
|
|
@@ -597,6 +771,15 @@ function definePoller(app, localId, options) {
|
|
|
597
771
|
});
|
|
598
772
|
}
|
|
599
773
|
|
|
774
|
+
// packages/plugin-sdk/dist/kay-app/sealing.js
|
|
775
|
+
var KAY_APP_SEALING_MAX_BYTES = 1048576;
|
|
776
|
+
function createUnavailableSealing(message) {
|
|
777
|
+
return {
|
|
778
|
+
seal: async () => ({ status: "unavailable", message }),
|
|
779
|
+
open: async () => ({ status: "unavailable", message })
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
|
|
600
783
|
// packages/plugin-sdk/dist/kay-app/skills.js
|
|
601
784
|
function createUnavailableSkills(message) {
|
|
602
785
|
const unavailable = {
|
|
@@ -605,9 +788,38 @@ function createUnavailableSkills(message) {
|
|
|
605
788
|
message
|
|
606
789
|
};
|
|
607
790
|
return {
|
|
791
|
+
propose: async () => {
|
|
792
|
+
throw new Error(message);
|
|
793
|
+
},
|
|
608
794
|
list: async () => unavailable,
|
|
609
795
|
read: async () => unavailable,
|
|
610
|
-
history: async () => unavailable
|
|
796
|
+
history: async () => unavailable,
|
|
797
|
+
diff: async () => unavailable,
|
|
798
|
+
revision: async () => unavailable,
|
|
799
|
+
writeFile: async () => {
|
|
800
|
+
throw new Error(message);
|
|
801
|
+
},
|
|
802
|
+
install: async () => {
|
|
803
|
+
throw new Error(message);
|
|
804
|
+
},
|
|
805
|
+
delete: async () => {
|
|
806
|
+
throw new Error(message);
|
|
807
|
+
},
|
|
808
|
+
sourceContributors: async () => {
|
|
809
|
+
throw new Error(message);
|
|
810
|
+
},
|
|
811
|
+
setMarketplaceAdded: async () => {
|
|
812
|
+
throw new Error(message);
|
|
813
|
+
},
|
|
814
|
+
shareDestinations: async () => {
|
|
815
|
+
throw new Error(message);
|
|
816
|
+
},
|
|
817
|
+
prepareShare: async () => {
|
|
818
|
+
throw new Error(message);
|
|
819
|
+
},
|
|
820
|
+
confirmShare: async () => {
|
|
821
|
+
throw new Error(message);
|
|
822
|
+
}
|
|
611
823
|
};
|
|
612
824
|
}
|
|
613
825
|
|
|
@@ -649,7 +861,8 @@ function transcriptRoleLabel(role) {
|
|
|
649
861
|
// packages/plugin-sdk/dist/kay-app/usage.js
|
|
650
862
|
function createUnavailableUsage(message) {
|
|
651
863
|
return {
|
|
652
|
-
uriActivity: async () => ({ status: "unavailable", message })
|
|
864
|
+
uriActivity: async () => ({ status: "unavailable", message }),
|
|
865
|
+
skillInvocations: async () => ({ status: "unavailable", message })
|
|
653
866
|
};
|
|
654
867
|
}
|
|
655
868
|
|
|
@@ -677,15 +890,25 @@ export {
|
|
|
677
890
|
KAY_APP_AUTOMATION_CONDITION_KINDS,
|
|
678
891
|
KAY_APP_DATA_CHANGE_MAX_BYTES,
|
|
679
892
|
KAY_APP_DATA_SNAPSHOT_MAX_BYTES,
|
|
893
|
+
KAY_APP_MODEL_SELECTION_RESPONSE_BOUND_MS,
|
|
894
|
+
KAY_APP_MODEL_SELECTION_SEND_BOUND_MS,
|
|
895
|
+
KAY_APP_MODEL_SELECTION_START_BOUND_MS,
|
|
896
|
+
KAY_APP_SEALING_MAX_BYTES,
|
|
897
|
+
KayAppCredentialRejectedError,
|
|
680
898
|
KayAppWorkflowFailure,
|
|
681
899
|
MAX_CHOICE_LABELS,
|
|
682
900
|
SIGNAL_TIME_MAX_MS,
|
|
901
|
+
STORED_TRANSCRIPT_MESSAGE_FILTER,
|
|
902
|
+
STORED_TRANSCRIPT_MESSAGE_KINDS,
|
|
683
903
|
UriConflictError,
|
|
684
904
|
UriNotFoundError,
|
|
685
905
|
UriProviderError,
|
|
686
906
|
UriUnsupportedOperationError,
|
|
687
907
|
UriValidationError,
|
|
908
|
+
createConsoleKayPluginLog,
|
|
688
909
|
createFallbackOnlySignals,
|
|
910
|
+
createKayPluginLog,
|
|
911
|
+
createUnavailableSealing,
|
|
689
912
|
createUnavailableSkills,
|
|
690
913
|
createUnavailableTools,
|
|
691
914
|
createUnavailableUsage,
|
|
@@ -694,9 +917,13 @@ export {
|
|
|
694
917
|
invalidObservation,
|
|
695
918
|
isRetryable,
|
|
696
919
|
parseLineSelector,
|
|
920
|
+
parseStoredTranscriptKindFilter,
|
|
697
921
|
pathToFileURL,
|
|
698
922
|
payload,
|
|
923
|
+
requireWriteContent,
|
|
924
|
+
storedTranscriptKindOf,
|
|
699
925
|
transcriptMessageText,
|
|
700
926
|
transcriptMessageTexts,
|
|
701
|
-
transcriptRoleLabel
|
|
927
|
+
transcriptRoleLabel,
|
|
928
|
+
withCredential
|
|
702
929
|
};
|
package/dist/phase-shift.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ declare type PhaseShiftCost = z.infer<typeof phaseShiftCostSchema>;
|
|
|
28
28
|
* the feature accounts for itself.
|
|
29
29
|
*
|
|
30
30
|
* Absent on a record written before the detector accounted for itself, and on
|
|
31
|
-
* a call no attempt priced
|
|
31
|
+
* a call no attempt priced - absence means "not recorded", never zero.
|
|
32
32
|
*/
|
|
33
33
|
declare const phaseShiftCostSchema: z.ZodObject<{
|
|
34
34
|
amountUsd: z.ZodNumber;
|
|
@@ -45,7 +45,7 @@ declare const phaseShiftCostSchema: z.ZodObject<{
|
|
|
45
45
|
/** One accepted transition, placed in time. */
|
|
46
46
|
export declare interface PhaseShiftTimelineChange {
|
|
47
47
|
readonly startEntryId: string;
|
|
48
|
-
/** When the new work began
|
|
48
|
+
/** When the new work began - the onset entry's own timestamp, not the judgment's. */
|
|
49
49
|
readonly startedAt: string;
|
|
50
50
|
readonly relation: "outcome" | "phase";
|
|
51
51
|
readonly reason: string;
|
|
@@ -69,7 +69,7 @@ export declare function phaseShiftTimelineFromEntries(entries: readonly Transcri
|
|
|
69
69
|
*
|
|
70
70
|
* A record is evidence about the span it names and nothing else: time outside
|
|
71
71
|
* every record's `[windowStartAt, throughAt]` is unobserved, which is not the
|
|
72
|
-
* same as unchanged. An empty `changes` is the opposite
|
|
72
|
+
* same as unchanged. An empty `changes` is the opposite - a check that ran and
|
|
73
73
|
* found no transition.
|
|
74
74
|
*/
|
|
75
75
|
export declare interface PhaseShiftTimelineRecord {
|
|
@@ -100,7 +100,7 @@ declare interface TranscriptEntryLike {
|
|
|
100
100
|
readonly id: string;
|
|
101
101
|
readonly type: string;
|
|
102
102
|
readonly customType?: string;
|
|
103
|
-
/** Opaque. Never parsed or validated here
|
|
103
|
+
/** Opaque. Never parsed or validated here - a feature's own schema owns that. */
|
|
104
104
|
readonly data?: unknown;
|
|
105
105
|
}
|
|
106
106
|
|
package/dist/system-one.d.ts
CHANGED
|
@@ -231,12 +231,25 @@ export declare interface SystemOneAvailability {
|
|
|
231
231
|
readonly cause?: SystemOneFailureCause;
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
+
/** Structurally the plugin SDK's `KayAppSessionEventCause`: only the fields the host reads. */
|
|
235
|
+
declare interface SystemOneCallCause {
|
|
236
|
+
readonly kind?: "session-event" | "backfill";
|
|
237
|
+
readonly handler: string;
|
|
238
|
+
readonly sourceSessionId: string;
|
|
239
|
+
}
|
|
240
|
+
|
|
234
241
|
export declare interface SystemOneCallOptions {
|
|
235
242
|
readonly signal?: AbortSignal;
|
|
236
243
|
/** Bounds the whole call, retries included. */
|
|
237
244
|
readonly timeoutMs?: number;
|
|
238
245
|
/** What the call is for, carried to the host's usage accounting. Never sent to a provider. */
|
|
239
246
|
readonly purpose?: string;
|
|
247
|
+
/**
|
|
248
|
+
* The session event a plugin's call answers, so the host charges the call to that session.
|
|
249
|
+
* The host checks the plugin is handling that session's event right now. Never sent to a
|
|
250
|
+
* provider.
|
|
251
|
+
*/
|
|
252
|
+
readonly cause?: SystemOneCallCause;
|
|
240
253
|
}
|
|
241
254
|
|
|
242
255
|
export declare interface SystemOneClient {
|
package/dist/time.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare function isValidZone(id: unknown): boolean;
|
|
|
17
17
|
/**
|
|
18
18
|
* `app.time` / `api.time`: host facts about time. Added to `kay.app` in SDK 0.12.1 and to
|
|
19
19
|
* `kay.agent` with the calendar zone-of-record work: a plugin that calls it declares
|
|
20
|
-
* `compatibility.sdk` `^0.
|
|
20
|
+
* `compatibility.sdk` `^0.19.0`, so an older Bonsai refuses a directory or repository plugin at
|
|
21
21
|
* load instead of the call failing.
|
|
22
22
|
*/
|
|
23
23
|
export declare interface KayAppTime {
|
|
@@ -27,9 +27,7 @@ export declare interface KayAppTime {
|
|
|
27
27
|
* Every call asks the host again and returns a new object; nothing is cached. Call it where you
|
|
28
28
|
* need the value (inside a tool, a handler or a workflow step), not inside `activate()`: a value
|
|
29
29
|
* read there is as old as the activation, and the host can run a bundled plugin's `activate()`
|
|
30
|
-
* against a recording api that has no `time`, so a read there throws.
|
|
31
|
-
* directory plugin that declares a workflow with a cron `timezone`: `workflows.define` is legal
|
|
32
|
-
* only during `activate()`, so it reads the zone there, and the schedule then keeps that zone.
|
|
30
|
+
* against a recording api that has no `time`, so a read there throws.
|
|
33
31
|
* Keep the result for as long as you use it, and not across a long wait (a sleep, a timer, a
|
|
34
32
|
* queued run): the zone can change while you wait. On a daemon that runs on the user's machine,
|
|
35
33
|
* a change of the process's `TZ` shows in the next call. A `TZ` that names a zone wins over the
|
|
@@ -152,6 +152,16 @@ export declare interface TranscriptReview {
|
|
|
152
152
|
readonly start: number;
|
|
153
153
|
readonly end: number;
|
|
154
154
|
} | undefined;
|
|
155
|
+
/**
|
|
156
|
+
* The run whose own extent holds this position, the one starting latest; among runs that
|
|
157
|
+
* start at the same position, the first in run order. Undefined before the first run and at
|
|
158
|
+
* or after the end.
|
|
159
|
+
*/
|
|
160
|
+
runAt(position: number): {
|
|
161
|
+
readonly runId: string;
|
|
162
|
+
readonly start: number;
|
|
163
|
+
readonly end: number;
|
|
164
|
+
} | undefined;
|
|
155
165
|
/** The run input carrying this input id. */
|
|
156
166
|
inputById(inputId: string): TranscriptReviewRunInput | undefined;
|
|
157
167
|
attemptAt(position: number, block: number): ToolCallAttempt | undefined;
|
|
@@ -533,43 +533,98 @@ function createTranscriptReview(options = {}) {
|
|
|
533
533
|
}
|
|
534
534
|
starts.sort((left, right) => left.boundary - right.boundary);
|
|
535
535
|
const runStarts = [...finalRuns.values()].map((run) => ({ runId: run.runId, boundary: run.boundary })).sort((left, right) => left.boundary - right.boundary);
|
|
536
|
+
const runEndAt = Array.from({ length: runStarts.length });
|
|
537
|
+
for (let at = runStarts.length - 1; at >= 0; at -= 1) {
|
|
538
|
+
const next = runStarts[at + 1];
|
|
539
|
+
runEndAt[at] = next === void 0 ? endPosition : next.boundary > runStarts[at].boundary ? next.boundary : runEndAt[at + 1];
|
|
540
|
+
}
|
|
541
|
+
const runStartIndex = /* @__PURE__ */ new Map();
|
|
542
|
+
runStarts.forEach((run, at) => runStartIndex.set(run.runId, at));
|
|
543
|
+
const lastProseBefore = [];
|
|
544
|
+
let lastProse;
|
|
545
|
+
for (const record of records) {
|
|
546
|
+
lastProseBefore.push(lastProse);
|
|
547
|
+
if (record.hasProse)
|
|
548
|
+
lastProse = record.position;
|
|
549
|
+
}
|
|
536
550
|
const previousProse = (before) => {
|
|
537
|
-
|
|
538
|
-
|
|
551
|
+
const index = byPosition.get(before);
|
|
552
|
+
return index === void 0 ? void 0 : lastProseBefore[index];
|
|
553
|
+
};
|
|
554
|
+
const spanIndexAt = (position) => {
|
|
555
|
+
if (position >= endPosition)
|
|
539
556
|
return void 0;
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
557
|
+
let low = 0;
|
|
558
|
+
let high = starts.length - 1;
|
|
559
|
+
let found;
|
|
560
|
+
while (low <= high) {
|
|
561
|
+
const middle = low + high >> 1;
|
|
562
|
+
if (starts[middle].boundary <= position) {
|
|
563
|
+
found = middle;
|
|
564
|
+
low = middle + 1;
|
|
565
|
+
} else {
|
|
566
|
+
high = middle - 1;
|
|
567
|
+
}
|
|
543
568
|
}
|
|
544
|
-
return
|
|
569
|
+
return found;
|
|
570
|
+
};
|
|
571
|
+
const ownRunsOf = starts.map(() => ({
|
|
572
|
+
ids: [],
|
|
573
|
+
seen: /* @__PURE__ */ new Set()
|
|
574
|
+
}));
|
|
575
|
+
const addOwnRun = (span, runId) => {
|
|
576
|
+
const own = ownRunsOf[span];
|
|
577
|
+
if (own.seen.has(runId))
|
|
578
|
+
return;
|
|
579
|
+
own.seen.add(runId);
|
|
580
|
+
own.ids.push(runId);
|
|
581
|
+
};
|
|
582
|
+
for (const run of runStarts) {
|
|
583
|
+
const started = finalRuns.get(run.runId).startedPosition;
|
|
584
|
+
if (started === void 0)
|
|
585
|
+
continue;
|
|
586
|
+
const span = spanIndexAt(started);
|
|
587
|
+
if (span !== void 0)
|
|
588
|
+
addOwnRun(span, run.runId);
|
|
589
|
+
}
|
|
590
|
+
const joinedOf = starts.map(() => []);
|
|
591
|
+
for (const input of inputs) {
|
|
592
|
+
if (input.runId === void 0)
|
|
593
|
+
continue;
|
|
594
|
+
const span = spanIndexAt(input.position);
|
|
595
|
+
if (span === void 0)
|
|
596
|
+
continue;
|
|
597
|
+
addOwnRun(span, input.runId);
|
|
598
|
+
if (input.human && !input.opensRun)
|
|
599
|
+
joinedOf[span].push(input);
|
|
600
|
+
}
|
|
601
|
+
const firstInputAtOrAfter = (position) => {
|
|
602
|
+
let low = 0;
|
|
603
|
+
let high = inputs.length;
|
|
604
|
+
while (low < high) {
|
|
605
|
+
const middle = low + high >> 1;
|
|
606
|
+
if (inputs[middle].position < position)
|
|
607
|
+
low = middle + 1;
|
|
608
|
+
else
|
|
609
|
+
high = middle;
|
|
610
|
+
}
|
|
611
|
+
return low;
|
|
545
612
|
};
|
|
546
613
|
const spans = starts.map((start, index) => {
|
|
547
614
|
const next = starts[index + 1];
|
|
548
615
|
const end = next?.boundary ?? endPosition;
|
|
549
616
|
const closingEnd = next?.opener !== void 0 ? Math.max(end, next.opener.position + 1) : end;
|
|
550
|
-
const ownRuns = [];
|
|
617
|
+
const ownRuns = ownRunsOf[index].ids;
|
|
551
618
|
const closingRuns = [];
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
}
|
|
559
|
-
const joined = [];
|
|
560
|
-
for (const input of inputs) {
|
|
561
|
-
if (input.runId === void 0)
|
|
562
|
-
continue;
|
|
563
|
-
if (input.position >= start.boundary && input.position < end) {
|
|
564
|
-
if (!ownRuns.includes(input.runId))
|
|
565
|
-
ownRuns.push(input.runId);
|
|
566
|
-
if (input.human && !input.opensRun)
|
|
567
|
-
joined.push(input);
|
|
568
|
-
} else if (input.position >= end && input.position < closingEnd) {
|
|
569
|
-
if (!closingRuns.includes(input.runId))
|
|
570
|
-
closingRuns.push(input.runId);
|
|
619
|
+
const closingSeen = /* @__PURE__ */ new Set();
|
|
620
|
+
for (let at = firstInputAtOrAfter(end); at < inputs.length && inputs[at].position < closingEnd; at += 1) {
|
|
621
|
+
const runId = inputs[at].runId;
|
|
622
|
+
if (runId !== void 0 && !closingSeen.has(runId)) {
|
|
623
|
+
closingSeen.add(runId);
|
|
624
|
+
closingRuns.push(runId);
|
|
571
625
|
}
|
|
572
626
|
}
|
|
627
|
+
const joined = joinedOf[index];
|
|
573
628
|
ownRuns.sort((left, right) => finalRuns.get(left).boundary - finalRuns.get(right).boundary);
|
|
574
629
|
const close = next !== void 0 ? next.opener !== void 0 ? "next-opener" : "next-opener-unresolved" : cutAt !== void 0 ? "time-bound" : "end-of-store";
|
|
575
630
|
const previousAnswer = previousProse(start.boundary);
|
|
@@ -626,12 +681,30 @@ function createTranscriptReview(options = {}) {
|
|
|
626
681
|
},
|
|
627
682
|
spanAt: (position) => position < endPosition ? lastAtOrBefore(spans, position) : void 0,
|
|
628
683
|
runExtent: (runId) => {
|
|
629
|
-
const
|
|
630
|
-
|
|
684
|
+
const at = runStartIndex.get(runId);
|
|
685
|
+
return at === void 0 ? void 0 : { start: runStarts[at].boundary, end: runEndAt[at] };
|
|
686
|
+
},
|
|
687
|
+
runAt: (position) => {
|
|
688
|
+
let low = 0;
|
|
689
|
+
let high = runStarts.length - 1;
|
|
690
|
+
let found;
|
|
691
|
+
while (low <= high) {
|
|
692
|
+
const middle = low + high >> 1;
|
|
693
|
+
if (runStarts[middle].boundary <= position) {
|
|
694
|
+
found = middle;
|
|
695
|
+
low = middle + 1;
|
|
696
|
+
} else {
|
|
697
|
+
high = middle - 1;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
if (found === void 0)
|
|
701
|
+
return void 0;
|
|
702
|
+
const start = runStarts[found].boundary;
|
|
703
|
+
while (found > 0 && runStarts[found - 1].boundary === start)
|
|
704
|
+
found -= 1;
|
|
705
|
+
if (position >= runEndAt[found])
|
|
631
706
|
return void 0;
|
|
632
|
-
|
|
633
|
-
const next = runStarts.slice(at + 1).find((candidate) => candidate.boundary > run.boundary);
|
|
634
|
-
return { start: run.boundary, end: next?.boundary ?? endPosition };
|
|
707
|
+
return { runId: runStarts[found].runId, start, end: runEndAt[found] };
|
|
635
708
|
},
|
|
636
709
|
inputById: (inputId) => inputById.get(inputId),
|
|
637
710
|
attemptAt: (position, block) => {
|
package/dist/transcript.d.ts
CHANGED
|
@@ -15,16 +15,16 @@ export declare const ATTACHMENTS_CUSTOM_TYPE = "attachments";
|
|
|
15
15
|
export declare function branchEntryIds(entries: readonly TranscriptTreeEntryLike[]): ReadonlySet<string>;
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* Every `type: "custom"` entry of one `customType`, oldest
|
|
18
|
+
* Every `type: "custom"` entry of one `customType`, oldest->newest, with every
|
|
19
19
|
* field ({@link TranscriptSourceEntryLike}'s id/timestamp/tree links plus the
|
|
20
|
-
* entry's own `data`) preserved unchanged
|
|
20
|
+
* entry's own `data`) preserved unchanged - `data` is returned exactly as it
|
|
21
21
|
* arrived, opaque and unvalidated, never coerced toward a schema this module
|
|
22
22
|
* cannot know.
|
|
23
23
|
*
|
|
24
24
|
* `options.branch` is required, deliberately: `"active"` filters to
|
|
25
25
|
* {@link branchEntryIds}; `"all"` returns every matching entry in the flat
|
|
26
26
|
* log, rewind-abandoned or not. A silent default would let a caller reach
|
|
27
|
-
* for whichever one it did not mean to
|
|
27
|
+
* for whichever one it did not mean to - pick `"all"` only when the caller
|
|
28
28
|
* itself needs to reason about abandoned entries (an audit, a recovery
|
|
29
29
|
* tool); an ordinary reader states `"active"` explicitly.
|
|
30
30
|
*/
|
|
@@ -53,7 +53,7 @@ declare type ProducedResourceAction = "created" | "updated";
|
|
|
53
53
|
|
|
54
54
|
/** One URI a tool call created or updated as a side effect. */
|
|
55
55
|
declare interface ProducedResourceDeclaration {
|
|
56
|
-
/** A `scheme
|
|
56
|
+
/** A `scheme://...` URI or an absolute local file path, compared as an exact string. */
|
|
57
57
|
readonly uri: string;
|
|
58
58
|
readonly action: ProducedResourceAction;
|
|
59
59
|
}
|
|
@@ -92,7 +92,7 @@ export declare interface TranscriptEntryLike {
|
|
|
92
92
|
readonly id: string;
|
|
93
93
|
readonly type: string;
|
|
94
94
|
readonly customType?: string;
|
|
95
|
-
/** Opaque. Never parsed or validated here
|
|
95
|
+
/** Opaque. Never parsed or validated here - a feature's own schema owns that. */
|
|
96
96
|
readonly data?: unknown;
|
|
97
97
|
}
|
|
98
98
|
|
|
@@ -162,7 +162,9 @@ export declare interface TurnSegment {
|
|
|
162
162
|
* nothing distinguishes a steer from a fresh request.
|
|
163
163
|
*
|
|
164
164
|
* `throughIndex` bounds the walk for a caller holding only a prefix; segments
|
|
165
|
-
* are returned oldest first.
|
|
165
|
+
* are returned oldest first. A daemon reader that cannot hold the entry list
|
|
166
|
+
* looks the run up by run id instead (engine redesign 3.1,
|
|
167
|
+
* `docs/engine-redesign/decisions/2026-10-28-3.1-turn-definition.md`).
|
|
166
168
|
*/
|
|
167
169
|
export declare function turnSegments(entries: readonly TurnBoundaryEntry[], throughIndex?: number): readonly TurnSegment[];
|
|
168
170
|
|