@yaklabs-ai/plugin-sdk 0.10.0 → 0.12.2

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.
@@ -1,8 +1,3 @@
1
- import { Questions } from '@typesafe-ai/sdk';
2
- import { SystemOneRequest } from '@typesafe-ai/sdk';
3
- import { SystemOneResult } from '@typesafe-ai/sdk';
4
- import { TypeSafeClient } from '@typesafe-ai/sdk';
5
- import { Usage } from '@typesafe-ai/sdk';
6
1
  import { z } from 'zod';
7
2
  import type * as z_2 from 'zod';
8
3
 
@@ -28,6 +23,9 @@ export declare interface AccountIdentity {
28
23
  readonly avatarUrl?: string;
29
24
  /** Issuer-asserted beta-tester flag; only Kay's product-account service sets it. */
30
25
  readonly betaTester?: boolean;
26
+ readonly activeOrganizationId?: string;
27
+ readonly organizationSelectionState?: "selected" | "unresolved";
28
+ readonly organizationScopeEpoch?: number;
31
29
  /**
32
30
  * Provider-native session id claim (WorkOS's `sid`), needed to call the provider's own
33
31
  * session-revocation endpoint at sign-out (`POST /user_management/sessions/revoke`, not yet
@@ -100,8 +98,18 @@ export declare interface AgentToolResult<T = JsonValue_2 | undefined> {
100
98
  content: (TextContent | ImageContent)[];
101
99
  /** Arbitrary structured details for logs or UI rendering. */
102
100
  details: T;
101
+ /**
102
+ * Machine-readable result matching the tool's `outputSchema`, for programmatic callers. Not sent
103
+ * to the model; `content` remains the model-facing result.
104
+ */
105
+ structuredContent?: JsonValue_2;
103
106
  /** Usage from the final tool execution itself, if available. Not used for main LLM context accounting. */
104
- usage?: Usage_2;
107
+ usage?: Usage;
108
+ /**
109
+ * Report a failure without throwing. The model sees `content` as an error result, like a thrown
110
+ * error, but `details` and `structuredContent` are kept for the UI and programmatic callers.
111
+ */
112
+ isError?: boolean;
105
113
  /**
106
114
  * Hint that the agent should stop after the current tool batch.
107
115
  * Early termination only happens when every finalized tool result in the batch sets this to true.
@@ -340,6 +348,20 @@ declare interface BackgroundTaskSnapshot {
340
348
 
341
349
  declare type BackgroundTaskStatus = "queued" | "running" | "completed" | "failed" | "cancelled";
342
350
 
351
+ /** Fields shared by every catalog entry, regardless of what you can do with it. */
352
+ declare interface BaseModel<TApi extends string> {
353
+ id: string;
354
+ name: string;
355
+ api: TApi;
356
+ provider: ProviderId;
357
+ baseUrl: string;
358
+ input: ("text" | "image")[];
359
+ /** Provider input limits and cache-safe preprocessing metadata. */
360
+ inputLimits?: ModelInputLimits;
361
+ cost: ModelCost;
362
+ headers?: Record<string, string>;
363
+ }
364
+
343
365
  export declare function basicUriHelp(options: {
344
366
  readonly uri: string;
345
367
  readonly title: string;
@@ -595,6 +617,27 @@ export declare interface CurrentResourceState {
595
617
  readonly content?: string | Uint8Array;
596
618
  }
597
619
 
620
+ /**
621
+ * Declare the URIs a tool call created or updated as a side effect, on the result it returns.
622
+ *
623
+ * The declarations ride the result to the host, which records them in the transcript under the
624
+ * reserved `producedResources` details key, so an automation run lists them beside the URIs its
625
+ * `write` and `edit` calls changed. A declaration the contract refuses (not exactly `{ uri, action }`,
626
+ * a URI that is neither `scheme://…` nor an absolute local path, an unknown action) never fails the
627
+ * call, because its effect has already happened: the host records the call's claim as malformed,
628
+ * the run reports a gap for it, and the session logs a warning. A tool never writes the reserved key
629
+ * itself; the host drops whatever a result's own details hold there. Declarations ride only a
630
+ * returned result: a call that throws declares nothing.
631
+ *
632
+ * @param result The result the tool returns. Its `details` must be an object or `undefined`;
633
+ * `undefined` becomes an empty object that carries the declarations.
634
+ * @param declarations Each names a `scheme://` URI or an absolute local path, compared as an
635
+ * exact string, and whether the call `created` or `updated` it.
636
+ * @returns A copy of `result` carrying these declarations after any it already carried.
637
+ * @throws TypeError when `details` is neither an object nor `undefined`, which the types rule out.
638
+ */
639
+ export declare function declareProducedResources<TDetails extends object | undefined>(result: AgentToolResult<TDetails>, declarations: readonly ProducedResourceDeclaration[]): AgentToolResult<DetailsWithProducedResources<TDetails>>;
640
+
598
641
  /**
599
642
  * The one-liner for an auth-gated tool (decision 002 addendum, F-19). Composes
600
643
  * {@link toolParameters}, {@link withResolvedAuth}, and `schema.parse` so `body` receives a
@@ -623,6 +666,8 @@ export declare function defineKayAgentAdvertisement(advertisement: KayAgentTarge
623
666
 
624
667
  export declare function defineTool<TParams extends ToolParametersWire = ToolParametersWire, TDetails = unknown>(definition: PluginToolDefinition<TParams, TDetails>): ToolDefinition<TParams, TDetails>;
625
668
 
669
+ declare const DELEGATED_REFRESH_REJECTED: unique symbol;
670
+
626
671
  /**
627
672
  * What `service_connect` hands a delegated scheme's {@link DelegatedAuthScheme.connect}: the
628
673
  * scope being connected plus the host's browser-redirect capability when one is configured.
@@ -644,12 +689,29 @@ declare interface DelegatedConnectContext {
644
689
  /** What a delegated scheme's `connect` resolves with: the material to vault + optional label/provenance. */
645
690
  declare interface DelegatedConnectResult {
646
691
  readonly material: DelegatedSecretMaterial;
692
+ /**
693
+ * A stable account id for this sign-in, used instead of a freshly minted one, so a reconnect
694
+ * overwrites the same record (and keeps it the default) rather than adding a sibling. 1-128
695
+ * characters: letters, digits, and `._:@+-`, starting with a letter or digit; any other value
696
+ * fails the connect. Absent mints a fresh id per connect.
697
+ */
698
+ readonly accountId?: string;
647
699
  /** Account display label; a caller-supplied `service_connect` label takes precedence. */
648
700
  readonly label?: string;
649
701
  /** Structured provenance the scheme derived during connect; persisted via the vault's write-path. */
650
702
  readonly provenance?: AccountProvenance;
651
703
  }
652
704
 
705
+ /**
706
+ * The terminal failure of {@link PluginDelegatedScheme.refresh}: the provider no longer accepts the
707
+ * stored grant (an OAuth `invalid_grant`, say), so only a reconnect helps. Kay marks the account
708
+ * as needing a reconnect. Throw any other error for a failure that may pass on its own.
709
+ */
710
+ export declare class DelegatedRefreshRejectedError extends Error {
711
+ readonly [DELEGATED_REFRESH_REJECTED] = true;
712
+ constructor(message: string, options?: ErrorOptions);
713
+ }
714
+
653
715
  /**
654
716
  * Token material minted by a delegated scheme's extension-provided flow. Core reads only
655
717
  * `accessToken`/`expiresAt` (resolution + proactive refresh); `data` is an opaque blob the
@@ -685,6 +747,9 @@ declare interface DerivedToolClassification {
685
747
  */
686
748
  export declare function describeUriTextEditTarget(grammar: UriTextEditGrammar, index: number, count: number): string;
687
749
 
750
+ /** `details` once it carries declarations: an `undefined` input becomes an empty object. */
751
+ export declare type DetailsWithProducedResources<TDetails> = TDetails extends undefined ? Record<string, never> : TDetails;
752
+
688
753
  /**
689
754
  * The execute-time auth surface the SDK wrappers read off `ctx.auth`. Slice 3 attaches a
690
755
  * concrete implementation (vault + pkce refresh + active-account store) to ExtensionContext;
@@ -814,6 +879,366 @@ declare type InferToolInput<TParams extends ToolParametersWire> = TParams extend
814
879
  readonly [toolParametersInput]?: infer TInput;
815
880
  } ? TInput : TParams;
816
881
 
882
+ /**
883
+ * The value a Browser Interaction driver sets as `credentialGuard` to declare that every act runs
884
+ * the page-side credential guard from `@kay/interaction-page-scripts` (never type into or click a
885
+ * sign-in form). The engine refuses to register a browser driver without it.
886
+ */
887
+ export declare const INTERACTION_CREDENTIAL_GUARD = "kay.credential-guard/v1";
888
+
889
+ export declare interface InteractionActed {
890
+ /** The address of the target acted on, when it changed (an open landed in a new page). */
891
+ readonly target?: string;
892
+ readonly url: string;
893
+ readonly title: string;
894
+ /** What the action visibly caused: a dialog, an alert, a page opened beside it. */
895
+ readonly changes?: readonly string[];
896
+ readonly notes?: readonly string[];
897
+ /** Fresh browser sign-in state for the service the engine named in the open spec. */
898
+ readonly webSession?: {
899
+ readonly state: "signed-in" | "signed-out" | "unknown";
900
+ readonly checkedAt: number | null;
901
+ };
902
+ }
903
+
904
+ /**
905
+ * One action over a candidate from the latest observation of the same target. `fill` replaces the
906
+ * field's contents unless `append` is set, and presses Enter afterwards when `submit` is set.
907
+ */
908
+ export declare type InteractionAction = {
909
+ readonly kind: "click";
910
+ readonly element: InteractionCandidate;
911
+ } | {
912
+ readonly kind: "fill";
913
+ readonly element: InteractionCandidate;
914
+ readonly text: string;
915
+ readonly submit?: boolean;
916
+ readonly append?: boolean;
917
+ } | {
918
+ readonly kind: "select";
919
+ readonly element: InteractionCandidate;
920
+ } | {
921
+ readonly kind: "activate";
922
+ readonly element: InteractionCandidate;
923
+ } | {
924
+ readonly kind: "press";
925
+ readonly element: InteractionCandidate;
926
+ }
927
+ /**
928
+ * Scroll by `delta` px (positive is down). With `element` (a `scroll` candidate that names a
929
+ * node), the scroll container that candidate scrolls; without, the whole page or window.
930
+ */
931
+ | {
932
+ readonly kind: "scroll";
933
+ readonly delta: number;
934
+ readonly element?: InteractionCandidate;
935
+ } | {
936
+ readonly kind: "wait";
937
+ };
938
+
939
+ /**
940
+ * One element (or control) an observation offers, with the kind of action it supports. `id` is
941
+ * the driver's per-observation id; the engine mints its own session-unique ids over it. Extra
942
+ * fields are the driver's native identity (a page node number, an accessibility token), returned
943
+ * to the driver untouched in {@link InteractionAction}.
944
+ */
945
+ export declare interface InteractionCandidate {
946
+ readonly id: string;
947
+ readonly kind: InteractionCandidateKind;
948
+ readonly label: string;
949
+ readonly node?: number | undefined;
950
+ readonly role?: string | undefined;
951
+ readonly value?: string | undefined;
952
+ readonly current_value?: string | undefined;
953
+ readonly checked?: string | undefined;
954
+ readonly selected?: string | undefined;
955
+ readonly expanded?: string | undefined;
956
+ readonly delta?: number | undefined;
957
+ /** Where an element outside the visible area sits; absent means on screen. */
958
+ readonly position?: "above" | "below" | "beside" | undefined;
959
+ /** A `press` candidate's key (`return`, `escape`, `tab`); its id is `press_<key>` by convention. */
960
+ readonly key?: string | undefined;
961
+ /** The region the element sits in; see {@link InteractionRegion}. */
962
+ readonly region?: InteractionRegion | undefined;
963
+ /**
964
+ * The `node` of the scroll container (a list or pane that scrolls on its own) the element sits
965
+ * in, matching that container's `scroll` candidates; absent when it sits in none.
966
+ */
967
+ readonly scroller?: number | undefined;
968
+ readonly [native: string]: unknown;
969
+ }
970
+
971
+ /** The candidate kinds a driver may offer. */
972
+ export declare type InteractionCandidateKind = "click" | "fill" | "select" | "scroll" | "wait" | "activate" | "press";
973
+
974
+ export declare interface InteractionDriver {
975
+ /** Unique in the session. `builtin:` is reserved for Kay's own drivers. */
976
+ readonly id: string;
977
+ /** Human-readable name the agent sees beside the driver's targets. */
978
+ readonly label: string;
979
+ readonly kind: InteractionDriverKind;
980
+ /** Required on a `browser` driver; see {@link INTERACTION_CREDENTIAL_GUARD}. */
981
+ readonly credentialGuard?: typeof INTERACTION_CREDENTIAL_GUARD;
982
+ /** Whether the driver can act at all right now (platform, grants, a live connection). */
983
+ isAvailable(): Promise<boolean>;
984
+ targets(): Promise<InteractionOutcome<{
985
+ readonly targets: readonly InteractionTarget[];
986
+ }>>;
987
+ observe(target: string | undefined, options?: {
988
+ readonly fullText?: boolean;
989
+ }): Promise<InteractionOutcome<InteractionObserved>>;
990
+ act(target: string | undefined, action: InteractionAction): Promise<InteractionOutcome<InteractionActed>>;
991
+ screenshot(target: string | undefined): Promise<InteractionOutcome<{
992
+ readonly png: Uint8Array;
993
+ }>>;
994
+ open(spec: InteractionOpenSpec): Promise<InteractionOutcome<InteractionActed>>;
995
+ }
996
+
997
+ /**
998
+ * The Interaction driver contract: what a plugin implements to let Kay's agent drive something
999
+ * on the user's machine (a browser, an app, a remote screen) through the harness-owned
1000
+ * Interaction engine.
1001
+ *
1002
+ * The engine owns everything that is policy: the `interaction_*` tools, the session-unique element
1003
+ * ids the agent sees, the run loop that drives a goal step by step, the permission check before
1004
+ * every action, screenshots, and reports. A driver owns only its own I/O: list what it can drive,
1005
+ * observe one target as a list of actionable candidates, perform one action on a candidate from
1006
+ * its latest observation, capture a screenshot, and open a page or app. It chooses no actions,
1007
+ * maps no permissions, and retries nothing beyond its own transport. That split is what makes
1008
+ * every tool work on every driver.
1009
+ *
1010
+ * Shape mirrors `SearchProvider` behind `web_search`: one tool set owned by the harness, many
1011
+ * backends registered per session, the `builtin:` id namespace reserved for Kay's own.
1012
+ */
1013
+ /** "Browser Interaction" drives web pages; "Computer Use Interaction" drives native apps. */
1014
+ export declare type InteractionDriverKind = "browser" | "computer-use";
1015
+
1016
+ /** A failed operation. `unavailable`: nothing to act on; `refused`: will not run as asked. */
1017
+ export declare interface InteractionFailure {
1018
+ readonly ok: false;
1019
+ readonly reason: "unavailable" | "refused" | "error";
1020
+ readonly message: string;
1021
+ }
1022
+
1023
+ /** What a driver sees on one target. */
1024
+ export declare interface InteractionObservation {
1025
+ readonly url: string;
1026
+ readonly title: string;
1027
+ /** Visible text, or the whole page's text when the observe asked for `fullText`; capped. */
1028
+ readonly text: string;
1029
+ readonly actions: readonly InteractionCandidate[];
1030
+ /** Candidates the driver dropped to stay within its cap. */
1031
+ readonly omitted_actions: number;
1032
+ }
1033
+
1034
+ export declare interface InteractionObserved {
1035
+ /** The address of the target observed; absent when the default target has no address. */
1036
+ readonly target?: string;
1037
+ readonly observation: InteractionObservation;
1038
+ /** Lines the engine shows the agent under the observation (where the target sits, siblings). */
1039
+ readonly notes?: readonly string[];
1040
+ }
1041
+
1042
+ /** Navigate a page to `url`, or launch / switch to the app `app` names (a bundle id or a name). */
1043
+ export declare interface InteractionOpenSpec {
1044
+ readonly target?: string;
1045
+ readonly url?: string;
1046
+ readonly app?: string;
1047
+ /** The service whose browser sign-in state to report after navigation, when the engine knows it. */
1048
+ readonly webSessionServiceId?: string;
1049
+ }
1050
+
1051
+ export declare type InteractionOutcome<T> = ({
1052
+ readonly ok: true;
1053
+ } & T) | InteractionFailure;
1054
+
1055
+ /**
1056
+ * The part of a page or window an element sits in: the open dialog, menu, or sheet it belongs to,
1057
+ * else its landmark (navigation, main, a window). `front` marks the overlay covering the rest: a
1058
+ * modal dialog (or one held by a full-screen overlay), a sheet, or a floating menu, the last such
1059
+ * in the document; elements outside it
1060
+ * usually cannot be clicked while it is open. A docked or always-visible dialog or menu is a
1061
+ * region but never in front.
1062
+ */
1063
+ export declare interface InteractionRegion {
1064
+ readonly role: string;
1065
+ readonly name: string;
1066
+ readonly front?: boolean | undefined;
1067
+ }
1068
+
1069
+ /**
1070
+ * One surface Kay ships, in the driver contract's own shape, so a plugin's driver is the surface
1071
+ * plus an identity: `{ id, label, kind, ...api.interaction.desktop }`. Each call is checked
1072
+ * against the plugin's `interaction.surface {surface}` grant, and then against the session's
1073
+ * permissions exactly as the agent's `interaction_*` tools are: an act is judged as the plugin
1074
+ * permission it amounts to (a Send click in Gmail as a Gmail write), an open as `interaction_open`,
1075
+ * an observation or screenshot as `interaction_read`. A refused or unavailable call answers
1076
+ * `{ ok: false }` (and `isAvailable()` false) rather than throwing.
1077
+ */
1078
+ export declare type InteractionSurface = Pick<InteractionDriver, "isAvailable" | "targets" | "observe" | "act" | "screenshot" | "open">;
1079
+
1080
+ /** The interaction surfaces Kay itself ships, which plugins drive through `api.interaction`. */
1081
+ export declare type InteractionSurfaceName = "browser-pane" | "desktop";
1082
+
1083
+ /**
1084
+ * One thing a driver can be pointed at. `id` is a driver-owned address, unique across every
1085
+ * driver in the session (prefix it with your scheme), that the agent passes back as `target`.
1086
+ * `active` marks the driver's default target.
1087
+ */
1088
+ export declare interface InteractionTarget {
1089
+ readonly id: string;
1090
+ readonly title: string;
1091
+ readonly url?: string;
1092
+ readonly active: boolean;
1093
+ }
1094
+
1095
+ /** Whether `error` is a {@link DelegatedRefreshRejectedError}, including one from another SDK copy. */
1096
+ export declare function isDelegatedRefreshRejected(error: unknown): error is DelegatedRefreshRejectedError;
1097
+
1098
+ export declare type JevAnswer = JevBoolAnswer | JevChoiceAnswer | JevScoreAnswer;
1099
+
1100
+ /** The answer shape one question gets back. */
1101
+ export declare type JevAnswerFor<Q> = Q extends JevBoolQuestion ? JevBoolAnswer : Q extends JevChoiceQuestion<infer L> ? JevChoiceAnswer<L> : Q extends JevScoreQuestion ? JevScoreAnswer : never;
1102
+
1103
+ export declare interface JevBoolAnswer {
1104
+ readonly type: "bool";
1105
+ /** P(yes), from 0 to 1. */
1106
+ readonly probability: number;
1107
+ }
1108
+
1109
+ /** A yes/no question. `criteria` says what yes and what no mean; omit it to leave both open. */
1110
+ export declare interface JevBoolQuestion {
1111
+ readonly type: "bool";
1112
+ readonly instructions: string;
1113
+ readonly criteria?: {
1114
+ readonly true: string;
1115
+ readonly false: string;
1116
+ };
1117
+ }
1118
+
1119
+ /**
1120
+ * The one error `classify` rejects with. It carries a classification, never the provider's own
1121
+ * message or body: those can echo the request state, and this error reaches logs.
1122
+ */
1123
+ export declare class JevCallError extends Error {
1124
+ readonly transport: JevTransport;
1125
+ readonly kind: JevCallErrorKind;
1126
+ /** The final attempt's HTTP status, when a response arrived. */
1127
+ readonly status: number | undefined;
1128
+ constructor(init: {
1129
+ readonly transport: JevTransport;
1130
+ readonly kind: JevCallErrorKind;
1131
+ readonly status?: number | undefined;
1132
+ });
1133
+ }
1134
+
1135
+ /**
1136
+ * Why a Jev call failed, as a closed set:
1137
+ *
1138
+ * - `http`: the route answered with an error status (`status` says which).
1139
+ * - `too-large`: the route refused the request's size (413, or a 400 naming the token limit).
1140
+ * - `network`: no response arrived.
1141
+ * - `aborted`: the call was cancelled.
1142
+ * - `invalid-answer`: the route answered, but not with an answer for every asked question.
1143
+ */
1144
+ export declare type JevCallErrorKind = "http" | "too-large" | "network" | "aborted" | "invalid-answer";
1145
+
1146
+ export declare interface JevChoiceAnswer<L extends string = string> {
1147
+ readonly type: "choice";
1148
+ readonly choice: L;
1149
+ readonly confidence: number;
1150
+ /** P(label) for every offered label. */
1151
+ readonly probabilities: Readonly<Record<L, number>>;
1152
+ }
1153
+
1154
+ /** A choice among labels. Each label maps to what it means; an empty string leaves it open. */
1155
+ export declare interface JevChoiceQuestion<L extends string = string> {
1156
+ readonly type: "choice";
1157
+ readonly instructions: string;
1158
+ readonly criteria: Readonly<Record<L, string>>;
1159
+ }
1160
+
1161
+ /** One answered request: every asked question has an answer of its own kind. */
1162
+ export declare interface JevClassification<Q extends JevQuestions = JevQuestions> {
1163
+ /** The Jev model the host asked. */
1164
+ readonly model: string;
1165
+ readonly answers: {
1166
+ readonly [K in keyof Q]: JevAnswerFor<Q[K]>;
1167
+ };
1168
+ /** Token counts, when the route reported them. */
1169
+ readonly usage?: {
1170
+ readonly inputTokens: number;
1171
+ readonly outputTokens: number;
1172
+ };
1173
+ }
1174
+
1175
+ export declare interface JevClassifyRequest<Q extends JevQuestions = JevQuestions> {
1176
+ readonly state: JevState;
1177
+ readonly questions: Q;
1178
+ }
1179
+
1180
+ /**
1181
+ * The Jev client a `use` body receives. `classify` either resolves with an answer for every
1182
+ * asked question, each of its question's kind, or rejects with a {@link JevCallError}; it never
1183
+ * resolves with a partial or substituted answer.
1184
+ */
1185
+ export declare interface JevClient {
1186
+ classify<const Q extends JevQuestions>(request: JevClassifyRequest<Q>, options?: {
1187
+ readonly signal?: AbortSignal;
1188
+ }): Promise<JevClassification<Q>>;
1189
+ }
1190
+
1191
+ export declare type JevQuestion = JevBoolQuestion | JevChoiceQuestion | JevScoreQuestion;
1192
+
1193
+ /** A rubric: questions keyed by the name each answer comes back under. */
1194
+ export declare type JevQuestions = Readonly<Record<string, JevQuestion>>;
1195
+
1196
+ export declare interface JevScoreAnswer {
1197
+ readonly type: "score";
1198
+ /** The expected score, from 0 to the number of rungs minus one. */
1199
+ readonly score: number;
1200
+ readonly confidence: number;
1201
+ }
1202
+
1203
+ /** A score over ordered rungs: the first criterion scores 0, the next 1, and so on. */
1204
+ export declare interface JevScoreQuestion {
1205
+ readonly type: "score";
1206
+ readonly instructions: string;
1207
+ readonly criteria: readonly string[];
1208
+ }
1209
+
1210
+ /**
1211
+ * ---
1212
+ * responsibility: The plugin-facing CONTRACT for Jev typed-decision inference — the shape of
1213
+ * `api.withJev` on both plugin SDK targets, the {@link JevClient} a `use` body receives, the
1214
+ * question and answer vocabulary it speaks, and the fallback-only implementation a host
1215
+ * without a Jev lane binds.
1216
+ * owns:
1217
+ * - {@link WithJev}, {@link WithJevOptions}, {@link createFallbackOnlyWithJev}.
1218
+ * - {@link JevClient}, the {@link JevQuestion} and {@link JevAnswer} vocabulary, and
1219
+ * {@link JevCallError}.
1220
+ * does_not_own:
1221
+ * - The wire. The host serves `classify` over whichever route the user's Jev provider order
1222
+ * picks; a plugin never sees a vendor client, a vendor type, or a route.
1223
+ * - Credential resolution, the `jev.use` decision, the Jev-branch budget, or usage accounting.
1224
+ * Those are host-side (`@kay/agent-runtime`'s `kay/jev/`).
1225
+ * ---
1226
+ *
1227
+ * The vocabulary is Kay's own (SDK 0.12.0). Before it, `use` received TypeSafe's `TypeSafeClient`
1228
+ * and plugins coded against a vendor's types. It follows pi's classifier contract, which the host
1229
+ * runs Jev through: a yes/no question is `bool` and answers a `probability`, every instruction and
1230
+ * criterion is text, and the state is a JSON object.
1231
+ */
1232
+ /**
1233
+ * The state a rubric reads: a JSON object, never text or an array. Every value must survive
1234
+ * `JSON.stringify` unchanged (no functions or class instances), because it is sent as JSON.
1235
+ * Typed as `object` so a state declared as an interface fits without an index signature.
1236
+ */
1237
+ export declare type JevState = object;
1238
+
1239
+ /** The route a Jev call took: the user's own TypeSafe key, or Bonsai's hosted gateway. */
1240
+ export declare type JevTransport = "direct" | "hosted";
1241
+
817
1242
  /** The frozen `createJsonApiClient` surface — see the module doc for why it stops at these three. */
818
1243
  export declare interface JsonApiClient {
819
1244
  getJson<TBody = unknown>(url: string, options?: PluginApiQueryOptions): Promise<PluginApiResponse<TBody>>;
@@ -848,6 +1273,14 @@ declare type JsonValue_3 = string | number | boolean | null | JsonValue_3[] | {
848
1273
 
849
1274
  declare const JsonValue_3: z.ZodType<JsonValue_3>;
850
1275
 
1276
+ /**
1277
+ * The root selector the host binds to the session family's shared Whiteboard folder. The plugin
1278
+ * that owns the Whiteboard gets the whole folder; every other plugin gets its own
1279
+ * `plugins/<plugin-id>/` folder inside it. Calls on it are claims on
1280
+ * `filesystem.read`/`filesystem.write` with this `root`, decided like any other.
1281
+ */
1282
+ export declare const KAY_FAMILY_WHITEBOARD_FILESYSTEM_ROOT = "family-whiteboard";
1283
+
851
1284
  /** A plugin's Kay agent activation — receives only the brokered {@link KayAgentPluginApi}. */
852
1285
  export declare type KayAgentActivate = (api: KayAgentPluginApi) => void;
853
1286
 
@@ -938,10 +1371,18 @@ export declare interface KayAgentEvents {
938
1371
  publish(localId: string, payload: unknown): void;
939
1372
  }
940
1373
 
941
- /** Claim-checked filesystem operations. Paths are root-relative; canonical host paths never cross the seam. */
1374
+ /**
1375
+ * Claim-checked filesystem operations. Paths are root-relative; canonical host paths never cross
1376
+ * the seam. Writes are atomic: readers see the old file or the new one, never a partial write. A
1377
+ * replace keeps the file's mode but makes a new file, so owner and extended attributes are not
1378
+ * carried over. On a volume without hard links an exclusive create can briefly show an empty file.
1379
+ */
942
1380
  export declare interface KayAgentFilesystem {
943
1381
  readText(location: KayAgentFilesystemLocation): Promise<string>;
944
- writeText(location: KayAgentFilesystemLocation, content: string): Promise<void>;
1382
+ writeText(location: KayAgentFilesystemLocation, content: string, options?: KayAgentFilesystemWriteOptions): Promise<void>;
1383
+ /** The whole file, or the requested window of it. */
1384
+ readBytes(location: KayAgentFilesystemLocation, range?: KayAgentFilesystemByteRange): Promise<Uint8Array>;
1385
+ writeBytes(location: KayAgentFilesystemLocation, bytes: Uint8Array, options?: KayAgentFilesystemWriteOptions): Promise<void>;
945
1386
  mkdir(location: KayAgentFilesystemLocation): Promise<void>;
946
1387
  readDir(location: KayAgentFilesystemLocation): Promise<readonly KayAgentFilesystemEntry[]>;
947
1388
  stat(location: KayAgentFilesystemLocation): Promise<KayAgentFilesystemStat>;
@@ -950,6 +1391,12 @@ export declare interface KayAgentFilesystem {
950
1391
  realpath(location: KayAgentFilesystemLocation): Promise<string>;
951
1392
  }
952
1393
 
1394
+ /** A byte window of a file; `maxBytes` is capped by the host. */
1395
+ export declare interface KayAgentFilesystemByteRange {
1396
+ readonly offset: number;
1397
+ readonly maxBytes: number;
1398
+ }
1399
+
953
1400
  export declare interface KayAgentFilesystemEntry {
954
1401
  readonly name: string;
955
1402
  readonly kind: "file" | "directory" | "symlink" | "other";
@@ -974,6 +1421,35 @@ export declare interface KayAgentFilesystemStat {
974
1421
  readonly modifiedAtMs: number;
975
1422
  }
976
1423
 
1424
+ export declare interface KayAgentFilesystemWriteOptions {
1425
+ /** Fail with `already_exists` instead of replacing a file already at the location. */
1426
+ readonly exclusive?: boolean;
1427
+ }
1428
+
1429
+ /**
1430
+ * The host's per-session sink a plugin's drivers register into. Bound by the host to the plugin
1431
+ * and the session; a host that composed no Interaction engine drops registrations.
1432
+ */
1433
+ export declare interface KayAgentInteractionDrivers {
1434
+ register(driver: InteractionDriver): void;
1435
+ }
1436
+
1437
+ export declare interface KayAgentInteractionSurfaces {
1438
+ /**
1439
+ * Kay's built-in browser pane: the pages in the user's Bonsai tabs. The page-side credential
1440
+ * guard runs on every act, so a driver over this surface may declare
1441
+ * {@link INTERACTION_CREDENTIAL_GUARD}.
1442
+ */
1443
+ readonly browserPane: InteractionSurface;
1444
+ /**
1445
+ * The user's desktop through the platform's accessibility APIs: native apps as targets
1446
+ * (`app://<bundle id>`), their windows' controls as elements. On macOS Kay drives it with its
1447
+ * bundled accessibility worker under the app's Accessibility permission; on a platform with no
1448
+ * backend it reports itself unavailable.
1449
+ */
1450
+ readonly desktop: InteractionSurface;
1451
+ }
1452
+
977
1453
  /** One knowledge-index hit — a reference and within-list rank score, never a snippet. */
978
1454
  export declare interface KayAgentKnowledgeHit {
979
1455
  readonly uri: string;
@@ -1126,9 +1602,17 @@ export declare interface KayAgentPluginApi {
1126
1602
  * command it is about to run, and against the host's executable binding.
1127
1603
  */
1128
1604
  readonly process: KayAgentProcess;
1605
+ /**
1606
+ * Always present; the interaction surfaces Kay ships (its browser pane, and the desktop through
1607
+ * the platform accessibility APIs), each call checked against `interaction.surface {surface}`
1608
+ * and the session's permissions (see {@link InteractionSurface}).
1609
+ * Wrap one in an {@link InteractionDriver} and register it with
1610
+ * {@link KayAgentPluginApi.registerInteractionDriver} to make it drivable by the agent.
1611
+ */
1612
+ readonly interaction: KayAgentInteractionSurfaces;
1129
1613
  /**
1130
1614
  * Jev typed-decision inference, as an OPTIONAL accelerator with a REQUIRED fallback. Each call
1131
- * is checked against `jev.use` — but a refused grant or a missing saved key both
1615
+ * is checked against `jev.use` — but a refused grant or no usable Jev provider both
1132
1616
  * produce the same outcome: your `fallback` runs.
1133
1617
  *
1134
1618
  * Always present, on every host. That is the point: with no absent state to feature-detect,
@@ -1157,6 +1641,14 @@ export declare interface KayAgentPluginApi {
1157
1641
  * from `ctx.auth`. A provider without a binding reuses inference credentials or needs none.
1158
1642
  */
1159
1643
  registerSearchProvider(provider: SearchProvider): void;
1644
+ /**
1645
+ * Register an Interaction driver (a backend behind the `interaction_*` tools: something the agent
1646
+ * can read, click, type into, and open). The engine owns the tools, element ids, run loop,
1647
+ * permission checks, and screenshots; the driver owns only its I/O. Declare the driver's `id`
1648
+ * under `contributes.interactionDrivers` in kay-plugin.json first. A `browser` driver must set
1649
+ * `credentialGuard` (see {@link INTERACTION_CREDENTIAL_GUARD}).
1650
+ */
1651
+ registerInteractionDriver(driver: InteractionDriver): void;
1160
1652
  /**
1161
1653
  * Register a content converter (turns raw bytes of a mime type into agent-facing content behind the
1162
1654
  * read tool's finalize stage). Parallel to the kernel's `registerConverter`. Converters are
@@ -1466,6 +1958,14 @@ declare const KayPluginManifestV1: z.ZodObject<{
1466
1958
  displayName: z.ZodOptional<z.ZodString>;
1467
1959
  schemes: z.ZodOptional<z.ZodArray<z.ZodString>>;
1468
1960
  }, z.core.$strict>>>;
1961
+ interactionDrivers: z.ZodOptional<z.ZodArray<z.ZodObject<{
1962
+ localId: z.ZodString;
1963
+ displayName: z.ZodOptional<z.ZodString>;
1964
+ kind: z.ZodEnum<{
1965
+ browser: "browser";
1966
+ "computer-use": "computer-use";
1967
+ }>;
1968
+ }, z.core.$strict>>>;
1469
1969
  entityResolvers: z.ZodOptional<z.ZodArray<z.ZodObject<{
1470
1970
  localId: z.ZodString;
1471
1971
  displayName: z.ZodOptional<z.ZodString>;
@@ -1730,12 +2230,12 @@ declare const KayPluginManifestV1: z.ZodObject<{
1730
2230
  capabilities: z.ZodOptional<z.ZodObject<{
1731
2231
  endpoints: z.ZodOptional<z.ZodArray<z.ZodString>>;
1732
2232
  host: z.ZodOptional<z.ZodArray<z.ZodEnum<{
2233
+ "skills.read": "skills.read";
1733
2234
  "automations.run": "automations.run";
1734
2235
  "navigation.open-session": "navigation.open-session";
1735
2236
  "cost.read": "cost.read";
1736
2237
  "billing.read": "billing.read";
1737
2238
  "context.read": "context.read";
1738
- "skills.read": "skills.read";
1739
2239
  "memory.read": "memory.read";
1740
2240
  "usage.read": "usage.read";
1741
2241
  "self-improvement.read": "self-improvement.read";
@@ -2163,7 +2663,7 @@ declare type KayPluginManifestV1 = z.infer<typeof KayPluginManifestV1>;
2163
2663
 
2164
2664
  declare type KnownApi = "openai-completions" | "mistral-conversations" | "openai-responses" | "azure-openai-responses" | "openai-codex-responses" | "anthropic-messages" | "bedrock-converse-stream" | "google-generative-ai" | "google-vertex" | "pi-messages";
2165
2665
 
2166
- declare type KnownProvider = "amazon-bedrock" | "ant-ling" | "anthropic" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "radius" | "nvidia" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "zai-coding-cn" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "together" | "baseten" | "opencode" | "opencode-go" | "kimi-coding" | "meta" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "qwen-token-plan" | "qwen-token-plan-cn" | "qwen-token-plan-individual" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
2666
+ declare type KnownProvider = "amazon-bedrock" | "ant-ling" | "anthropic" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "radius" | "typesafe" | "nvidia" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "zai-coding-cn" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "together" | "baseten" | "opencode" | "opencode-go" | "kimi-coding" | "meta" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "qwen-token-plan" | "qwen-token-plan-cn" | "qwen-token-plan-individual" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
2167
2667
 
2168
2668
  declare interface LineRange {
2169
2669
  readonly start: number;
@@ -2221,29 +2721,26 @@ declare interface MistralConversationsCompat {
2221
2721
  supportsMidConvoSystemMessages?: boolean;
2222
2722
  }
2223
2723
 
2224
- declare interface Model<TApi extends Api> {
2225
- id: string;
2226
- name: string;
2227
- api: TApi;
2228
- provider: ProviderId;
2229
- baseUrl: string;
2724
+ /** Chat model: usable with `stream()` and friends. */
2725
+ declare interface Model<TApi extends Api> extends BaseModel<TApi> {
2726
+ /**
2727
+ * Optional: chat is the default model type, so models without `type` are chat
2728
+ * models. Narrow mixed model lists with `isModelType()` instead of comparing
2729
+ * `type` directly.
2730
+ */
2731
+ type?: "chat";
2230
2732
  reasoning: boolean;
2231
2733
  /**
2232
2734
  * Maps pi thinking levels to provider/model-specific values.
2233
2735
  * Missing keys use provider defaults. null marks a level as unsupported.
2234
2736
  */
2235
2737
  thinkingLevelMap?: ThinkingLevelMap;
2236
- input: ("text" | "image")[];
2237
- /** Provider input limits and cache-safe preprocessing metadata. */
2238
- inputLimits?: ModelInputLimits;
2239
- cost: ModelCost;
2240
2738
  /** Prompt cache lifetimes per retention tier. Unset when the provider's cache behavior is unknown. */
2241
2739
  promptCache?: ModelPromptCache;
2242
2740
  contextWindow: number;
2243
2741
  maxTokens: number;
2244
2742
  /** Default sampling parameters for this model. See {@link StreamOptions.samplingParams}; per-request keys override these. */
2245
2743
  samplingParams?: Record<string, unknown>;
2246
- headers?: Record<string, string>;
2247
2744
  /** Compatibility overrides for OpenAI-compatible APIs. If not set, auto-detected from baseUrl. */
2248
2745
  compat?: TApi extends "openai-completions" ? OpenAICompletionsCompat : TApi extends "openai-responses" | "azure-openai-responses" | "openai-codex-responses" ? OpenAIResponsesCompat : TApi extends "anthropic-messages" ? AnthropicMessagesCompat : TApi extends "bedrock-converse-stream" ? BedrockCompat : TApi extends "mistral-conversations" ? MistralConversationsCompat : never;
2249
2746
  }
@@ -2776,6 +3273,10 @@ declare const PluginCapabilityRefusalV1: z.ZodObject<{
2776
3273
  target: z.ZodLiteral<"kay.app">;
2777
3274
  slug: z.ZodLiteral<"signals.read">;
2778
3275
  envelope: z.ZodObject<{}, z.core.$strict>;
3276
+ }, z.core.$strict>, z.ZodObject<{
3277
+ target: z.ZodLiteral<"kay.app">;
3278
+ slug: z.ZodLiteral<"skills.read">;
3279
+ envelope: z.ZodObject<{}, z.core.$strict>;
2779
3280
  }, z.core.$strict>, z.ZodObject<{
2780
3281
  target: z.ZodLiteral<"kay.app">;
2781
3282
  slug: z.ZodLiteral<"workspace.command">;
@@ -2855,6 +3356,7 @@ declare const PluginCapabilityRefusalV1: z.ZodObject<{
2855
3356
  default: "default";
2856
3357
  allow: "allow";
2857
3358
  ask: "ask";
3359
+ auto: "auto";
2858
3360
  }>>;
2859
3361
  }, z.core.$strict>>;
2860
3362
  fallback: z.ZodArray<z.ZodObject<{
@@ -2871,6 +3373,7 @@ declare const PluginCapabilityRefusalV1: z.ZodObject<{
2871
3373
  default: "default";
2872
3374
  allow: "allow";
2873
3375
  ask: "ask";
3376
+ auto: "auto";
2874
3377
  }>>;
2875
3378
  }, z.core.$strict>>;
2876
3379
  }, z.core.$strict>;
@@ -2878,6 +3381,15 @@ declare const PluginCapabilityRefusalV1: z.ZodObject<{
2878
3381
  target: z.ZodLiteral<"kay.agent">;
2879
3382
  slug: z.ZodLiteral<"tool-interception.register">;
2880
3383
  envelope: z.ZodObject<{}, z.core.$strict>;
3384
+ }, z.core.$strict>, z.ZodObject<{
3385
+ target: z.ZodLiteral<"kay.agent">;
3386
+ slug: z.ZodLiteral<"interaction.surface">;
3387
+ envelope: z.ZodObject<{
3388
+ surface: z.ZodEnum<{
3389
+ "browser-pane": "browser-pane";
3390
+ desktop: "desktop";
3391
+ }>;
3392
+ }, z.core.$strict>;
2881
3393
  }, z.core.$strict>, z.ZodObject<{
2882
3394
  target: z.ZodLiteral<"plugin">;
2883
3395
  slug: z.ZodLiteral<"config.declare-section">;
@@ -2968,8 +3480,15 @@ export declare interface PluginDelegatedScheme {
2968
3480
  /** Run the connect flow and mint the material to store. Throw to fail the connect. */
2969
3481
  readonly connect: (ctx: PluginDelegatedConnectContext) => Promise<PluginDelegatedConnectResult>;
2970
3482
  /**
2971
- * Mint fresh material from the current (expiring) material. Absent means non-refreshable:
2972
- * expired material resolves as-is (like an OAuth scheme without a refresh token).
3483
+ * Mint fresh material from the current (expiring) material, including the `data` the last
3484
+ * connect or refresh returned. Kay calls this only inside its credential authority, which holds
3485
+ * the refresh lease and saves the result; this hook performs the exchange and nothing else.
3486
+ * Returned `data` replaces the stored `data`; omitted `data` keeps it. Returned `expiresAt`
3487
+ * replaces the stored expiry; omitted `expiresAt` means the new material does not expire.
3488
+ * Throw {@link DelegatedRefreshRejectedError} when the provider refused the grant for good (the
3489
+ * user must reconnect); any other throw is retried with backoff and keeps the account connected.
3490
+ * Absent means non-refreshable: expired material resolves as-is (like an OAuth scheme without a
3491
+ * refresh token).
2973
3492
  */
2974
3493
  readonly refresh?: (material: PluginDelegatedSecretMaterial) => Promise<PluginDelegatedSecretMaterial>;
2975
3494
  /**
@@ -3122,6 +3641,19 @@ export declare type PluginToolDefinition<TParams extends ToolParametersWire = To
3122
3641
  readonly execute: (toolCallId: string, params: ToolExecutionAwareParams<InferToolInput<TParams>>, signal: AbortSignal | undefined, onUpdate: AgentToolUpdateCallback<TDetails> | undefined, ctx: ToolContext) => Promise<AgentToolResult<TDetails>>;
3123
3642
  };
3124
3643
 
3644
+ /**
3645
+ * What a run did to a URI. The words match the automation run wire's artifact actions. When one
3646
+ * run both creates and updates a URI, the reader reports `created`.
3647
+ */
3648
+ export declare type ProducedResourceAction = "created" | "updated";
3649
+
3650
+ /** One URI a tool call created or updated as a side effect. */
3651
+ export declare interface ProducedResourceDeclaration {
3652
+ /** A `scheme://…` URI or an absolute local file path, compared as an exact string. */
3653
+ readonly uri: string;
3654
+ readonly action: ProducedResourceAction;
3655
+ }
3656
+
3125
3657
  declare type ProviderId = KnownProvider | string;
3126
3658
 
3127
3659
  /**
@@ -3135,8 +3667,6 @@ declare interface ProxiedToolCall {
3135
3667
  readonly input: Record<string, unknown>;
3136
3668
  }
3137
3669
 
3138
- export { Questions }
3139
-
3140
3670
  export declare interface RawResource {
3141
3671
  readonly uri: string;
3142
3672
  readonly content: string | Uint8Array;
@@ -3525,10 +4055,6 @@ declare interface SessionContext {
3525
4055
  * how most third-party APIs use `""` to mean "no value" rather than "the empty string". */
3526
4056
  export declare function str(record: Record<string, unknown> | undefined, key: string): string | undefined;
3527
4057
 
3528
- export { SystemOneRequest }
3529
-
3530
- export { SystemOneResult }
3531
-
3532
4058
  declare interface TextContent {
3533
4059
  type: "text";
3534
4060
  text: string;
@@ -3645,6 +4171,19 @@ declare interface ToolCallModel {
3645
4171
  */
3646
4172
  declare type ToolCallOrigin = "model" | "host";
3647
4173
 
4174
+ /** A call to judge with {@link ToolContext.checkToolCallPermission}. */
4175
+ declare interface ToolCallPermissionCheck {
4176
+ readonly toolName: string;
4177
+ readonly input: Record<string, unknown>;
4178
+ }
4179
+
4180
+ declare type ToolCallPermissionVerdict = {
4181
+ readonly allowed: true;
4182
+ } | {
4183
+ readonly allowed: false;
4184
+ readonly reason: string;
4185
+ };
4186
+
3648
4187
  /**
3649
4188
  * What a tool call ADDRESSES, resolved by the session before execution from facts it already
3650
4189
  * holds for auth scoping: a URI verb's matched module (and the extension that registered it), or
@@ -3687,6 +4226,13 @@ export declare interface ToolContext {
3687
4226
  * behind itself. Present only with a live session. One request may be pending at a time.
3688
4227
  */
3689
4228
  readonly requestMidTurnCompaction?: (customInstructions?: string, trigger?: "command" | "suggestion") => MidTurnCompactionRequest;
4229
+ /**
4230
+ * Put a call this tool is about to cause through the session's permission gate, as if the agent
4231
+ * had made it directly: classification, rules, mode, the auto approver, and the approval card.
4232
+ * The call is only judged, never executed. For a tool whose effect is only knowable at run time
4233
+ * (a click in a web page that turns out to send an email). Present only with a live session.
4234
+ */
4235
+ readonly checkToolCallPermission?: (call: ToolCallPermissionCheck) => Promise<ToolCallPermissionVerdict>;
3690
4236
  /**
3691
4237
  * Re-root the session into `newCwd` mid-run, recomposing the cwd-scoped substrate (builtin tools,
3692
4238
  * the capability registry, the system-prompt project line) in place so subsequent tool calls operate
@@ -3973,7 +4519,11 @@ declare interface ToolPermissionHint {
3973
4519
  /** Controls whether a tool is expected to complete inline or via background adoption. */
3974
4520
  export declare type ToolRunPolicy = "inline" | "background";
3975
4521
 
3976
- export { TypeSafeClient }
4522
+ /** A surface that answers every call `unavailable` with `message`: the uncomposed default. */
4523
+ export declare function unavailableInteractionSurface(message: string): InteractionSurface;
4524
+
4525
+ /** Both surfaces unavailable: a host that composed no Interaction surfaces, a probe, a double. */
4526
+ export declare function unavailableInteractionSurfaces(message: string): KayAgentInteractionSurfaces;
3977
4527
 
3978
4528
  /**
3979
4529
  * One sentence naming the two dialects, for refusal messages. Callers prefix
@@ -4315,6 +4865,21 @@ export declare interface UriModule {
4315
4865
  */
4316
4866
  readonly title?: string;
4317
4867
  readonly fallback?: boolean;
4868
+ /**
4869
+ * Whether this module parses the read tool's trailing line selector out of its own addresses.
4870
+ * Absent or false: the host owns the explicit forms (`:50-200`, `:50-`, `:50+10`, `:raw`). The
4871
+ * read tool strips one before dispatch, hands `read` the bare address, and applies the window
4872
+ * to what comes back, so a module never has to know the grammar for the read tool's own
4873
+ * `Continue with '<address>:N-M'` banner to work on its addresses (#10754). A bare trailing
4874
+ * `:<digits>` is never taken from such a module: it is too common inside real ids (a Figma
4875
+ * node `1:2`), so it reaches the module as written.
4876
+ *
4877
+ * Declare `true` only when the module must see the raw address: its grammar can end in an
4878
+ * explicit-range shape, it wants the bare `:50` form too, or it windows the content itself
4879
+ * (streaming a large file, skipping a cap it applies to an unwindowed read). Such a module
4880
+ * calls `parseLineSelector` itself and reports what it did through `RawResource.selector`.
4881
+ */
4882
+ readonly ownsLineSelectors?: boolean;
4318
4883
  readonly claims?: readonly UriClaim[];
4319
4884
  /** Migration-only prompt summary until structured help/catalog coverage replaces prose. */
4320
4885
  readonly description?: string;
@@ -4331,7 +4896,9 @@ export declare interface UriModule {
4331
4896
  * The host owns framing, the whole-quote fit (no elision) and display-safety admission.
4332
4897
  *
4333
4898
  * Unlike preflight, this hook is async and may do I/O. Resolve names through `ctx`,
4334
- * the same dispatch context used by execution, never an ambient or cached account.
4899
+ * the same dispatch context used by execution, never an ambient or cached account. A name
4900
+ * the module resolved under that account may be cached for a bounded time, keyed by that
4901
+ * account's identity and never answered to another account or after a failed lookup.
4335
4902
  * The host calls it once before raising the ask, enforces the short `ctx.signal`
4336
4903
  * deadline and discards late answers. A throw yields no summary and a module-attributed
4337
4904
  * diagnostic; declining costs a click into the app, never an under-described approval.
@@ -4341,6 +4908,26 @@ export declare interface UriModule {
4341
4908
  readonly uri: string;
4342
4909
  readonly payload: unknown;
4343
4910
  }, ctx: UriResolveContext): Promise<UriOperationDescription | undefined>;
4911
+ /**
4912
+ * A short, render-only name for the resource a settled call on `request.uri` touched, which the
4913
+ * host stamps on the tool result's `details` so a transcript row can name it where it would
4914
+ * otherwise print the address (`#lane-analytics` and `thread`, not a channel id). Answer
4915
+ * `undefined` for any address you cannot honestly name.
4916
+ *
4917
+ * Called once per successful URI verb call, AFTER the verb handler has returned, with the same
4918
+ * dispatch context. Resolve names through `ctx` and nothing else, and prefer a cache your own
4919
+ * verb handlers warm, keyed by the executing account: a name one account saw is never answered
4920
+ * to another, and a failed, blank or aborted lookup is never cached. The host bounds the wait
4921
+ * (a finished result is held at most a quarter of a second), gives `ctx.signal` a hard deadline,
4922
+ * and drops a late, thrown or refused answer without failing the call; a throw is reported as a
4923
+ * module-attributed diagnostic. The label is a label, never an identity: the address remains the
4924
+ * click target, hover text and accessible name. It is UI-only, so it never enters the tool
4925
+ * result's content and no telemetry reads it.
4926
+ *
4927
+ * Unlike `describeOperation` this is not an approval surface: it carries no consequence, no
4928
+ * quote and no coverage claim, and nothing may gate a permission on it.
4929
+ */
4930
+ labelResource?(request: UriResourceLabelRequest, ctx: UriResolveContext): Promise<UriResourceLabel | undefined>;
4344
4931
  /**
4345
4932
  * Per-resource observability: does a `format: "observation"` read of THIS
4346
4933
  * uri render source-native material ({@link UriResolveContext.format})?
@@ -4780,6 +5367,24 @@ export declare interface UriResourceDescription {
4780
5367
  readonly sourceUrl?: string;
4781
5368
  }
4782
5369
 
5370
+ /**
5371
+ * What a settled call touched, as a person would name it.
5372
+ *
5373
+ * `name` is the resource itself (`#lane-analytics`). `section` is the part of it the address
5374
+ * reaches into (`thread`), and is absent when the address is the resource.
5375
+ */
5376
+ export declare interface UriResourceLabel {
5377
+ readonly name: string;
5378
+ readonly section?: string;
5379
+ }
5380
+
5381
+ /** The call a module is asked to label. */
5382
+ export declare interface UriResourceLabelRequest {
5383
+ readonly operation: UriOperation;
5384
+ /** The dispatch address: selector-stripped, the exact form the module's verb handler received. */
5385
+ readonly uri: string;
5386
+ }
5387
+
4783
5388
  declare interface UriSchemeClaim {
4784
5389
  readonly kind: "scheme";
4785
5390
  readonly scheme: string;
@@ -5054,9 +5659,7 @@ declare interface UrlPatternClaim {
5054
5659
  readonly examples?: readonly string[];
5055
5660
  }
5056
5661
 
5057
- export { Usage }
5058
-
5059
- declare interface Usage_2 {
5662
+ declare interface Usage {
5060
5663
  input: number;
5061
5664
  output: number;
5062
5665
  cacheRead: number;
@@ -5236,8 +5839,8 @@ export declare type WhiteboardValue = z.infer<typeof WhiteboardValue>;
5236
5839
  /**
5237
5840
  * Run `use` against a live Jev client, falling back to `fallback` whenever Jev cannot serve the
5238
5841
  * call. The wrapper exists so a feature can ASK for a typed decision without ever depending on
5239
- * one: `fallback` is required, and it runs whenever no host-managed key is saved,
5240
- * the user has not granted `jev.use`, the branch exceeds its budget, `use` throws, or
5842
+ * one: `fallback` is required, and it runs whenever no provider in the user's Jev provider
5843
+ * order holds a usable credential, the user has not granted `jev.use`, the branch exceeds its budget, `use` throws, or
5241
5844
  * `use` declines by returning `undefined`. With valid options, this rejects on an explicit
5242
5845
  * `signal` abort, reaching `deadlineAt`, or `fallback` itself throwing.
5243
5846
  *
@@ -5245,10 +5848,9 @@ export declare type WhiteboardValue = z.infer<typeof WhiteboardValue>;
5245
5848
  * {@link createFallbackOnlyWithJev}, so a caller never branches on availability — branching is
5246
5849
  * exactly how a fallback gets skipped.
5247
5850
  *
5248
- * `jev` is the vendor's own `TypeSafeClient`, configured with the host's default model and base
5249
- * URL. Native `request.model` overrides remain supported. It
5250
- * is valid only for the duration of the callback: a reference retained past `use`'s scope is
5251
- * refused at the transport, and an in-flight request is aborted when the call stops waiting.
5851
+ * `jev` is a {@link JevClient} on the host's Jev model. It is valid only for the duration of
5852
+ * the callback: a reference retained past `use`'s scope is refused at the transport, and an
5853
+ * in-flight request is aborted when the call stops waiting.
5252
5854
  * The callback itself is ABANDONED, not interrupted — a host cannot stop arbitrary JavaScript
5253
5855
  * that is already running, so `use` must not perform side effects it would mind completing
5254
5856
  * unobserved. The same applies to a running fallback: abort/deadline stops waiting for it but
@@ -5257,7 +5859,7 @@ export declare type WhiteboardValue = z.infer<typeof WhiteboardValue>;
5257
5859
  export declare type WithJev = <T>(
5258
5860
  /** Return `undefined` to decline (the fallback runs). A feature whose real result can itself be
5259
5861
  * `undefined` should return `null` or its own wrapper type instead. */
5260
- use: (jev: TypeSafeClient) => T | undefined | PromiseLike<T | undefined>,
5862
+ use: (jev: JevClient) => T | undefined | PromiseLike<T | undefined>,
5261
5863
  /** Required. The behaviour the feature has without Jev. */
5262
5864
  fallback: () => T | PromiseLike<T>, options?: WithJevOptions) => Promise<T>;
5263
5865