@loomcycle/client 1.147.0 → 1.148.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 CHANGED
@@ -600,6 +600,7 @@ The tenant is your own. `opts.tenant` names another for an admin token, and for
600
600
  | `listGateIdentities(gate, subject, opts?)` | `GET /v1/_authgate/{gate}/identities?subject=` | `GateIdentitiesResponse` — logins, `has_password`, `has_totp` |
601
601
  | `getGateTenantStatus(gate, opts?)` | `GET /v1/_authgate/{gate}/tenant-status` | `GateTenantStatus` — whether the tenant has, or ever had, a user, and whether an owner invite is live |
602
602
  | `deviceLogin({onPrompt, clientId?, signal?})` | `POST /v1/_auth/device`, then `POST /v1/_auth/device/token` | `DeviceLoginResult` — signs a person in through the server's device gate (RFC 8628): `onPrompt` gets the code to show, the person approves it at `/ui/device`, and the token is theirs, never outliving the session they approved from. Sends no bearer. `DeviceLoginError` (`code` `access_denied` / `expired_token`) otherwise |
603
+ | `clientToolsTicket(opts?)` | `POST /v1/client-tools/ticket` | `{ticket, expiresAt}` — a one-time ticket that opens one client-tool socket within 30 s, presented as `ticket.<t>` in `Sec-WebSocket-Protocol`. `connectClientTools` mints one before every connect and reconnect; it falls back to the `bearer.<token>` entry only on a server without tickets (404/405, or 503 `ticket_unavailable`) that does not run strict sign-in. 503 `ticket_unavailable` without `LOOMCYCLE_SECRET_KEY` |
603
604
 
604
605
  None of these takes a password: the person sets their own through the invite or reset link. Hand the link's `url` to the person and do not log it — its fragment is the one-time code.
605
606
 
@@ -702,7 +703,7 @@ const tokens = await oauth.completeAuthorize({
702
703
 
703
704
  A Tauri app may register a private-use scheme instead (`loomboard://auth/callback`) and pass the deep link it receives to `parseAuthorizeResponse`. Token calls made from its webview send the origin `tauri://localhost`, which the client must list in `allowed_origins`; calls from the Rust or Node side send none.
704
705
 
705
- **The token provider.** `new LoomcycleClient({ tokenProvider })` (instead of `authToken`; passing both throws) asks the provider for the bearer on every request, `connectClientTools` included. `OAuthTokenProvider` refreshes 60 s before the access token expires (`refreshSkewMs`), and once after a 401: the request is retried a single time with the new token, never more. Concurrent requests share one refresh. Any other source of short-lived tokens can implement `TokenProvider` (`getToken`, optional `onUnauthorized`).
706
+ **The token provider.** `new LoomcycleClient({ tokenProvider })` (instead of `authToken`; passing both throws) asks the provider for the bearer on every request, `connectClientTools`'s ticket mint included. `OAuthTokenProvider` refreshes 60 s before the access token expires (`refreshSkewMs`), and once after a 401: the request is retried a single time with the new token, never more. Concurrent requests share one refresh. Any other source of short-lived tokens can implement `TokenProvider` (`getToken`, optional `onUnauthorized`).
706
707
 
707
708
  Things to know:
708
709
 
@@ -8,9 +8,11 @@
8
8
  //
9
9
  // Transport note: the adapter is otherwise fetch/SSE-only and takes no WebSocket
10
10
  // dependency. connectClientTools uses the global `WebSocket` (browsers, Node
11
- // 22+); on older Node pass `WebSocketImpl` (e.g. the `ws` package). The bearer
12
- // rides the `Sec-WebSocket-Protocol` subprotocol (browsers can't set an
13
- // Authorization header on a WebSocket).
11
+ // 22+); on older Node pass `WebSocketImpl` (e.g. the `ws` package). Browsers
12
+ // can't set an Authorization header on a WebSocket, so the credential rides the
13
+ // `Sec-WebSocket-Protocol` header: a one-time ticket (`ticket.<t>`, minted over
14
+ // an ordinary authenticated call) where the server offers one, else the
15
+ // bearer itself (`bearer.<token>`, older servers, never in strict sign-in).
14
16
  Object.defineProperty(exports, "__esModule", { value: true });
15
17
  exports.ClientToolHost = exports.CLIENT_TOOL_SUBPROTOCOL = void 0;
16
18
  exports.clientToolsURL = clientToolsURL;
@@ -29,9 +31,11 @@ class ClientToolHost {
29
31
  opts;
30
32
  ws;
31
33
  closed = false;
32
- /** `auth` is the bearer, or a function that supplies one on each
33
- * (re)connect — a client built with a token provider passes one, so a
34
- * reconnect after the access token expired carries the refreshed one. */
34
+ /** `auth` is the bearer, or a function that supplies the credential on
35
+ * each (re)connect — a bearer, or a fresh one-time ticket. A ticket is
36
+ * spent by the handshake, so connectClientTools passes a function that
37
+ * mints one per connect; a reconnect after an access token expired then
38
+ * carries the refreshed one too. */
35
39
  constructor(url, auth, opts) {
36
40
  this.url = url;
37
41
  this.auth = auth;
@@ -54,7 +58,7 @@ class ClientToolHost {
54
58
  throw new Error("connectClientTools: no WebSocket implementation available — pass WebSocketImpl (e.g. the `ws` package) on Node < 22");
55
59
  }
56
60
  if (typeof this.auth === "function") {
57
- this.auth().then((token) => this.open(WS, token), (err) => {
61
+ this.auth().then((cred) => this.open(WS, cred), (err) => {
58
62
  this.opts.onError?.(err);
59
63
  // A sign-in that ended does not come back by retrying: stop
60
64
  // rather than ask again every few seconds.
@@ -69,12 +73,20 @@ class ClientToolHost {
69
73
  }
70
74
  this.open(WS, this.auth);
71
75
  }
72
- open(WS, token) {
76
+ open(WS, cred) {
73
77
  if (this.closed)
74
78
  return;
75
79
  const protocols = [exports.CLIENT_TOOL_SUBPROTOCOL];
76
- if (token)
77
- protocols.push("bearer." + token);
80
+ if (typeof cred === "string") {
81
+ if (cred)
82
+ protocols.push("bearer." + cred);
83
+ }
84
+ else if (cred && "ticket" in cred) {
85
+ protocols.push("ticket." + cred.ticket);
86
+ }
87
+ else if (cred?.bearer) {
88
+ protocols.push("bearer." + cred.bearer);
89
+ }
78
90
  this.opts.onStatus?.("connecting");
79
91
  const ws = new WS(this.url, protocols);
80
92
  this.ws = ws;
@@ -26,6 +26,7 @@
26
26
  */
27
27
  Object.defineProperty(exports, "__esModule", { value: true });
28
28
  exports.LoomcycleClient = void 0;
29
+ const errors_js_1 = require("./errors.js");
29
30
  const fetch_helpers_js_1 = require("./fetch-helpers.js");
30
31
  const stream_js_1 = require("./stream.js");
31
32
  const interactive_js_1 = require("./interactive.js");
@@ -1684,14 +1685,50 @@ class LoomcycleClient {
1684
1685
  * `.close()` to stop. Uses the global WebSocket (browsers, Node 22+); pass
1685
1686
  * `WebSocketImpl` (e.g. the `ws` package) on older Node. */
1686
1687
  connectClientTools(opts) {
1687
- // A provider is asked on every (re)connect, so a host outliving one
1688
- // access token reconnects with the next.
1689
- const provider = this.tokenProvider;
1690
- const auth = provider ? () => provider.getToken() : this.ctx.authToken;
1688
+ // With a credential, every (re)connect mints a fresh one-time ticket (a
1689
+ // ticket is spent by the handshake); a host outliving one access token
1690
+ // mints the next through the provider. Without one (an open-mode
1691
+ // server) the socket is opened bare, as before.
1692
+ const auth = this.tokenProvider || this.ctx.authToken ? () => this.clientToolsCredential() : undefined;
1691
1693
  const host = new client_tools_js_1.ClientToolHost((0, client_tools_js_1.clientToolsURL)(this.ctx.baseUrl), auth, opts);
1692
1694
  host.start();
1693
1695
  return host;
1694
1696
  }
1697
+ /** Mint a one-time ticket for the client-tool socket (RFC GJ): POST
1698
+ * /v1/client-tools/ticket with this client's credential. The ticket opens
1699
+ * one socket, within 30 s of the mint, as `ticket.<t>` in
1700
+ * Sec-WebSocket-Protocol — the way a browser opens the socket under
1701
+ * strict sign-in, where the bearer is not read from that header.
1702
+ * connectClientTools calls it for you on every connect. */
1703
+ async clientToolsTicket(opts) {
1704
+ const out = await (0, fetch_helpers_js_1.postJSON)(this.ctx, "/v1/client-tools/ticket", undefined, opts);
1705
+ return { ticket: out.ticket, expiresAt: out.expires_at };
1706
+ }
1707
+ /** The credential a client-tool connect presents: a fresh ticket, or —
1708
+ * only when the server has no ticket route (an older runtime: 404/405)
1709
+ * or issues no tickets (503 ticket_unavailable) and does not run strict
1710
+ * sign-in — the bearer itself, as before. Under strict sign-in the
1711
+ * bearer is never put in the handshake header: the server would not
1712
+ * read it, and proxies and access logs do not treat that header as a
1713
+ * credential. */
1714
+ async clientToolsCredential() {
1715
+ try {
1716
+ return { ticket: (await this.clientToolsTicket()).ticket };
1717
+ }
1718
+ catch (err) {
1719
+ const noTicket = err instanceof errors_js_1.LoomcycleError &&
1720
+ (err.status === 404 || err.status === 405 || (err.status === 503 && err.code === "ticket_unavailable"));
1721
+ if (!noTicket)
1722
+ throw err;
1723
+ const me = await this.whoami();
1724
+ if (me.auth?.mode === "strict") {
1725
+ throw new errors_js_1.LoomcycleError("connectClientTools: this loomcycle runs strict sign-in and issues no client-tool ticket " +
1726
+ "(it needs a release with POST /v1/client-tools/ticket and LOOMCYCLE_SECRET_KEY set)", { code: "ticket_unavailable" });
1727
+ }
1728
+ const token = this.tokenProvider ? await this.tokenProvider.getToken() : this.ctx.authToken;
1729
+ return token ? { bearer: token } : undefined;
1730
+ }
1731
+ }
1695
1732
  /** Restore from a same-instance snapshot id OR an inline
1696
1733
  * envelope JSON. Idempotent: ON CONFLICT DO NOTHING per row;
1697
1734
  * the returned counters reflect rows actually written.
@@ -2914,6 +2951,31 @@ class LoomcycleClient {
2914
2951
  async moveDocuments(input, opts) {
2915
2952
  return (await this.document({ op: "move_documents", ...input }, opts));
2916
2953
  }
2954
+ /** The annotations of one chunk, document (`document_id`) or folder
2955
+ * (`level: "path"` with `path`), each marked `stale` or current (the Document
2956
+ * tool's `get_annotation`). Tenant scope; `scope` defaults to `"tenant"`. A
2957
+ * folder's annotation is left out unless the caller may read every document
2958
+ * it covers. `opts` as on {@link LoomcycleClient.document}. */
2959
+ async getAnnotation(input, opts) {
2960
+ return (await this.document({ op: "get_annotation", scope: "tenant", ...input }, opts));
2961
+ }
2962
+ /** Page through the tenant's annotations with filters (the Document tool's
2963
+ * `list_annotations`). Pass the answer's `next_cursor` as `after` for the
2964
+ * next page. `opts` as on {@link LoomcycleClient.document}. */
2965
+ async listAnnotations(input = {}, opts) {
2966
+ return (await this.document({ op: "list_annotations", scope: "tenant", ...input }, opts));
2967
+ }
2968
+ /** Write an annotation (the Document tool's `set_annotation`). Without
2969
+ * `inputs_sha256` it is sent as an operator's manual annotation
2970
+ * (`manual: true`), which the annotation pass never overwrites; the operator
2971
+ * plane alone may write one. `opts` as on {@link LoomcycleClient.document}. */
2972
+ async annotate(input, opts) {
2973
+ const body = { op: "set_annotation", scope: "tenant", ...input };
2974
+ if (input.inputs_sha256 === undefined && input.manual === undefined) {
2975
+ body.manual = true;
2976
+ }
2977
+ return (await this.document(body, opts));
2978
+ }
2917
2979
  /** Find the copies in a set of documents (the Document tool's
2918
2980
  * `find_duplicates`, RFC GB): the same text by sha256, or the same title once
2919
2981
  * copy markers are stripped, each copy pointed at its original. A report
package/dist/cjs/index.js CHANGED
@@ -165,6 +165,7 @@
165
165
  * document(input): Promise<DocumentToolResponse> // 13 ops; needs SQL Memory
166
166
  * copyDocuments(input) / moveDocuments(input): Promise<DocumentTransferResult> // RFC FT, dry run by default
167
167
  * findDuplicates(input): Promise<DocumentFindDuplicatesResult> // RFC GB, a report unless propose: true
168
+ * getAnnotation / listAnnotations / annotate // a brief + abstract per section, document, folder
168
169
  *
169
170
  * // History — browse/search/annotate past chats (RFC BE; tenant-confined)
170
171
  * history(input): Promise<HistoryToolResponse> // list/get/search/rename/annotate/pin/archive/recap/resume
@@ -27,6 +27,13 @@ export interface WebSocketLike {
27
27
  }) => void) | null;
28
28
  }
29
29
  export type WebSocketCtor = new (url: string, protocols?: string | string[]) => WebSocketLike;
30
+ /** What a client-tool socket presents on its handshake: a one-time ticket
31
+ * (preferred; see LoomcycleClient.clientToolsTicket) or the bearer itself. */
32
+ export type ClientToolsCredential = {
33
+ ticket: string;
34
+ } | {
35
+ bearer: string;
36
+ };
30
37
  export interface ConnectClientToolsOptions {
31
38
  /** The tools this client provides. */
32
39
  tools: ClientToolSchema[];
@@ -59,10 +66,12 @@ export declare class ClientToolHost {
59
66
  private readonly opts;
60
67
  private ws?;
61
68
  private closed;
62
- /** `auth` is the bearer, or a function that supplies one on each
63
- * (re)connect — a client built with a token provider passes one, so a
64
- * reconnect after the access token expired carries the refreshed one. */
65
- constructor(url: string, auth: string | undefined | (() => Promise<string | undefined>), opts: ConnectClientToolsOptions);
69
+ /** `auth` is the bearer, or a function that supplies the credential on
70
+ * each (re)connect — a bearer, or a fresh one-time ticket. A ticket is
71
+ * spent by the handshake, so connectClientTools passes a function that
72
+ * mints one per connect; a reconnect after an access token expired then
73
+ * carries the refreshed one too. */
74
+ constructor(url: string, auth: string | undefined | (() => Promise<string | ClientToolsCredential | undefined>), opts: ConnectClientToolsOptions);
66
75
  /** Open the connection (called for you by connectClientTools). */
67
76
  start(): void;
68
77
  /** Stop the host + close the socket; suppresses reconnect. */
@@ -7,9 +7,11 @@
7
7
  //
8
8
  // Transport note: the adapter is otherwise fetch/SSE-only and takes no WebSocket
9
9
  // dependency. connectClientTools uses the global `WebSocket` (browsers, Node
10
- // 22+); on older Node pass `WebSocketImpl` (e.g. the `ws` package). The bearer
11
- // rides the `Sec-WebSocket-Protocol` subprotocol (browsers can't set an
12
- // Authorization header on a WebSocket).
10
+ // 22+); on older Node pass `WebSocketImpl` (e.g. the `ws` package). Browsers
11
+ // can't set an Authorization header on a WebSocket, so the credential rides the
12
+ // `Sec-WebSocket-Protocol` header: a one-time ticket (`ticket.<t>`, minted over
13
+ // an ordinary authenticated call) where the server offers one, else the
14
+ // bearer itself (`bearer.<token>`, older servers, never in strict sign-in).
13
15
  import { OAuthError } from "./errors.js";
14
16
  /** The app-level subprotocol the server negotiates for /v1/client-tools. */
15
17
  export const CLIENT_TOOL_SUBPROTOCOL = "loomcycle.client-tools.v1";
@@ -25,9 +27,11 @@ export class ClientToolHost {
25
27
  opts;
26
28
  ws;
27
29
  closed = false;
28
- /** `auth` is the bearer, or a function that supplies one on each
29
- * (re)connect — a client built with a token provider passes one, so a
30
- * reconnect after the access token expired carries the refreshed one. */
30
+ /** `auth` is the bearer, or a function that supplies the credential on
31
+ * each (re)connect — a bearer, or a fresh one-time ticket. A ticket is
32
+ * spent by the handshake, so connectClientTools passes a function that
33
+ * mints one per connect; a reconnect after an access token expired then
34
+ * carries the refreshed one too. */
31
35
  constructor(url, auth, opts) {
32
36
  this.url = url;
33
37
  this.auth = auth;
@@ -50,7 +54,7 @@ export class ClientToolHost {
50
54
  throw new Error("connectClientTools: no WebSocket implementation available — pass WebSocketImpl (e.g. the `ws` package) on Node < 22");
51
55
  }
52
56
  if (typeof this.auth === "function") {
53
- this.auth().then((token) => this.open(WS, token), (err) => {
57
+ this.auth().then((cred) => this.open(WS, cred), (err) => {
54
58
  this.opts.onError?.(err);
55
59
  // A sign-in that ended does not come back by retrying: stop
56
60
  // rather than ask again every few seconds.
@@ -65,12 +69,20 @@ export class ClientToolHost {
65
69
  }
66
70
  this.open(WS, this.auth);
67
71
  }
68
- open(WS, token) {
72
+ open(WS, cred) {
69
73
  if (this.closed)
70
74
  return;
71
75
  const protocols = [CLIENT_TOOL_SUBPROTOCOL];
72
- if (token)
73
- protocols.push("bearer." + token);
76
+ if (typeof cred === "string") {
77
+ if (cred)
78
+ protocols.push("bearer." + cred);
79
+ }
80
+ else if (cred && "ticket" in cred) {
81
+ protocols.push("ticket." + cred.ticket);
82
+ }
83
+ else if (cred?.bearer) {
84
+ protocols.push("bearer." + cred.bearer);
85
+ }
74
86
  this.opts.onStatus?.("connecting");
75
87
  const ws = new WS(this.url, protocols);
76
88
  this.ws = ws;
package/dist/client.d.ts CHANGED
@@ -26,7 +26,7 @@
26
26
  import { InteractiveSession } from "./interactive.js";
27
27
  import { LoomcycleOAuth } from "./oauth.js";
28
28
  import { ClientToolHost, type ConnectClientToolsOptions } from "./client-tools.js";
29
- import type { ChangeFeedFrame, StreamChangesOptions, DocumentFeedFrame, DocumentFeedOptions, CredentialListResponse, CredentialMeta, OAuthConnectStart, OAuthCredentialConfig, CryptoKeyEncoding, CryptoKeyExport, CryptoKeyExternal, CryptoKeyType, CryptoRequest, CryptoResultByOp, DecideRequest, DecideResponse, DecisionModelsResponse, SpeechOptions, SpeechResult, TranscribeOptions, TranscribeResult, SpeechInfo, CredentialScope, DirectoryInspection, DirectoryTenant, DirectoryUser, ErasureReport, ErasureResult, MergeSubjectsResult, ReviewQueueFilter, ReviewQueueResult, RuleStatementsResult, RevertRulingResult, ListRulingsResult, ApplyReviewPolicyResult, BindSubjectPrincipalResult, Agent, AgentEvent, AgentList, CancelAgentResult, ClientOptions, ContinueOptions, RunOverrideOptions, EffectiveConfigResponse, RunFileInput, RunInboxDownload, AgentOverridableResponse, RetuneRunResponse, RunConfigResponse, RunPromptResponse, CreateSnapshotOptions, EnsureCodeAgentOptions, EnsureCodeAgentResult, EnsureHookDefOptions, EnsureHookDefResult, HookDefInput, HookDefOverlay, HookDefRowResponse, CreateDefOptions, ForkDefOptions, HookDefForkOverlay, ScheduleDefInput, ScheduleDefOverlay, ScheduleDefRowResponse, WebhookDefInput, WebhookDefOverlay, WebhookDefRowResponse, EnsureMcpServerOptions, EnsureMcpServerResult, HealthResponse, InterruptListResponse, InterruptStatus, ListUserAgentsOptions, WalkRunsPage, AckChannelOptions, AwaitChannelsOptions, BroadcastChannelsOptions, ChannelAckResult, ChannelAwaitResult, ChannelBroadcastResult, ChannelDescriptor, ChannelPeekResult, ListTeamChannelsOptions, PeekTeamChannelOptions, ReleaseTeamChannelOptions, TeamChannelPeekResult, TeamChannelReleaseResult, TeamChannelsResult, ChannelPublishResult, ChannelPurgeResult, ChannelReleaseResult, ChannelSubscribeResult, CreateChannelOptions, ListChannelsResponse, PeekChannelOptions, PublishChannelOptions, ReleaseChannelOptions, SetMemoryEntryOptions, SetMemoryEntryResponse, SubscribeChannelOptions, UpdateChannelOptions, LibraryAgentDefinition, LibraryListResponse, LibraryMcpServerDefinition, LibrarySkillDefinition, ListUsersResponse, UserRecord, CreateUserBody, UpdateUserBody, MintedUserToken, TokenSurface, ListUserTokensResponse, UserIdentitiesResponse, AppSignInsResponse, AuthGateListResponse, CreateInviteBody, CreatedInvite, AuthInviteListResponse, CreatedPasswordReset, GateIdentitiesResponse, GateTenantStatus, RunnableAgentsResponse, LLMChatOptions, LLMChatResponse, LLMChatStreamItem, LLMEmbeddingsOptions, LLMEmbeddingsResponse, MCPServerDefVerifyResult, MemoryEmbedStatsResponse, MemoryEntriesResponse, MemoryEntryResponse, MemoryBackfillResponse, MemoryPurgeResponse, MemoryReembedResponse, MemoryScopeIDsResponse, MemoryScopesResponse, MemorySearchInput, MemorySearchResponse, PauseResult, RetentionOverride, PersistentVolumesResponse, EphemeralVolumesResponse, ResolveInterruptOptions, ResumeResult, ResolverMatrix, CompactRunResult, RunTreeDeletion, ReplaySessionResult, CancelTurnResult, ReviewRunResult, RunBatchOptions, RunBatchResult, RunOptions, ConfiguredRun, ConfiguredRunPatch, RunStateStreamItem, RuntimeStateResponse, SnapshotCreateResponse, SnapshotDescriptor, SnapshotEnvelope, SnapshotRestoreResponse, StreamUserRunStatesOptions, SubstrateToolInput, SubstrateToolResponse, CreatedTeam, CreateTeamOptions, DefNamesResponse, ForkTeamOptions, ModelAliasesResponse, OperatorTokenDefNamesResponse, ProviderModelsResponse, RoutingResponse, ScheduleListResponse, SchedulePauseResult, ScheduleRunNowResult, ScheduleStateView, ListTeamsResponse, PromotedTeam, RetiredTeam, TeamBreakpoints, TeamDefDetail, TeamRunDetached, TeamRunTarget, TeamVerification, TeamDraft, TeamDraftVerification, TeamVersionList, TeamDiagram, TeamRunResult, PathToolInput, PathToolResponse, DocumentToolInput, DocumentToolResponse, DocumentCopyInput, DocumentMoveInput, DocumentFindDuplicatesInput, DocumentFindDuplicatesResult, DocumentTransferResult, HistoryToolInput, HistoryToolResponse, EvaluationSubmitInput, EvaluationGetInput, EvaluationListForRunInput, EvaluationListForDefInput, EvaluationAggregateInput, EvaluationInput, EvaluationSubmitResult, EvaluationRecord, EvaluationListForRunResult, EvaluationListForDefResult, EvaluationAggregate, TranscriptResponse, WhoamiResponse, UsageDimension, UsageBucket, UsageReportResponse, TokenLimit, TokenLimitsResponse, ConfigResponse, SetTokenLimitRequest, AclBinding, AclBindingListResponse, AclCatalog, AclDefInput, AclDefListResponse, AclDefNamesResponse, AclDefRow, AclRule, AclValidateResult, AuthzDecision, AuthzEvaluationRequest, AuthzEvaluationsRequest, AuthzEvaluationsResponse, AuthzExplainResponse, AuthzSimulateRequest, AuthzSimulateResponse, CreateAclBindingBody, CreateGroupBody, GroupDetail, GroupEffective, GroupListResponse, GroupMemberChange, GroupMemberKind, GroupRow, AppClientConfig, AppClientEntry, ClientDefInput, ClientDefListResponse, ClientDefNamesResponse, ClientDefRecord, ClientDefRetireResult, ClientDefVerifyResult, DeviceLoginOptions, DeviceLoginResult } from "./types.js";
29
+ import type { ChangeFeedFrame, StreamChangesOptions, DocumentFeedFrame, DocumentFeedOptions, CredentialListResponse, CredentialMeta, OAuthConnectStart, OAuthCredentialConfig, CryptoKeyEncoding, CryptoKeyExport, CryptoKeyExternal, CryptoKeyType, CryptoRequest, CryptoResultByOp, DecideRequest, DecideResponse, DecisionModelsResponse, SpeechOptions, SpeechResult, TranscribeOptions, TranscribeResult, SpeechInfo, CredentialScope, DirectoryInspection, DirectoryTenant, DirectoryUser, ErasureReport, ErasureResult, MergeSubjectsResult, ReviewQueueFilter, ReviewQueueResult, RuleStatementsResult, RevertRulingResult, ListRulingsResult, ApplyReviewPolicyResult, BindSubjectPrincipalResult, Agent, AgentEvent, AgentList, CancelAgentResult, ClientOptions, ContinueOptions, RunOverrideOptions, EffectiveConfigResponse, RunFileInput, RunInboxDownload, AgentOverridableResponse, RetuneRunResponse, RunConfigResponse, RunPromptResponse, CreateSnapshotOptions, EnsureCodeAgentOptions, EnsureCodeAgentResult, EnsureHookDefOptions, EnsureHookDefResult, HookDefInput, HookDefOverlay, HookDefRowResponse, CreateDefOptions, ForkDefOptions, HookDefForkOverlay, ScheduleDefInput, ScheduleDefOverlay, ScheduleDefRowResponse, WebhookDefInput, WebhookDefOverlay, WebhookDefRowResponse, EnsureMcpServerOptions, EnsureMcpServerResult, HealthResponse, InterruptListResponse, InterruptStatus, ListUserAgentsOptions, WalkRunsPage, AckChannelOptions, AwaitChannelsOptions, BroadcastChannelsOptions, ChannelAckResult, ChannelAwaitResult, ChannelBroadcastResult, ChannelDescriptor, ChannelPeekResult, ListTeamChannelsOptions, PeekTeamChannelOptions, ReleaseTeamChannelOptions, TeamChannelPeekResult, TeamChannelReleaseResult, TeamChannelsResult, ChannelPublishResult, ChannelPurgeResult, ChannelReleaseResult, ChannelSubscribeResult, CreateChannelOptions, ListChannelsResponse, PeekChannelOptions, PublishChannelOptions, ReleaseChannelOptions, SetMemoryEntryOptions, SetMemoryEntryResponse, SubscribeChannelOptions, UpdateChannelOptions, LibraryAgentDefinition, LibraryListResponse, LibraryMcpServerDefinition, LibrarySkillDefinition, ListUsersResponse, UserRecord, CreateUserBody, UpdateUserBody, MintedUserToken, TokenSurface, ListUserTokensResponse, UserIdentitiesResponse, AppSignInsResponse, AuthGateListResponse, CreateInviteBody, CreatedInvite, AuthInviteListResponse, CreatedPasswordReset, GateIdentitiesResponse, GateTenantStatus, RunnableAgentsResponse, LLMChatOptions, LLMChatResponse, LLMChatStreamItem, LLMEmbeddingsOptions, LLMEmbeddingsResponse, MCPServerDefVerifyResult, MemoryEmbedStatsResponse, MemoryEntriesResponse, MemoryEntryResponse, MemoryBackfillResponse, MemoryPurgeResponse, MemoryReembedResponse, MemoryScopeIDsResponse, MemoryScopesResponse, MemorySearchInput, MemorySearchResponse, PauseResult, RetentionOverride, PersistentVolumesResponse, EphemeralVolumesResponse, ResolveInterruptOptions, ResumeResult, ResolverMatrix, CompactRunResult, RunTreeDeletion, ReplaySessionResult, CancelTurnResult, ReviewRunResult, RunBatchOptions, RunBatchResult, RunOptions, ConfiguredRun, ConfiguredRunPatch, RunStateStreamItem, RuntimeStateResponse, SnapshotCreateResponse, SnapshotDescriptor, SnapshotEnvelope, SnapshotRestoreResponse, StreamUserRunStatesOptions, SubstrateToolInput, SubstrateToolResponse, CreatedTeam, CreateTeamOptions, DefNamesResponse, ForkTeamOptions, ModelAliasesResponse, OperatorTokenDefNamesResponse, ProviderModelsResponse, RoutingResponse, ScheduleListResponse, SchedulePauseResult, ScheduleRunNowResult, ScheduleStateView, ListTeamsResponse, PromotedTeam, RetiredTeam, TeamBreakpoints, TeamDefDetail, TeamRunDetached, TeamRunTarget, TeamVerification, TeamDraft, TeamDraftVerification, TeamVersionList, TeamDiagram, TeamRunResult, PathToolInput, PathToolResponse, DocumentToolInput, DocumentToolResponse, DocumentCopyInput, DocumentMoveInput, DocumentFindDuplicatesInput, DocumentFindDuplicatesResult, DocumentAnnotation, DocumentListAnnotationsInput, DocumentListAnnotationsResult, DocumentAnnotateInput, DocumentTransferResult, HistoryToolInput, HistoryToolResponse, EvaluationSubmitInput, EvaluationGetInput, EvaluationListForRunInput, EvaluationListForDefInput, EvaluationAggregateInput, EvaluationInput, EvaluationSubmitResult, EvaluationRecord, EvaluationListForRunResult, EvaluationListForDefResult, EvaluationAggregate, TranscriptResponse, WhoamiResponse, UsageDimension, UsageBucket, UsageReportResponse, TokenLimit, TokenLimitsResponse, ConfigResponse, SetTokenLimitRequest, AclBinding, AclBindingListResponse, AclCatalog, AclDefInput, AclDefListResponse, AclDefNamesResponse, AclDefRow, AclRule, AclValidateResult, AuthzDecision, AuthzEvaluationRequest, AuthzEvaluationsRequest, AuthzEvaluationsResponse, AuthzExplainResponse, AuthzSimulateRequest, AuthzSimulateResponse, CreateAclBindingBody, CreateGroupBody, GroupDetail, GroupEffective, GroupListResponse, GroupMemberChange, GroupMemberKind, GroupRow, AppClientConfig, AppClientEntry, ClientDefInput, ClientDefListResponse, ClientDefNamesResponse, ClientDefRecord, ClientDefRetireResult, ClientDefVerifyResult, DeviceLoginOptions, DeviceLoginResult } from "./types.js";
30
30
  export declare class LoomcycleClient {
31
31
  private ctx;
32
32
  private readonly tokenProvider?;
@@ -1185,6 +1185,26 @@ export declare class LoomcycleClient {
1185
1185
  * `.close()` to stop. Uses the global WebSocket (browsers, Node 22+); pass
1186
1186
  * `WebSocketImpl` (e.g. the `ws` package) on older Node. */
1187
1187
  connectClientTools(opts: ConnectClientToolsOptions): ClientToolHost;
1188
+ /** Mint a one-time ticket for the client-tool socket (RFC GJ): POST
1189
+ * /v1/client-tools/ticket with this client's credential. The ticket opens
1190
+ * one socket, within 30 s of the mint, as `ticket.<t>` in
1191
+ * Sec-WebSocket-Protocol — the way a browser opens the socket under
1192
+ * strict sign-in, where the bearer is not read from that header.
1193
+ * connectClientTools calls it for you on every connect. */
1194
+ clientToolsTicket(opts?: {
1195
+ signal?: AbortSignal;
1196
+ }): Promise<{
1197
+ ticket: string;
1198
+ expiresAt: string;
1199
+ }>;
1200
+ /** The credential a client-tool connect presents: a fresh ticket, or —
1201
+ * only when the server has no ticket route (an older runtime: 404/405)
1202
+ * or issues no tickets (503 ticket_unavailable) and does not run strict
1203
+ * sign-in — the bearer itself, as before. Under strict sign-in the
1204
+ * bearer is never put in the handshake header: the server would not
1205
+ * read it, and proxies and access logs do not treat that header as a
1206
+ * credential. */
1207
+ private clientToolsCredential;
1188
1208
  /** Restore from a same-instance snapshot id OR an inline
1189
1209
  * envelope JSON. Idempotent: ON CONFLICT DO NOTHING per row;
1190
1210
  * the returned counters reflect rows actually written.
@@ -2167,6 +2187,43 @@ export declare class LoomcycleClient {
2167
2187
  scopeId?: string;
2168
2188
  tenant?: string;
2169
2189
  }): Promise<DocumentTransferResult>;
2190
+ /** The annotations of one chunk, document (`document_id`) or folder
2191
+ * (`level: "path"` with `path`), each marked `stale` or current (the Document
2192
+ * tool's `get_annotation`). Tenant scope; `scope` defaults to `"tenant"`. A
2193
+ * folder's annotation is left out unless the caller may read every document
2194
+ * it covers. `opts` as on {@link LoomcycleClient.document}. */
2195
+ getAnnotation(input: {
2196
+ scope?: "tenant";
2197
+ id?: string;
2198
+ document_id?: string;
2199
+ path?: string;
2200
+ level?: "branch" | "document" | "path";
2201
+ }, opts?: {
2202
+ signal?: AbortSignal;
2203
+ scopeId?: string;
2204
+ tenant?: string;
2205
+ }): Promise<{
2206
+ annotations: DocumentAnnotation[];
2207
+ }>;
2208
+ /** Page through the tenant's annotations with filters (the Document tool's
2209
+ * `list_annotations`). Pass the answer's `next_cursor` as `after` for the
2210
+ * next page. `opts` as on {@link LoomcycleClient.document}. */
2211
+ listAnnotations(input?: DocumentListAnnotationsInput, opts?: {
2212
+ signal?: AbortSignal;
2213
+ scopeId?: string;
2214
+ tenant?: string;
2215
+ }): Promise<DocumentListAnnotationsResult>;
2216
+ /** Write an annotation (the Document tool's `set_annotation`). Without
2217
+ * `inputs_sha256` it is sent as an operator's manual annotation
2218
+ * (`manual: true`), which the annotation pass never overwrites; the operator
2219
+ * plane alone may write one. `opts` as on {@link LoomcycleClient.document}. */
2220
+ annotate(input: DocumentAnnotateInput, opts?: {
2221
+ signal?: AbortSignal;
2222
+ scopeId?: string;
2223
+ tenant?: string;
2224
+ }): Promise<{
2225
+ annotation: DocumentAnnotation;
2226
+ }>;
2170
2227
  /** Find the copies in a set of documents (the Document tool's
2171
2228
  * `find_duplicates`, RFC GB): the same text by sha256, or the same title once
2172
2229
  * copy markers are stripped, each copy pointed at its original. A report
package/dist/client.js CHANGED
@@ -23,6 +23,7 @@
23
23
  * via fetch-helpers.ts:raiseFromResponse — see README.md for the
24
24
  * full mapping table.
25
25
  */
26
+ import { LoomcycleError } from "./errors.js";
26
27
  import { authHeaders, authorizedFetch, deleteRequest, deleteJSON, jsonFetch, patchJSON, postJSON, putJSON, raiseFromResponse, } from "./fetch-helpers.js";
27
28
  import { parseSSE } from "./stream.js";
28
29
  import { InteractiveSession } from "./interactive.js";
@@ -1681,14 +1682,50 @@ export class LoomcycleClient {
1681
1682
  * `.close()` to stop. Uses the global WebSocket (browsers, Node 22+); pass
1682
1683
  * `WebSocketImpl` (e.g. the `ws` package) on older Node. */
1683
1684
  connectClientTools(opts) {
1684
- // A provider is asked on every (re)connect, so a host outliving one
1685
- // access token reconnects with the next.
1686
- const provider = this.tokenProvider;
1687
- const auth = provider ? () => provider.getToken() : this.ctx.authToken;
1685
+ // With a credential, every (re)connect mints a fresh one-time ticket (a
1686
+ // ticket is spent by the handshake); a host outliving one access token
1687
+ // mints the next through the provider. Without one (an open-mode
1688
+ // server) the socket is opened bare, as before.
1689
+ const auth = this.tokenProvider || this.ctx.authToken ? () => this.clientToolsCredential() : undefined;
1688
1690
  const host = new ClientToolHost(clientToolsURL(this.ctx.baseUrl), auth, opts);
1689
1691
  host.start();
1690
1692
  return host;
1691
1693
  }
1694
+ /** Mint a one-time ticket for the client-tool socket (RFC GJ): POST
1695
+ * /v1/client-tools/ticket with this client's credential. The ticket opens
1696
+ * one socket, within 30 s of the mint, as `ticket.<t>` in
1697
+ * Sec-WebSocket-Protocol — the way a browser opens the socket under
1698
+ * strict sign-in, where the bearer is not read from that header.
1699
+ * connectClientTools calls it for you on every connect. */
1700
+ async clientToolsTicket(opts) {
1701
+ const out = await postJSON(this.ctx, "/v1/client-tools/ticket", undefined, opts);
1702
+ return { ticket: out.ticket, expiresAt: out.expires_at };
1703
+ }
1704
+ /** The credential a client-tool connect presents: a fresh ticket, or —
1705
+ * only when the server has no ticket route (an older runtime: 404/405)
1706
+ * or issues no tickets (503 ticket_unavailable) and does not run strict
1707
+ * sign-in — the bearer itself, as before. Under strict sign-in the
1708
+ * bearer is never put in the handshake header: the server would not
1709
+ * read it, and proxies and access logs do not treat that header as a
1710
+ * credential. */
1711
+ async clientToolsCredential() {
1712
+ try {
1713
+ return { ticket: (await this.clientToolsTicket()).ticket };
1714
+ }
1715
+ catch (err) {
1716
+ const noTicket = err instanceof LoomcycleError &&
1717
+ (err.status === 404 || err.status === 405 || (err.status === 503 && err.code === "ticket_unavailable"));
1718
+ if (!noTicket)
1719
+ throw err;
1720
+ const me = await this.whoami();
1721
+ if (me.auth?.mode === "strict") {
1722
+ throw new LoomcycleError("connectClientTools: this loomcycle runs strict sign-in and issues no client-tool ticket " +
1723
+ "(it needs a release with POST /v1/client-tools/ticket and LOOMCYCLE_SECRET_KEY set)", { code: "ticket_unavailable" });
1724
+ }
1725
+ const token = this.tokenProvider ? await this.tokenProvider.getToken() : this.ctx.authToken;
1726
+ return token ? { bearer: token } : undefined;
1727
+ }
1728
+ }
1692
1729
  /** Restore from a same-instance snapshot id OR an inline
1693
1730
  * envelope JSON. Idempotent: ON CONFLICT DO NOTHING per row;
1694
1731
  * the returned counters reflect rows actually written.
@@ -2911,6 +2948,31 @@ export class LoomcycleClient {
2911
2948
  async moveDocuments(input, opts) {
2912
2949
  return (await this.document({ op: "move_documents", ...input }, opts));
2913
2950
  }
2951
+ /** The annotations of one chunk, document (`document_id`) or folder
2952
+ * (`level: "path"` with `path`), each marked `stale` or current (the Document
2953
+ * tool's `get_annotation`). Tenant scope; `scope` defaults to `"tenant"`. A
2954
+ * folder's annotation is left out unless the caller may read every document
2955
+ * it covers. `opts` as on {@link LoomcycleClient.document}. */
2956
+ async getAnnotation(input, opts) {
2957
+ return (await this.document({ op: "get_annotation", scope: "tenant", ...input }, opts));
2958
+ }
2959
+ /** Page through the tenant's annotations with filters (the Document tool's
2960
+ * `list_annotations`). Pass the answer's `next_cursor` as `after` for the
2961
+ * next page. `opts` as on {@link LoomcycleClient.document}. */
2962
+ async listAnnotations(input = {}, opts) {
2963
+ return (await this.document({ op: "list_annotations", scope: "tenant", ...input }, opts));
2964
+ }
2965
+ /** Write an annotation (the Document tool's `set_annotation`). Without
2966
+ * `inputs_sha256` it is sent as an operator's manual annotation
2967
+ * (`manual: true`), which the annotation pass never overwrites; the operator
2968
+ * plane alone may write one. `opts` as on {@link LoomcycleClient.document}. */
2969
+ async annotate(input, opts) {
2970
+ const body = { op: "set_annotation", scope: "tenant", ...input };
2971
+ if (input.inputs_sha256 === undefined && input.manual === undefined) {
2972
+ body.manual = true;
2973
+ }
2974
+ return (await this.document(body, opts));
2975
+ }
2914
2976
  /** Find the copies in a set of documents (the Document tool's
2915
2977
  * `find_duplicates`, RFC GB): the same text by sha256, or the same title once
2916
2978
  * copy markers are stripped, each copy pointed at its original. A report
package/dist/index.d.ts CHANGED
@@ -164,6 +164,7 @@
164
164
  * document(input): Promise<DocumentToolResponse> // 13 ops; needs SQL Memory
165
165
  * copyDocuments(input) / moveDocuments(input): Promise<DocumentTransferResult> // RFC FT, dry run by default
166
166
  * findDuplicates(input): Promise<DocumentFindDuplicatesResult> // RFC GB, a report unless propose: true
167
+ * getAnnotation / listAnnotations / annotate // a brief + abstract per section, document, folder
167
168
  *
168
169
  * // History — browse/search/annotate past chats (RFC BE; tenant-confined)
169
170
  * history(input): Promise<HistoryToolResponse> // list/get/search/rename/annotate/pin/archive/recap/resume
@@ -220,8 +221,8 @@ export type { InteractiveSessionOps } from "./interactive.js";
220
221
  export { verifyLoomcycleSignature, verifyLoomcycleDelivery } from "./signature.js";
221
222
  export type { VerifySignatureOptions, VerifiedDelivery } from "./signature.js";
222
223
  export { ClientToolHost, clientToolsURL, CLIENT_TOOL_SUBPROTOCOL } from "./client-tools.js";
223
- export type { ClientToolSchema, ClientToolInvocation, ConnectClientToolsOptions, WebSocketLike, WebSocketCtor, } from "./client-tools.js";
224
+ export type { ClientToolSchema, ClientToolInvocation, ConnectClientToolsOptions, ClientToolsCredential, WebSocketLike, WebSocketCtor, } from "./client-tools.js";
224
225
  export { LoomcycleOAuth, OAuthTokenProvider, parseAuthorizeResponse, pkceChallenge } from "./oauth.js";
225
226
  export type { LoomcycleOAuthOptions, OAuthTokenProviderOptions } from "./oauth.js";
226
- export type { AgentEvent, ClientOptions, ContinueOptions, EventType, HostWidening, ImageMediaType, ParentContext, PromptContent, PromptSegment, RetryInfo, RunOptions, RunOverrideOptions, SamplingOptions, CompactionOptions, ContextOptions, ToolUse, Usage, CallTiming, Agent, AgentStatus, AwaitedState, AgentUsage, RunResult, RunSpec, RunSpecTeam, ConfiguredRun, ConfiguredRunPatch, ToolChoiceOptions, OutputFormatOptions, CancelAgentResult, ListAgentsResponse, ListUserAgentsOptions, AgentList, WalkRunsPage, RunBatchOptions, RunBatchResult, SpawnRunResult, CompactRunResult, RunTreeDeletion, RunTreeNotReached, DirectoryBudget, DirectoryInspection, DirectoryTenant, DirectoryUser, ErasureAccess, ErasureReport, ErasureResidue, ErasureResult, ErasureTier, MergeSubjectsResult, SubjectRef, BindSubjectPrincipalResult, ReviewQueueFilter, ReviewQueueGroup, ReviewQueueResult, RuleStatementsResult, RevertRulingResult, RulingBreakdown, RulingItem, RulingSelector, RulingRecord, ListRulingsResult, PolicyRuleCount, ApplyReviewPolicyResult, ErasureBoundSubject, ErasureTokenRef, CancelTurnResult, ReviewRunResult, ReplaySessionResult, TranscriptEvent, TranscriptResponse, HealthResponse, ListUsersResponse, UserSummary, UserStatus, UserRecord, CreateUserBody, UpdateUserBody, MintedUserToken, TokenRestrictions, TokenSurface, UserTokenMeta, ListUserTokensResponse, UserIdentity, UserIdentitiesResponse, AppSignIn, AppSignInsResponse, AuthGateKind, AuthGate, AuthGateKey, AuthGateRemoval, AuthGateProbe, AuthGateListResponse, CreateInviteBody, CreatedInvite, AuthInviteState, AuthInvite, AuthInviteListResponse, CreatedPasswordReset, GateIdentity, GateIdentitiesResponse, GateTenantStatus, RunnableAgent, RunnableAgentsResponse, WhoamiResponse, WhoamiEffective, WhoamiAuth, PauseResult, RetentionOverride, ResumeResult, RuntimeStateResponse, RuntimeStateStatus, ResolverMatrix, ResolverModelStatus, ResolverProviderAvailability, CreateSnapshotOptions, SnapshotCreateResponse, SnapshotDescriptor, SnapshotEnvelope, SnapshotListResponse, SnapshotRestoreResponse, MemoryEntriesResponse, MemoryEntry, MemoryEntryResponse, MemoryScopeIDsResponse, MemoryScopeIDSummary, MemoryScopeKind, MemoryScopesResponse, MemorySearchDocumentFilter, MemorySearchInput, MemorySource, MemoryWhen, MemoryTimeFilter, MemorySearchEntry, MemorySearchResponse, MemoryEmbedModelStats, MemoryEmbedStatsResponse, MemoryReembedConfigured, MemoryReembedResponse, MemoryBackfillResponse, MemoryPurgeResponse, InterruptListResponse, InterruptRow, InterruptStatus, ResolveInterruptOptions, ChannelHookCall, ChannelHookResult, HookFailMode, HookPhase, HookToolCall, HookToolResult, PostHookCall, PostHookResult, PreHookCall, PreHookResult, SubstrateToolInput, SubstrateToolResponse, TeamNameSummary, ListTeamsResponse, TeamDiagram, CreatedTeam, PromotedTeam, RetiredTeam, TeamDefDetail, TeamVerification, TeamDraft, TeamDraftVerification, TeamIssue, TeamIssueKind, TeamVersion, TeamVersionList, TeamBreakpoints, TeamRunDetached, TeamRunResult, TeamRunTarget, CreateTeamOptions, ForkTeamOptions, DefNameSummary, DefNamesResponse, OperatorTokenDefNameSummary, OperatorTokenDefNamesResponse, ScheduleListEntry, ScheduleListResponse, ScheduleActiveRun, ScheduleStateView, ScheduleRunNowResult, SchedulePauseResult, ModelAlias, ModelAliasesResponse, RoutingResponse, RoutingUserTier, RoutingTier, RoutingCandidate, RoutingThroughput, RoutingProvider, SearchRoutingProvider, RoutingEmbedder, RoutingDecision, RoutingDecisionModel, ProviderModelsResponse, TeamRunStep, TeamDecisionHandler, TeamDecisionQuestion, TeamDecisionAnswer, PathToolInput, PathToolResponse, DocumentToolInput, DocumentEdgeEvidence, DocumentToolResponse, DocumentCopyInput, DocumentMoveInput, DocumentTransferEntry, DocumentTransferResult, DocumentFindDuplicatesInput, DocumentDuplicatePair, DocumentFindDuplicatesResult, DocumentSearchFilter, DocumentSearchHit, DocumentSearchResult, DocumentRelatedResult, GraphSnapshot, HistoryToolInput, HistoryToolResponse, EvaluationEmitterRole, EvaluationSubmitInput, EvaluationGetInput, EvaluationListForRunInput, EvaluationListForDefInput, EvaluationAggregateInput, EvaluationInput, EvaluationSubmitResult, EvaluationRecord, EvaluationListForRunResult, EvaluationListForDefResult, EvaluationScoreStats, EvaluationAggregate, VolumeMode, PersistentVolumeEntry, PersistentVolumesResponse, EphemeralVolumeEntry, EphemeralVolumesResponse, SystemPromptPayload, UserInputPayload, ChannelDescriptor, ListChannelsResponse, RunStateEvent, RunStateStreamClose, RunStateStreamItem, RunStateStreamOpen, StreamUserRunStatesOptions, ChangeFeedError, ChangeFeedFrame, ChangeFeedStatus, EmbedderHealth, MemoryChange, MemoryChangeScope, MemoryChangeType, StreamChangesOptions, DocumentFeedChange, DocumentFeedChangeType, DocumentFeedFrame, DocumentFeedOptions, DocumentFeedStatus, AckChannelOptions, ChannelAckResult, ChannelMessageItem, ChannelPeekResult, ListTeamChannelsOptions, PeekTeamChannelOptions, ReleaseTeamChannelOptions, TeamChannelReleaseResult, TeamChannelDeclaredIn, TeamChannelDescriptor, TeamChannelPeekResult, TeamChannelsResult, ChannelPublishResult, ChannelPurgeResult, ChannelReleaseResult, ChannelScope, ChannelSubscribeResult, PeekChannelOptions, PublishChannelOptions, SubscribeChannelOptions, AwaitChannelsOptions, BroadcastChannelsOptions, ChannelAwaitEntry, ChannelAwaitMode, ChannelAwaitResult, ChannelBroadcastEntry, ChannelBroadcastResult, CreateChannelOptions, ReleaseChannelOptions, UpdateChannelOptions, SetMemoryEntryOptions, SetMemoryEntryResponse, AgentDefRowResponse, AgentDefVerifyResult, SkillDefVerifyResult, EnsureMcpServerOptions, EnsureMcpServerResult, MCPServerDefRowResponse, MCPServerDefVerifyResult, AgentDefOverlay, AgentRouting, AgentChannelACL, AgentInterruptionACL, AgentDecision, MemoryRerank, AgentSampling, AgentCompaction, AgentTranscription, AgentSpeech, AgentContext, TierCandidate, CoreBlock, HookEvent, InlineWebhook, HookEntry, EventHooks, ToolEntry, ToolHooksByTool, EnsureCodeAgentOptions, EnsureCodeAgentResult, CreateDefOptions, ForkDefOptions, EnsureHookDefOptions, EnsureHookDefResult, HookDefBody, HookDefForkOverlay, HookDefInput, HookDefMatch, HookDefOverlay, HookDefRowResponse, HookDefVerifyResult, ScheduleDefInput, ScheduleDefOverlay, ScheduleDefRowResponse, ScheduledRunHook, ScheduledRunPromptContent, ScheduledRunPromptSegment, WebhookDefAuth, WebhookDefFilter, WebhookDefInput, WebhookDefOverlay, WebhookDefRateLimit, WebhookDefRowResponse, WebhookDefDeliveries, WebhookDefSyncResponse, LibraryAgentDefinition, LibraryEntry, LibraryListResponse, LibraryMcpServerDefinition, LibrarySkillDefinition, LLMChatContent, LLMChatMessage, LLMChatOptions, LLMChatResponse, LLMChatStreamDelta, LLMChatStreamItem, LLMChatToolCall, LLMChatUsage, LLMTool, LLMEmbeddingItem, LLMEmbeddingsOptions, LLMEmbeddingsResponse, LLMEmbeddingsUsage, UsageDimension, UsageBucket, UsageAggregate, UsageReportResponse, CapabilityInertInfo, LimitInfo, FileCapturedInfo, TranscriptionInfo, AdmissionInfo, ErrorInfo, CallFormat, CallRef, HookDecisionInfo, TeamDecisionInfo, OverrideInfo, FallbackInfo, InterruptionEventInfo, SpawnChildInfo, TurnCancelledInfo, ChannelEventInfo, ContextCompactionInfo, ContextRecapInfo, ContextStateInfo, ContextExhaustedInfo, ContextTierVerdict, ContextDistillDeclinedInfo, EffectiveConfigResponse, RunFileInput, RunFileImportSource, RunFileExtractStructure, RunFileImportHeading, RunInboxDownload, EffectiveConfigSource, EffectiveValue, InertContextSetting, AgentOverridableResponse, OverridableField, OverrideLockReason, RetuneRunResponse, RunConfigRecord, SubagentHoldInfo, RunConfigResponse, RunPromptResponse, RunPromptSnapshot, PromptBlock, TokenLimit, TokenLimitsResponse, ConfigResponse, ConfigProvider, ConfigModel, ConfigSearch, ConfigInstance, SetTokenLimitRequest, CredentialScope, CredentialMeta, OAuthConnectStart, OAuthCredentialConfig, OAuthCredentialState, OAuthCredentialStatus, OAuthTokenEndpointAuth, CredentialListResponse, CryptoKeyVersion, CryptoKeyExport, CryptoKeyType, CryptoKeyEncoding, CryptoKeyBackend, CryptoKeyExternal, CryptoOp, CryptoRequestBase, CryptoKeyRef, CryptoEncryptRequest, CryptoDecryptRequest, CryptoRewrapRequest, CryptoMacRequest, CryptoVerifyMacRequest, CryptoSignRequest, CryptoVerifyRequest, CryptoPublicKeyRequest, CryptoTotpRequest, CryptoHashRequest, CryptoRandomRequest, CryptoHashPasswordRequest, CryptoVerifyPasswordRequest, CryptoRequest, CryptoEncryptResult, CryptoDecryptResult, CryptoRewrapResult, CryptoMacResult, CryptoVerifyResult, CryptoSignResult, CryptoPublicJWK, CryptoPublicKeyResult, CryptoTotpResult, CryptoHashResult, CryptoRandomResult, CryptoHashPasswordResult, CryptoVerifyPasswordResult, CryptoResultByOp, CryptoResult, DecideRequest, DecideResponse, DecisionQuestion, DecisionChoiceQuestion, DecisionNoulQuestion, DecisionScoreQuestion, DecisionAnswer, DecisionChoiceAnswer, DecisionNoulAnswer, DecisionScoreAnswer, DecisionModel, DecisionModelsResponse, SpeechFormat, SpeechOptions, SpeechResult, TranscribeOptions, TranscribeResult, TranscriptSegment, SpeechInfo, SpeechDirectionInfo, SpeechLanguageInfo, TranscriptionDirectionInfo, AclMode, AclSource, AclEffect, AclSubjectKind, AclCondition, AclRule, AclList, AclDefRow, AclDefListResponse, AclDefNamesResponse, AclValidateResult, AclCatalogType, AclCatalog, AclDefOp, AclDefInput, GroupRow, GroupMemberKind, GroupMember, GroupListResponse, GroupDetail, GroupEffective, CreateGroupBody, GroupMemberChange, AclBinding, AclBindingListResponse, CreateAclBindingBody, AuthzReason, AuthzDecision, AuthzRequestContext, AuthzEvaluationRequest, AuthzEvaluationsSemantic, AuthzEvaluationsRequest, AuthzEvaluationsResponse, AuthzTrace, AuthzAppliedBinding, AuthzExplainResponse, AuthzDraftBinding, AuthzSimulateRequest, AuthzSimulateResult, AuthzSimulateResponse, OAuthServerMetadata, OAuthTokenResponse, OAuthTokenSet, BeginAuthorizeOptions, AuthorizeRequest, AuthorizeResponseParams, CompleteAuthorizeOptions, RefreshTokenOptions, RevokeTokenOptions, TokenProvider, AppClientRefresh, AppClientConfig, ClientDefInput, ClientDefRecord, ConfigAppClient, AppClientEntry, ClientDefListResponse, ClientDefVerifyResult, ClientDefRetireResult, ClientDefNameSummary, ClientDefNamesResponse, DeviceLoginPrompt, DeviceLoginOptions, DeviceLoginResult, } from "./types.js";
227
+ export type { AgentEvent, ClientOptions, ContinueOptions, EventType, HostWidening, ImageMediaType, ParentContext, PromptContent, PromptSegment, RetryInfo, RunOptions, RunOverrideOptions, SamplingOptions, CompactionOptions, ContextOptions, ToolUse, Usage, CallTiming, Agent, AgentStatus, AwaitedState, AgentUsage, RunResult, RunSpec, RunSpecTeam, ConfiguredRun, ConfiguredRunPatch, ToolChoiceOptions, OutputFormatOptions, CancelAgentResult, ListAgentsResponse, ListUserAgentsOptions, AgentList, WalkRunsPage, RunBatchOptions, RunBatchResult, SpawnRunResult, CompactRunResult, RunTreeDeletion, RunTreeNotReached, DirectoryBudget, DirectoryInspection, DirectoryTenant, DirectoryUser, ErasureAccess, ErasureReport, ErasureResidue, ErasureResult, ErasureTier, MergeSubjectsResult, SubjectRef, BindSubjectPrincipalResult, ReviewQueueFilter, ReviewQueueGroup, ReviewQueueResult, RuleStatementsResult, RevertRulingResult, RulingBreakdown, RulingItem, RulingSelector, RulingRecord, ListRulingsResult, PolicyRuleCount, ApplyReviewPolicyResult, ErasureBoundSubject, ErasureTokenRef, CancelTurnResult, ReviewRunResult, ReplaySessionResult, TranscriptEvent, TranscriptResponse, HealthResponse, ListUsersResponse, UserSummary, UserStatus, UserRecord, CreateUserBody, UpdateUserBody, MintedUserToken, TokenRestrictions, TokenSurface, UserTokenMeta, ListUserTokensResponse, UserIdentity, UserIdentitiesResponse, AppSignIn, AppSignInsResponse, AuthGateKind, AuthGate, AuthGateKey, AuthGateRemoval, AuthGateProbe, AuthGateListResponse, CreateInviteBody, CreatedInvite, AuthInviteState, AuthInvite, AuthInviteListResponse, CreatedPasswordReset, GateIdentity, GateIdentitiesResponse, GateTenantStatus, RunnableAgent, RunnableAgentsResponse, WhoamiResponse, WhoamiEffective, WhoamiAuth, PauseResult, RetentionOverride, ResumeResult, RuntimeStateResponse, RuntimeStateStatus, ResolverMatrix, ResolverModelStatus, ResolverProviderAvailability, CreateSnapshotOptions, SnapshotCreateResponse, SnapshotDescriptor, SnapshotEnvelope, SnapshotListResponse, SnapshotRestoreResponse, MemoryEntriesResponse, MemoryEntry, MemoryEntryResponse, MemoryScopeIDsResponse, MemoryScopeIDSummary, MemoryScopeKind, MemoryScopesResponse, MemorySearchDocumentFilter, MemorySearchInput, MemorySource, MemoryWhen, MemoryTimeFilter, MemorySearchEntry, MemorySearchResponse, MemoryEmbedModelStats, MemoryEmbedStatsResponse, MemoryReembedConfigured, MemoryReembedResponse, MemoryBackfillResponse, MemoryPurgeResponse, InterruptListResponse, InterruptRow, InterruptStatus, ResolveInterruptOptions, ChannelHookCall, ChannelHookResult, HookFailMode, HookPhase, HookToolCall, HookToolResult, PostHookCall, PostHookResult, PreHookCall, PreHookResult, SubstrateToolInput, SubstrateToolResponse, TeamNameSummary, ListTeamsResponse, TeamDiagram, CreatedTeam, PromotedTeam, RetiredTeam, TeamDefDetail, TeamVerification, TeamDraft, TeamDraftVerification, TeamIssue, TeamIssueKind, TeamVersion, TeamVersionList, TeamBreakpoints, TeamRunDetached, TeamRunResult, TeamRunTarget, CreateTeamOptions, ForkTeamOptions, DefNameSummary, DefNamesResponse, OperatorTokenDefNameSummary, OperatorTokenDefNamesResponse, ScheduleListEntry, ScheduleListResponse, ScheduleActiveRun, ScheduleStateView, ScheduleRunNowResult, SchedulePauseResult, ModelAlias, ModelAliasesResponse, RoutingResponse, RoutingUserTier, RoutingTier, RoutingCandidate, RoutingThroughput, RoutingProvider, SearchRoutingProvider, RoutingEmbedder, RoutingDecision, RoutingDecisionModel, ProviderModelsResponse, TeamRunStep, TeamDecisionHandler, TeamDecisionQuestion, TeamDecisionAnswer, PathToolInput, PathToolResponse, DocumentToolInput, DocumentEdgeEvidence, DocumentToolResponse, DocumentCopyInput, DocumentMoveInput, DocumentTransferEntry, DocumentTransferResult, DocumentFindDuplicatesInput, DocumentDuplicatePair, DocumentFindDuplicatesResult, DocumentAnnotation, DocumentListAnnotationsInput, DocumentListAnnotationsResult, DocumentAnnotateInput, DocumentSearchFilter, DocumentSearchHit, DocumentSearchResult, DocumentRelatedResult, GraphSnapshot, HistoryToolInput, HistoryToolResponse, EvaluationEmitterRole, EvaluationSubmitInput, EvaluationGetInput, EvaluationListForRunInput, EvaluationListForDefInput, EvaluationAggregateInput, EvaluationInput, EvaluationSubmitResult, EvaluationRecord, EvaluationListForRunResult, EvaluationListForDefResult, EvaluationScoreStats, EvaluationAggregate, VolumeMode, PersistentVolumeEntry, PersistentVolumesResponse, EphemeralVolumeEntry, EphemeralVolumesResponse, SystemPromptPayload, UserInputPayload, ChannelDescriptor, ListChannelsResponse, RunStateEvent, RunStateStreamClose, RunStateStreamItem, RunStateStreamOpen, StreamUserRunStatesOptions, ChangeFeedError, ChangeFeedFrame, ChangeFeedStatus, EmbedderHealth, MemoryChange, MemoryChangeScope, MemoryChangeType, StreamChangesOptions, DocumentFeedChange, DocumentFeedChangeType, DocumentFeedFrame, DocumentFeedOptions, DocumentFeedStatus, AckChannelOptions, ChannelAckResult, ChannelMessageItem, ChannelPeekResult, ListTeamChannelsOptions, PeekTeamChannelOptions, ReleaseTeamChannelOptions, TeamChannelReleaseResult, TeamChannelDeclaredIn, TeamChannelDescriptor, TeamChannelPeekResult, TeamChannelsResult, ChannelPublishResult, ChannelPurgeResult, ChannelReleaseResult, ChannelScope, ChannelSubscribeResult, PeekChannelOptions, PublishChannelOptions, SubscribeChannelOptions, AwaitChannelsOptions, BroadcastChannelsOptions, ChannelAwaitEntry, ChannelAwaitMode, ChannelAwaitResult, ChannelBroadcastEntry, ChannelBroadcastResult, CreateChannelOptions, ReleaseChannelOptions, UpdateChannelOptions, SetMemoryEntryOptions, SetMemoryEntryResponse, AgentDefRowResponse, AgentDefVerifyResult, SkillDefVerifyResult, EnsureMcpServerOptions, EnsureMcpServerResult, MCPServerDefRowResponse, MCPServerDefVerifyResult, AgentDefOverlay, AgentRouting, AgentChannelACL, AgentInterruptionACL, AgentDecision, MemoryRerank, AgentSampling, AgentCompaction, AgentTranscription, AgentSpeech, AgentContext, TierCandidate, CoreBlock, HookEvent, InlineWebhook, HookEntry, EventHooks, ToolEntry, ToolHooksByTool, EnsureCodeAgentOptions, EnsureCodeAgentResult, CreateDefOptions, ForkDefOptions, EnsureHookDefOptions, EnsureHookDefResult, HookDefBody, HookDefForkOverlay, HookDefInput, HookDefMatch, HookDefOverlay, HookDefRowResponse, HookDefVerifyResult, ScheduleDefInput, ScheduleDefOverlay, ScheduleDefRowResponse, ScheduledRunHook, ScheduledRunPromptContent, ScheduledRunPromptSegment, WebhookDefAuth, WebhookDefFilter, WebhookDefInput, WebhookDefOverlay, WebhookDefRateLimit, WebhookDefRowResponse, WebhookDefDeliveries, WebhookDefSyncResponse, LibraryAgentDefinition, LibraryEntry, LibraryListResponse, LibraryMcpServerDefinition, LibrarySkillDefinition, LLMChatContent, LLMChatMessage, LLMChatOptions, LLMChatResponse, LLMChatStreamDelta, LLMChatStreamItem, LLMChatToolCall, LLMChatUsage, LLMTool, LLMEmbeddingItem, LLMEmbeddingsOptions, LLMEmbeddingsResponse, LLMEmbeddingsUsage, UsageDimension, UsageBucket, UsageAggregate, UsageReportResponse, CapabilityInertInfo, LimitInfo, FileCapturedInfo, TranscriptionInfo, AdmissionInfo, ErrorInfo, CallFormat, CallRef, HookDecisionInfo, TeamDecisionInfo, OverrideInfo, FallbackInfo, InterruptionEventInfo, SpawnChildInfo, TurnCancelledInfo, ChannelEventInfo, ContextCompactionInfo, ContextRecapInfo, ContextStateInfo, ContextExhaustedInfo, ContextTierVerdict, ContextDistillDeclinedInfo, EffectiveConfigResponse, RunFileInput, RunFileImportSource, RunFileExtractStructure, RunFileImportHeading, RunInboxDownload, EffectiveConfigSource, EffectiveValue, InertContextSetting, AgentOverridableResponse, OverridableField, OverrideLockReason, RetuneRunResponse, RunConfigRecord, SubagentHoldInfo, RunConfigResponse, RunPromptResponse, RunPromptSnapshot, PromptBlock, TokenLimit, TokenLimitsResponse, ConfigResponse, ConfigProvider, ConfigModel, ConfigSearch, ConfigInstance, SetTokenLimitRequest, CredentialScope, CredentialMeta, OAuthConnectStart, OAuthCredentialConfig, OAuthCredentialState, OAuthCredentialStatus, OAuthTokenEndpointAuth, CredentialListResponse, CryptoKeyVersion, CryptoKeyExport, CryptoKeyType, CryptoKeyEncoding, CryptoKeyBackend, CryptoKeyExternal, CryptoOp, CryptoRequestBase, CryptoKeyRef, CryptoEncryptRequest, CryptoDecryptRequest, CryptoRewrapRequest, CryptoMacRequest, CryptoVerifyMacRequest, CryptoSignRequest, CryptoVerifyRequest, CryptoPublicKeyRequest, CryptoTotpRequest, CryptoHashRequest, CryptoRandomRequest, CryptoHashPasswordRequest, CryptoVerifyPasswordRequest, CryptoRequest, CryptoEncryptResult, CryptoDecryptResult, CryptoRewrapResult, CryptoMacResult, CryptoVerifyResult, CryptoSignResult, CryptoPublicJWK, CryptoPublicKeyResult, CryptoTotpResult, CryptoHashResult, CryptoRandomResult, CryptoHashPasswordResult, CryptoVerifyPasswordResult, CryptoResultByOp, CryptoResult, DecideRequest, DecideResponse, DecisionQuestion, DecisionChoiceQuestion, DecisionNoulQuestion, DecisionScoreQuestion, DecisionAnswer, DecisionChoiceAnswer, DecisionNoulAnswer, DecisionScoreAnswer, DecisionModel, DecisionModelsResponse, SpeechFormat, SpeechOptions, SpeechResult, TranscribeOptions, TranscribeResult, TranscriptSegment, SpeechInfo, SpeechDirectionInfo, SpeechLanguageInfo, TranscriptionDirectionInfo, AclMode, AclSource, AclEffect, AclSubjectKind, AclCondition, AclRule, AclList, AclDefRow, AclDefListResponse, AclDefNamesResponse, AclValidateResult, AclCatalogType, AclCatalog, AclDefOp, AclDefInput, GroupRow, GroupMemberKind, GroupMember, GroupListResponse, GroupDetail, GroupEffective, CreateGroupBody, GroupMemberChange, AclBinding, AclBindingListResponse, CreateAclBindingBody, AuthzReason, AuthzDecision, AuthzRequestContext, AuthzEvaluationRequest, AuthzEvaluationsSemantic, AuthzEvaluationsRequest, AuthzEvaluationsResponse, AuthzTrace, AuthzAppliedBinding, AuthzExplainResponse, AuthzDraftBinding, AuthzSimulateRequest, AuthzSimulateResult, AuthzSimulateResponse, OAuthServerMetadata, OAuthTokenResponse, OAuthTokenSet, BeginAuthorizeOptions, AuthorizeRequest, AuthorizeResponseParams, CompleteAuthorizeOptions, RefreshTokenOptions, RevokeTokenOptions, TokenProvider, AppClientRefresh, AppClientConfig, ClientDefInput, ClientDefRecord, ConfigAppClient, AppClientEntry, ClientDefListResponse, ClientDefVerifyResult, ClientDefRetireResult, ClientDefNameSummary, ClientDefNamesResponse, DeviceLoginPrompt, DeviceLoginOptions, DeviceLoginResult, } from "./types.js";
227
228
  export { AclDeniedError, AgentIDInUseError, AgentNotFoundError, AlreadyPausingError, AuthError, BackpressureError, DeviceLoginError, NotFoundError, InsufficientScopeError, InvalidArgumentError, ChannelCursorRegressionError, LoomcycleError, NotPausedError, OAuthError, PauseNotConfiguredError, PerUserQuotaExhaustedError, PromptTooLargeError, RateLimitedError, RequestTooLargeError, SessionBusyError, SessionNotFoundError, SnapshotNotFoundError, SnapshotTooLargeError, SnapshotVersionError, SubstrateToolRefusedError, TokenLimitExceededError, UnavailableError, } from "./errors.js";
package/dist/index.js CHANGED
@@ -164,6 +164,7 @@
164
164
  * document(input): Promise<DocumentToolResponse> // 13 ops; needs SQL Memory
165
165
  * copyDocuments(input) / moveDocuments(input): Promise<DocumentTransferResult> // RFC FT, dry run by default
166
166
  * findDuplicates(input): Promise<DocumentFindDuplicatesResult> // RFC GB, a report unless propose: true
167
+ * getAnnotation / listAnnotations / annotate // a brief + abstract per section, document, folder
167
168
  *
168
169
  * // History — browse/search/annotate past chats (RFC BE; tenant-confined)
169
170
  * history(input): Promise<HistoryToolResponse> // list/get/search/rename/annotate/pin/archive/recap/resume
package/dist/types.d.ts CHANGED
@@ -810,6 +810,9 @@ export interface AgentEvent {
810
810
  * the flag would re-feed the model a successful-looking result. */
811
811
  is_error?: boolean;
812
812
  stop_reason?: string;
813
+ /** On `event: started`: the OpenTelemetry trace the run is recorded in.
814
+ * Absent when tracing is off or the trace is not sampled. */
815
+ trace_id?: string;
813
816
  /** Retry payload on `event: retry`. Nil on all other event types. */
814
817
  retry?: RetryInfo;
815
818
  /** Host-widening payload on `event: host_widened`. Nil on all other
@@ -1526,6 +1529,9 @@ export interface Agent {
1526
1529
  /** `"none"` for a no-trace run: its transcript holds markers, not content,
1527
1530
  * and `error` is a class. Absent on every other run. */
1528
1531
  retention?: string;
1532
+ /** The OpenTelemetry trace the run was recorded in. Absent when tracing was
1533
+ * off or the trace was not sampled. */
1534
+ trace_id?: string;
1529
1535
  error: string | null;
1530
1536
  usage: AgentUsage;
1531
1537
  last_heartbeat_at: string | null;
@@ -3806,6 +3812,12 @@ export type PathToolInput = {
3806
3812
  cursor?: string;
3807
3813
  /** rm: also delete the backing resource (NOT supported in v1). */
3808
3814
  resource_too?: boolean;
3815
+ /** ls (tenant scope): add each entry's annotation as `summary` (a folder's
3816
+ * from its `_annotation` document; `folder_summary` on a document with names
3817
+ * below it). */
3818
+ with_summary?: boolean;
3819
+ /** ls with_summary: the most abstract characters the page carries (default 2000). */
3820
+ summary_chars?: number;
3809
3821
  [extra: string]: unknown;
3810
3822
  };
3811
3823
  /** Input for {@link LoomcycleClient.document} — the RFC AK chunked-graph
@@ -3835,7 +3847,7 @@ export type DocumentEdgeEvidence = {
3835
3847
  part?: "body" | "title";
3836
3848
  };
3837
3849
  export type DocumentToolInput = {
3838
- op: "create_document" | "get_document" | "documents_summary" | "query_documents" | "graph_snapshot" | "delete_document" | "set_path" | "copy_documents" | "move_documents" | "find_duplicates" | "mark_source" | "create_chunk" | "upsert_chunk" | "get_chunk" | "update_chunk" | "delete_chunk" | "supersede_chunk" | "graph_recall" | "move_chunk" | "reorder_chunk" | "link_chunks" | "unlink_chunks" | "get_edges" | "get_edge" | "propose_statement" | "accept_statement" | "reject_statement" | "list_statements" | "judge_statements" | "maintain_statement" | "resolve_anchor" | "lease" | "release" | "describe_ontology" | "extract_citations" | "classify" | "accept_classification" | "query_chunks" | "add_tags" | "remove_tags" | "list_tags" | "define_type" | "list_types" | "set_asset" | "get_asset" | "export_md" | "import_md" | "backlinks" | "related" | "unlinked_mentions" | "history" | "get_version" | "diff" | "export_canvas" | "import_canvas" | "list_facts" | "judge_fact" | "verbatim_answer" | "verification_stats" | "remember" | "propose_entity" | "propose_subject" | "search" | "set_remote" | "sync" | "diff_remote";
3850
+ op: "create_document" | "get_document" | "documents_summary" | "query_documents" | "graph_snapshot" | "delete_document" | "set_path" | "copy_documents" | "move_documents" | "find_duplicates" | "mark_source" | "create_chunk" | "upsert_chunk" | "get_chunk" | "update_chunk" | "delete_chunk" | "supersede_chunk" | "graph_recall" | "move_chunk" | "reorder_chunk" | "link_chunks" | "unlink_chunks" | "get_edges" | "get_edge" | "propose_statement" | "accept_statement" | "reject_statement" | "list_statements" | "judge_statements" | "maintain_statement" | "resolve_anchor" | "lease" | "release" | "set_annotation" | "get_annotation" | "annotation_inputs" | "list_annotations" | "delete_annotation" | "describe_ontology" | "extract_citations" | "classify" | "accept_classification" | "query_chunks" | "add_tags" | "remove_tags" | "list_tags" | "define_type" | "list_types" | "set_asset" | "get_asset" | "export_md" | "import_md" | "backlinks" | "related" | "unlinked_mentions" | "history" | "get_version" | "diff" | "export_canvas" | "import_canvas" | "list_facts" | "judge_fact" | "verbatim_answer" | "verification_stats" | "remember" | "propose_entity" | "propose_subject" | "search" | "set_remote" | "sync" | "diff_remote";
3839
3851
  scope?: "agent" | "user" | "tenant";
3840
3852
  /** Document id (get/delete_document) or chunk id (get/update/delete/move_chunk). */
3841
3853
  id?: string;
@@ -4065,6 +4077,40 @@ export type DocumentToolInput = {
4065
4077
  name?: string;
4066
4078
  /** lease: how long to hold it, in milliseconds (default 60000, max one hour). */
4067
4079
  ttl_ms?: number;
4080
+ /** set_annotation / get_annotation / annotation_inputs / delete_annotation /
4081
+ * list_annotations: which annotation of the target — "branch" (a section) or
4082
+ * "document" (on the document's root chunk). Default: what the chunk is. */
4083
+ level?: "branch" | "document" | "path";
4084
+ /** set_annotation: one sentence (at most 240 characters) for choosing. */
4085
+ brief?: string;
4086
+ /** set_annotation: one paragraph (at most 2000 characters) standing in for reading. */
4087
+ abstract?: string;
4088
+ /** set_annotation: the annotation's language code (default: the document's). */
4089
+ language?: string;
4090
+ /** set_annotation: the hash annotation_inputs returned; refused when the text moved since. */
4091
+ inputs_sha256?: string;
4092
+ /** annotation_inputs / set_annotation: the prompt's version, part of the hash. */
4093
+ prompt_version?: number;
4094
+ /** set_annotation: the model that wrote it. */
4095
+ model?: string;
4096
+ /** set_annotation: an operator's own text (no hash; never overwritten by the walk).
4097
+ * list_annotations: only these. */
4098
+ manual?: boolean;
4099
+ /** list_annotations: only annotations whose target changed since they were written. */
4100
+ stale?: boolean;
4101
+ /** list_annotations: only annotations written before this RFC 3339 time. */
4102
+ written_before?: string;
4103
+ /** get_document / get_chunk / search / related / graph_recall / documents_summary /
4104
+ * query_documents: add each row's nearest annotation as `summary`
4105
+ * ({level, brief, abstract?, stale?, chunk_id?}). */
4106
+ with_summary?: boolean;
4107
+ /** with_summary: the most abstract characters a response carries (default 2000, max 8000). */
4108
+ summary_chars?: number;
4109
+ /** search: rank the annotations too — "include" fuses them with the passages,
4110
+ * "only" answers from them alone (a question about the corpus as a whole). */
4111
+ annotations?: "none" | "include" | "only";
4112
+ /** search with annotations: which levels to rank (default all). */
4113
+ annotation_levels?: Array<"branch" | "document" | "path">;
4068
4114
  /** classify: "propose" (default) applies an unambiguous rule match and files the
4069
4115
  * rest for review; "report" writes nothing. judge_statements: "rule"
4070
4116
  * (default) or "recommend". */
@@ -5588,9 +5634,11 @@ export interface AgentDefOverlay {
5588
5634
  * `'judge'` (it records the judge's verdicts) are for `provider: 'code-js'`
5589
5635
  * only. `'link'`: its `link_chunks` in the tenant scope is asserted rather
5590
5636
  * than filed for review. `'remember'`: its runs may call Document
5591
- * `remember`. Unset or `[]` = none. A new agent may list only what its
5592
- * author holds; a fork only what the version it forks held. */
5593
- statement_methods?: Array<'rule' | 'extractor' | 'judge' | 'link' | 'remember'>;
5637
+ * `remember`. `'annotate'` (code-js only): its runs may write document
5638
+ * annotations (Document `set_annotation`) and hold the `annotator` lease.
5639
+ * Unset or `[]` = none. A new agent may list only what its author holds; a
5640
+ * fork only what the version it forks held. */
5641
+ statement_methods?: Array<'rule' | 'extractor' | 'judge' | 'link' | 'remember' | 'annotate'>;
5594
5642
  /** Channel tool ACL (default-deny until set). */
5595
5643
  channels?: AgentChannelACL;
5596
5644
  /** Interruption tool gate — `enabled: true` REQUIRED for the tool to work. */
@@ -7884,6 +7932,10 @@ export interface AclCatalogType {
7884
7932
  verbs: string[];
7885
7933
  scopes?: string[];
7886
7934
  separator?: string;
7935
+ /** The verbs asked only of every instance of this type: a rule on one of
7936
+ * them must name `<type>:*` (a selector naming some instances is refused
7937
+ * with `rule_not_enforceable`). Absent on a type with none. */
7938
+ type_level_only?: string[];
7887
7939
  }
7888
7940
  /** `aclDef({op: "catalog"})`: what a rule may name. */
7889
7941
  export interface AclCatalog {
@@ -8369,3 +8421,62 @@ export interface DeviceLoginResult {
8369
8421
  expiresIn?: number;
8370
8422
  scope?: string[];
8371
8423
  }
8424
+ /** One stored annotation (the Document tool's annotation ops): an indicative
8425
+ * `brief` and an informative `abstract` written about a section (`branch`), a
8426
+ * document (`document`, on its root chunk) or a Path folder (`path`). Kept for
8427
+ * the tenant scope only. `stale` is computed on read: the text it was written
8428
+ * from has changed since. */
8429
+ export type DocumentAnnotation = {
8430
+ chunk_id: string;
8431
+ document_id: string;
8432
+ level: "branch" | "document" | "path";
8433
+ brief: string;
8434
+ abstract: string;
8435
+ language: string;
8436
+ class?: string;
8437
+ inputs_sha256: string;
8438
+ prompt_version: number;
8439
+ model?: string;
8440
+ manual: boolean;
8441
+ written_at: string;
8442
+ written_by: string;
8443
+ /** A path record's folder. */
8444
+ folder?: string;
8445
+ stale?: boolean;
8446
+ };
8447
+ /** The filters of {@link LoomcycleClient.listAnnotations}. */
8448
+ export type DocumentListAnnotationsInput = {
8449
+ scope?: "tenant";
8450
+ level?: "branch" | "document" | "path";
8451
+ document_id?: string;
8452
+ under_path?: string;
8453
+ stale?: boolean;
8454
+ manual?: boolean;
8455
+ /** RFC 3339. */
8456
+ written_before?: string;
8457
+ limit?: number;
8458
+ /** The previous page's `next_cursor`. */
8459
+ after?: string;
8460
+ };
8461
+ export type DocumentListAnnotationsResult = {
8462
+ annotations: DocumentAnnotation[];
8463
+ next_cursor?: string;
8464
+ };
8465
+ /** What {@link LoomcycleClient.annotate} writes: a target (`id` a chunk,
8466
+ * `document_id`, or with `level: "path"` the folder's `path`) and the two
8467
+ * texts. Without `inputs_sha256` (from `annotation_inputs`) it is an
8468
+ * operator's manual annotation, which the annotation pass never overwrites. */
8469
+ export type DocumentAnnotateInput = {
8470
+ scope?: "tenant";
8471
+ id?: string;
8472
+ document_id?: string;
8473
+ path?: string;
8474
+ level?: "branch" | "document" | "path";
8475
+ brief: string;
8476
+ abstract: string;
8477
+ language?: string;
8478
+ inputs_sha256?: string;
8479
+ prompt_version?: number;
8480
+ model?: string;
8481
+ manual?: boolean;
8482
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loomcycle/client",
3
- "version": "1.147.0",
3
+ "version": "1.148.0",
4
4
  "description": "TypeScript client for the loomcycle sidecar (HTTP+SSE). 71 methods covering run streaming, agent metadata, pause/resume/state, resolver re-probe (resolveProbe — issue #88 operator escape hatch), operator-token admin (operatorTokenDef — RFC L OSS multi-tenant auth) + whoami (RFC L authoritative principal, v0.17.0) + tenant-scoped listUsers / listUserAgents, dynamic MCP registration (mcpServerDef + v0.18.0 typed mcpServerDefVerify + ensureMcpServer idempotent register-if-changed), snapshot lifecycle, memory admin (incl. v0.9.0 Vector Memory embed_stats + reembed AND v0.11.5 setMemoryEntry + deleteMemoryEntry), interruption resolve, hook management, v0.8.22 substrate admin (agentDef + skillDef), v0.9.x n8n Phase 0 (listChannels + streamUserRunStates), v0.9.x Channel CRUD (publishChannel + subscribeChannel + peekChannel + ackChannel), v0.11.5 Channel admin CRUD (createChannel + updateChannel + deleteChannel — runtime substrate; yaml channels refuse mutation with HTTP 409), v0.9.x content_sha256 verify, v0.9.1 transcript first-cycle, v0.9.x dynamic MCP server registration (mcpServerDef + MCPServerDefVerifyResult), v0.10.3 Library v2 enumeration (listLibraryAgents + listLibrarySkills + listLibraryMcpServers), and v0.11.0 LLM Gateway (llmChat + llmStream — direct provider routing without agent overhead; primary target is n8n's LoomCycleChatModel AI Agent sub-node and any LangChain-compatible consumer). v0.10.1 — dual ESM + CommonJS distribution (additive — ESM consumers unchanged; CJS consumers like n8n's community-node loader now work). v0.19.0 — typed inline code-js agent ingestion (AgentDefOverlay.code_body + ensureCodeAgent — register a deterministic code agent through the substrate with no host filesystem bind; RFC J). v0.20.0 — ensureMcpServer surfaces discoveredToolCount straight from create (loomcycle now auto-discovers MCP tools at ingestion); rediscover is now an explicit force-refresh. v0.21.0 — run/continue accept optional non-secret `metadata` (repo name, review policy, …) passed to the agent, symmetric with the WebHook/Schedule trigger paths. v0.22.0 — version-aligned lockstep release; no client-surface change (RFC N tenant isolation of the agent/skill/MCP/Schedule/Webhook definition plane + real op-schemas on the builtin MCP meta-tools are both server-side). v0.23.0 — version-aligned lockstep release; no client-surface change (RFCs O/P/R MCP-server hardening + thin client and the RFC Q DeepSeek tool-content fix are all server-side / MCP-transport-side). v0.24.0 — purgeChannel clears a channel's buffered messages without deleting its definition (allowed on yaml-declared channels too, unlike deleteChannel — F20); AgentDefOverlay gains channels / evaluation_scopes / interruption so a COMPLETE interactive/multi-agent agent round-trips over the substrate (F14). (Consolidates the interim 0.24/0.25 package bumps, which were never tag-published, back into lockstep with the loomcycle v0.24.0 tag.) v0.25.0 — adds the RFC S channel fan-in/fan-out client twins: awaitChannels() (wait for any/all/at_least N messages across channels, or a timeout — non-committing) + broadcastChannels() (publish one payload to N channels in one atomic-pre-flight call), the client-facing counterparts of the in-band Channel.await / Channel.broadcast tool ops (the rest of v0.25.0 — the manual-management Web UI console + Context op=time + max_fires self-retiring schedules — is server-side / in-band, no client-surface change). v0.29.1 — Usage gains optional `max_context_tokens` (the serving model's context-window ceiling, stamped by the loop from Provider.Capabilities() on each usage event) so a consumer can render a 'context used / max' gauge without a hard-coded per-model table; additive + optional, no behavior change. (Lockstep catch-up: the field landed in loomcycle v0.29.0 but the adapter publish skipped on a version mismatch; v0.29.1 realigns the package version with the release tag so it publishes.) v0.33.0 — gRPC + TS client parity for the RFC Y external fan-out and the compaction surface: spawnRunBatch() (POST /v1/runs:batch — spawn up to 32 fresh runs concurrently in one call, combined index-aligned envelope, per-child failures in-envelope) + compactRun(runId) (POST /v1/runs/{run_id}/compact — summarize a parked run's context); plus per-run sampling + compaction overrides now accepted on runStreaming / continueSession (an explicit temperature 0 is preserved as deterministic, not dropped as falsy). (The gRPC half adds the matching SpawnRunBatch / CompactRun RPCs + the sampling/compaction fields on RunRequest/ContinueRequest — server-side.) v0.34.0 — version-aligned lockstep release; no client-surface change (context-transform plugins / RFC Z Phase 1a are server-side config; the exp7 hardening pass is server-side; the R2 cross-provider thinking-model downgrade surfaces a new `model_downgraded` SSE event the generic stream passes through unchanged). v0.35.0 — RFC AH dynamic filesystem volumes: volumeDef() (POST /v1/_volumedef — op-discriminated create/get/list/delete/purge; a Volume is flat, so delete unmaps + purge RemoveAll's, no retire/promote/fork) + listVolumes() / listEphemeralVolumes() (GET /v1/_volumes[/ephemeral] — tenant-scoped; host paths redacted for non-operator callers). Tenant-confined; the runtime derives the path inside an operator-blessed dynamic_root, so callers pass name + mode, never a host path. v1.1.1 — RFC AI interactive agentic sessions: an `interactive: true` flag on runStreaming/continueSession (a run that parks at end_turn for steering) + sendRunInput(runId, text) (POST /v1/runs/{id}/input — steer a live run) + streamRunByID(runId, {fromSeq}) (GET /v1/runs/{id}/stream — re-attach by run_id; the operator's prior turns replay as `steer` events so a cold client reconstructs the whole conversation) + a high-level InteractiveSession driver (client.interactiveSession / attachInteractiveSession — events()/send()/cancel(), the adapter port of the Web UI run terminal). The AgentEvent union gains awaiting_input/steer/context_compaction frames. Version-aligned with the loomcycle v1.1.x line so the v1.1.1 tag publishes it (also carrying the previously-unpublished v0.35.0 volume surface). v1.4.0 — RFC AL Path VFS + RFC AK Document on the wire: path(input) (POST /v1/_path — a Unix-like filesystem over Memory/Volumes/Documents; resolve/ls/stat/mkdir/mv/rm) + document(input) (POST /v1/_document — chunked-graph documents; 13 ops, needs SQL Memory on the sidecar). Scope (agent/user/tenant) + tenant are resolved server-side from the authenticated principal, never the wire; an off-run scope:'user' op keys on the principal subject so it interoperates with that user's agent runs. New PathToolInput / DocumentToolInput types; responses are op-varying (unknown — narrow as needed). v1.7.0 — RFC AT image/vision input: the PromptContent union gains an `image` variant ({ type:'image'; media_type: ImageMediaType; data: base64-no-prefix }) accepted in a user segment by runStreaming / continueSession (segments pass through unchanged — no method change). The model must be vision-capable or the run errors before the call. New ImageMediaType type (image/png|jpeg|gif|webp). v1.12.1 — Path/Document browse-by-subject + the full Document op set (RFC AS/AK): path(input, opts) / document(input, opts) accept optional scopeId / tenant browse overrides sent as ?scope_id= / ?tenant= query params (server reads them from the URL, re-checks authorization; omit both to browse your own subject — byte-identical to the pre-RFC-AS request), and DocumentToolInput.op now covers all 16 backend ops (adds set_path, export_md, import_md) with the matching include_metadata / markdown fields. Additive — existing path() / document() callers are unchanged. v1.16.0 — RFC BC client-executed tools (local tool host): connectClientTools({tools,onInvoke}) opens a persistent WebSocket to /v1/client-tools, registers tools this client runs on the user's machine (browser DOM / files / shell), and answers the invoke frames loomcycle routes when an agent of your principal calls a client:<tool> — returning your reply as an ordinary tool result. Returns a ClientToolHost driver (.close() to stop; auto-reconnect); dependency-free (global WebSocket in browsers / Node 22+, or an injected WebSocketImpl like the ws package on older Node); the bearer rides the Sec-WebSocket-Protocol subprotocol (browsers can't set an Authorization header on a WebSocket). The runtime's first WebSocket surface. v1.45.0 — RFC BL P5 subject erasure: erasureReport(subject, {tenant}) (GET /v1/_erasure — what this deployment holds about one subject, in three tiers: deletable with existing primitives, subject-keyed but not deletable, and facts ABOUT the subject in scopes they do not own) + erasureExecute(subject, {dryRun, confirm, tenant}) (POST /v1/_erasure — removes tiers 1 and 2). DEFAULTS TO A DRY RUN: dryRun defaults true and a live run also requires confirm === subject. The tier-3 residue is traceable only through the subject's chats, which a live run deletes, so a report afterwards shows rows: 0 while those facts remain — the returned object is the only durable record of what was not reached; persist it. New ErasureReport / ErasureResult / ErasureTier / ErasureResidue types. v1.47.0 — RFC BV memory-view SDK: memorySearch() (POST /v1/_memory/search — off-run unified semantic search spanning k/v entries AND document-chunk bodies in one ranked list, each hit tagged kind memory|document with chunk_id on document hits) + memoryEmbedStats(scope) + reembedMemory(scope, scopeId, {dryRun,limit}) (the Vector Memory embed-admin reads the memory-view console needs; dry_run defaults true). Fact reads (list_facts + get_chunk's entity block) ride the existing document() passthrough. Additive — existing callers unchanged. v1.61.0 — RFC CJ per-run context-window override: runStreaming / continueSession accept an optional maxContextTokens (integer tokens) that wins over the agent's own max_context_tokens; omitted inherits it (which defers to the provider/driver default). Distinct from a model's output cap; primarily for local inference (Ollama num_ctx). Serialized as the snake_case max_context_tokens field on POST /v1/runs + the continuation body; additive, existing callers unchanged. v1.72.1 — the TeamDef version lifecycle: listTeamVersions(name) (op=list — every version of one team, newest first), promoteTeam(defId) (op=promote — point the active pointer, which is what a run BY NAME executes; forkTeam defaults to promote:false, so authoring and putting in force stay two steps), retireTeam(defId, retired) (op=retire — reversible and version-scoped, unlike deleteTeam) and verifyTeam(name, contentSha256) (op=verify — the drift check for a workflow kept in source control and pushed to several deployments; an absent team answers deployed:false rather than raising). The ops existed on the substrate and over HTTP; a client that could author a team could not put one in force.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",