totemlayer 0.1.24 → 0.1.29

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,84 +1 @@
1
- import { TotemError } from "./errors.js";
2
- import { requireActionChecksKey, signalOnlyOptions } from "./request-options.js";
3
- import { Transport } from "./transport.js";
4
- export * from "./action-types.js";
5
- function responseField(payload, key) {
6
- const value = payload[key];
7
- if (!value || typeof value !== "object" || Array.isArray(value)) {
8
- throw new TotemError("Totem returned an invalid Action Checks response.", {
9
- code: "INVALID_RESPONSE",
10
- });
11
- }
12
- return value;
13
- }
14
- function proposal(action) {
15
- const authorityFields = [
16
- "organizationId",
17
- "userId",
18
- "ownerUserId",
19
- "requestedByUserId",
20
- "requestedByApiKeyId",
21
- "principal",
22
- "authentication",
23
- "apiKeyId",
24
- "from",
25
- ];
26
- if (!action || typeof action !== "object" || authorityFields.some((key) => key in action)) {
27
- throw new TotemError("Action Checks caller authority comes from its separate scoped API key.", {
28
- code: "INVALID_ACTION",
29
- });
30
- }
31
- return action;
32
- }
33
- /**
34
- * Separately authenticated Action Checks client. Human approval stays in Totem's UI.
35
- * Writes are never automatically replayed, even when the action has an idempotency key.
36
- * After an ambiguous execution failure, use get() to inspect the receipt before proceeding.
37
- */
38
- export class TotemActions {
39
- #transport;
40
- constructor(options) {
41
- this.#transport = new Transport({
42
- apiKey: requireActionChecksKey(options.actionChecksApiKey),
43
- baseUrl: options.baseUrl,
44
- timeoutMs: options.timeoutMs,
45
- maxRetries: options.maxRetries,
46
- retryDelayMs: options.retryDelayMs,
47
- fetch: options.fetch,
48
- }, { basePath: "/api/action-checks", responseEnvelope: "object" });
49
- }
50
- async create(action, options) {
51
- const result = await this.#transport.request("POST", "", {
52
- ...signalOnlyOptions(options),
53
- body: { action: proposal(action) },
54
- });
55
- return responseField(result, "suite");
56
- }
57
- async get(suiteId, options) {
58
- const result = await this.#transport.request("GET", `/${encodeURIComponent(suiteId)}`, signalOnlyOptions(options));
59
- return responseField(result, "suite");
60
- }
61
- async issueGrant(suiteId, action, options) {
62
- const result = await this.#transport.request("POST", `/${encodeURIComponent(suiteId)}/grant`, {
63
- ...signalOnlyOptions(options),
64
- body: { action: proposal(action) },
65
- });
66
- return responseField(result, "grant");
67
- }
68
- async execute(suiteId, input, options) {
69
- const result = await this.#transport.request("POST", `/${encodeURIComponent(suiteId)}/execute`, {
70
- ...signalOnlyOptions(options),
71
- body: { action: proposal(input.action), grant: input.grant },
72
- });
73
- const suite = responseField(result, "suite");
74
- const receipt = result.receipt === null
75
- ? null
76
- : responseField(result, "receipt");
77
- if (typeof result.receiptId !== "string" || !result.receiptId) {
78
- throw new TotemError("Totem returned an invalid execution receipt ID.", {
79
- code: "INVALID_RESPONSE",
80
- });
81
- }
82
- return { suite, receipt, receiptId: result.receiptId };
83
- }
84
- }
1
+ import{TotemError}from"./errors.js";import{requireActionChecksKey,signalOnlyOptions}from"./request-options.js";import{Transport}from"./transport.js";export*from"./action-types.js";function responseField(payload,key){const value=payload[key];if(!value||typeof value!=="object"||Array.isArray(value)){throw new TotemError("Totem returned an invalid Action Checks response.",{code:"INVALID_RESPONSE"})}return value}function proposal(action){const authorityFields=["organizationId","userId","ownerUserId","requestedByUserId","requestedByApiKeyId","principal","authentication","apiKeyId","from"];if(!action||typeof action!=="object"||authorityFields.some(key=>key in action)){throw new TotemError("Action Checks caller authority comes from its separate scoped API key.",{code:"INVALID_ACTION"})}return action}class TotemActions{#transport;constructor(options){this.#transport=new Transport({apiKey:requireActionChecksKey(options.actionChecksApiKey),baseUrl:options.baseUrl,timeoutMs:options.timeoutMs,maxRetries:options.maxRetries,retryDelayMs:options.retryDelayMs,fetch:options.fetch},{basePath:"/api/action-checks",responseEnvelope:"object"})}async create(action,options){const result=await this.#transport.request("POST","",{...signalOnlyOptions(options),body:{action:proposal(action)}});return responseField(result,"suite")}async get(suiteId,options){const result=await this.#transport.request("GET",`/${encodeURIComponent(suiteId)}`,signalOnlyOptions(options));return responseField(result,"suite")}async issueGrant(suiteId,action,options){const result=await this.#transport.request("POST",`/${encodeURIComponent(suiteId)}/grant`,{...signalOnlyOptions(options),body:{action:proposal(action)}});return responseField(result,"grant")}async execute(suiteId,input,options){const result=await this.#transport.request("POST",`/${encodeURIComponent(suiteId)}/execute`,{...signalOnlyOptions(options),body:{action:proposal(input.action),grant:input.grant}});const suite=responseField(result,"suite");const receipt=result.receipt===null?null:responseField(result,"receipt");if(typeof result.receiptId!=="string"||!result.receiptId){throw new TotemError("Totem returned an invalid execution receipt ID.",{code:"INVALID_RESPONSE"})}return{suite,receipt,receiptId:result.receiptId}}}export{TotemActions};
package/bin/sdk/errors.js CHANGED
@@ -1,67 +1 @@
1
- export class TotemError extends Error {
2
- code;
3
- status;
4
- requestId;
5
- retryAfterSeconds;
6
- constructor(message, options) {
7
- super(message, { cause: options.cause });
8
- this.name = new.target.name;
9
- this.code = options.code;
10
- this.status = options.status;
11
- this.requestId = options.requestId;
12
- this.retryAfterSeconds = options.retryAfterSeconds;
13
- }
14
- }
15
- export class TotemAuthenticationError extends TotemError {
16
- }
17
- export class TotemPermissionError extends TotemError {
18
- }
19
- export class TotemNotFoundError extends TotemError {
20
- }
21
- export class TotemConflictError extends TotemError {
22
- }
23
- export class TotemRateLimitError extends TotemError {
24
- }
25
- export class TotemTimeoutError extends TotemError {
26
- }
27
- export class TotemNetworkError extends TotemError {
28
- }
29
- export class TotemCanceledError extends TotemError {
30
- }
31
- export function apiError(status, body, requestId) {
32
- const error = body &&
33
- typeof body === "object" &&
34
- "error" in body &&
35
- body.error &&
36
- typeof body.error === "object"
37
- ? body.error
38
- : {};
39
- const message = "message" in error && typeof error.message === "string"
40
- ? error.message
41
- : `Totem request failed (${status}).`;
42
- const code = "code" in error && typeof error.code === "string" ? error.code : "HTTP_ERROR";
43
- const id = "requestId" in error && typeof error.requestId === "string" ? error.requestId : requestId;
44
- const Constructor = status === 401
45
- ? TotemAuthenticationError
46
- : status === 403
47
- ? TotemPermissionError
48
- : status === 404
49
- ? TotemNotFoundError
50
- : status === 409
51
- ? TotemConflictError
52
- : status === 429
53
- ? TotemRateLimitError
54
- : TotemError;
55
- const details = "details" in error ? error.details : undefined;
56
- const retryAfter = details && typeof details === "object" && "retryAfterSeconds" in details
57
- ? details.retryAfterSeconds
58
- : undefined;
59
- const retryAfterSeconds = status === 429 &&
60
- typeof retryAfter === "number" &&
61
- Number.isSafeInteger(retryAfter) &&
62
- retryAfter > 0 &&
63
- retryAfter <= 86400
64
- ? retryAfter
65
- : undefined;
66
- return new Constructor(message, { code, status, requestId: id, retryAfterSeconds });
67
- }
1
+ class TotemError extends Error{code;status;requestId;retryAfterSeconds;constructor(message,options){super(message,{cause:options.cause});this.name=new.target.name;this.code=options.code;this.status=options.status;this.requestId=options.requestId;this.retryAfterSeconds=options.retryAfterSeconds}}class TotemAuthenticationError extends TotemError{}class TotemPermissionError extends TotemError{}class TotemNotFoundError extends TotemError{}class TotemConflictError extends TotemError{}class TotemRateLimitError extends TotemError{}class TotemTimeoutError extends TotemError{}class TotemNetworkError extends TotemError{}class TotemCanceledError extends TotemError{}function apiError(status,body,requestId){const error=body&&typeof body==="object"&&"error"in body&&body.error&&typeof body.error==="object"?body.error:{};const message="message"in error&&typeof error.message==="string"?error.message:`Totem request failed (${status}).`;const code="code"in error&&typeof error.code==="string"?error.code:"HTTP_ERROR";const id="requestId"in error&&typeof error.requestId==="string"?error.requestId:requestId;const Constructor=status===401?TotemAuthenticationError:status===403?TotemPermissionError:status===404?TotemNotFoundError:status===409?TotemConflictError:status===429?TotemRateLimitError:TotemError;const details="details"in error?error.details:void 0;const retryAfter=details&&typeof details==="object"&&"retryAfterSeconds"in details?details.retryAfterSeconds:void 0;const retryAfterSeconds=status===429&&typeof retryAfter==="number"&&Number.isSafeInteger(retryAfter)&&retryAfter>0&&retryAfter<=86400?retryAfter:void 0;return new Constructor(message,{code,status,requestId:id,retryAfterSeconds})}export{TotemAuthenticationError,TotemCanceledError,TotemConflictError,TotemError,TotemNetworkError,TotemNotFoundError,TotemPermissionError,TotemRateLimitError,TotemTimeoutError,apiError};
@@ -1,6 +1,6 @@
1
1
  import { createLocalInspector, InspectionError } from "./inspector.js";
2
2
  import type { ActionProposal, AssistantActionCheck, AssistantActionCheckList, AssistantActionReceiptResult, AssistantCheckOptions } from "./action-types.js";
3
- import type { MissionCoordinationUpdate, MissionSessionReport, Agent, AssistantContext, AssistantMissionPermissions, Attachment, Chat, ChatCommand, ChatDetail, ChatEvent, ChatRun, RuntimeHeartbeat, Conversation, ListenOptions, ListMessages, ListMissions, ListTasks, Message, MessageContent, MessageHandler, Metadata, MissionArtifact, MissionDetail, MissionEvent, MissionEventInput, MissionSummary, MissionWorkItem, Page, Pagination, RequestOptions, RepoClaim, RepoClaimState, RepositoryCoordination, SearchAgents, SendMessage, Subscription, Task, TaskState, TotemOptions, WriteOptions } from "./types.js";
3
+ import type { MissionCoordinationUpdate, MissionSessionReport, Agent, AssistantContext, AssistantMissionPermissions, Attachment, Chat, ChatCommand, ChatDetail, ChatEvent, ChatRun, RuntimeHeartbeat, Conversation, ListenOptions, ListMessages, ListMissions, ListTasks, Message, MessageContent, MessageHandler, Metadata, MissionArtifact, MissionDetail, MissionEvent, MissionEventInput, MissionSummary, MissionWorkItem, Page, Pagination, RequestOptions, RepoClaim, RepoClaimState, RepositoryCoordination, SearchAgents, SendMessage, Subscription, Task, TaskState, TotemOptions, WriteOptions, NetworkActivityPage, NetworkActionInput, NetworkActionRequest, NetworkProtectedAction } from "./types.js";
4
4
  export * from "./types.js";
5
5
  export * from "./errors.js";
6
6
  export * from "./actions.js";
@@ -11,6 +11,38 @@ export declare class Totem {
11
11
  static connect(options: TotemOptions): Promise<ConnectedAgent>;
12
12
  connect(): Promise<ConnectedAgent>;
13
13
  agent(options?: RequestOptions): Promise<Agent>;
14
+ activity: {
15
+ list: (query?: { cursor?: string; limit?: number }, options?: RequestOptions) => Promise<NetworkActivityPage>;
16
+ };
17
+ /** Native Network authorization. Human approval remains in the receiving owner's conversation. */
18
+ actions: {
19
+ list: (query?: {
20
+ state?: Exclude<NetworkActionRequest["state"], "expired">;
21
+ direction?: "inbound" | "outbound";
22
+ cursor?: string;
23
+ limit?: number;
24
+ }, options?: RequestOptions) => Promise<Page<NetworkActionRequest>>;
25
+ request: (input: NetworkActionInput, options?: WriteOptions) => Promise<NetworkActionRequest>;
26
+ get: (id: string, options?: RequestOptions) => Promise<NetworkActionRequest>;
27
+ dispatch: (id: string, input: {
28
+ digest: string;
29
+ action: NetworkProtectedAction;
30
+ }, options?: RequestOptions) => Promise<NetworkActionRequest>;
31
+ complete: (id: string, input: {
32
+ executionId: string;
33
+ outcome: "succeeded" | "failed" | "uncertain";
34
+ summary: string;
35
+ }, options?: RequestOptions) => Promise<NetworkActionRequest>;
36
+ cancel: (id: string, options?: RequestOptions) => Promise<NetworkActionRequest>;
37
+ /** Execute one registered local operation after the exact receiver approval is consumed. */
38
+ run: <T>(id: string, action: NetworkProtectedAction, execute: (approved: NetworkProtectedAction, executionId: string) => Promise<{
39
+ value: T;
40
+ summary: string;
41
+ }>, options?: RequestOptions) => Promise<{
42
+ value: T;
43
+ receipt: NetworkActionRequest;
44
+ }>;
45
+ };
14
46
  assistant: {
15
47
  context: (options?: RequestOptions) => Promise<AssistantContext>;
16
48
  checks: {
@@ -195,6 +227,8 @@ export declare class Totem {
195
227
  }>;
196
228
  };
197
229
  runtime: {
230
+ activations: (options?: RequestOptions) => Promise<{ data: Array<{ id: string; state: string; ready: boolean }> }>;
231
+ reportActivation: (input: { id: string; state: "starting" | "ready" | "blocked" | "paused"; errorCode?: "READINESS_UNSUPPORTED" | "LISTENER_START_FAILED" | "AUTHORIZATION_REJECTED" }, options?: RequestOptions) => Promise<{ recorded: boolean }>;
198
232
  start: (input: {
199
233
  runId: string;
200
234
  provider: string;
@@ -233,6 +267,7 @@ export declare class Totem {
233
267
  postUpdate: (id: string, text: string, options?: WriteOptions) => Promise<Message>;
234
268
  update: (id: string, input: {
235
269
  state: Exclude<TaskState, "submitted" | "canceled">;
270
+ statusMessage?: NonNullable<Task["statusMessage"]>;
236
271
  artifacts?: Task["artifacts"];
237
272
  expectedVersion?: number;
238
273
  }, options?: RequestOptions) => Promise<Task>;