@peers-app/peers-sdk 0.22.0 → 0.23.1

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.
Files changed (45) hide show
  1. package/dist/context/user-context-singleton.d.ts +42 -0
  2. package/dist/context/user-context-singleton.js +45 -0
  3. package/dist/contracts/__tests__/contract-proxy.test.js +51 -1
  4. package/dist/contracts/__tests__/contract-resolvers.test.js +30 -0
  5. package/dist/contracts/__tests__/playground.test.js +5 -2
  6. package/dist/contracts/__tests__/system-contracts.test.js +3 -0
  7. package/dist/contracts/contract-proxy.d.ts +6 -0
  8. package/dist/contracts/contract-proxy.js +34 -0
  9. package/dist/contracts/contract-resolvers.js +9 -1
  10. package/dist/contracts/index.d.ts +1 -0
  11. package/dist/contracts/index.js +5 -2
  12. package/dist/contracts/system/index.d.ts +2 -0
  13. package/dist/contracts/system/index.js +5 -1
  14. package/dist/contracts/system/tool-access-control-contract.d.ts +35 -0
  15. package/dist/contracts/system/tool-access-control-contract.js +70 -0
  16. package/dist/data/access-level.d.ts +72 -0
  17. package/dist/data/access-level.js +109 -0
  18. package/dist/data/access-level.test.d.ts +1 -0
  19. package/dist/data/access-level.test.js +53 -0
  20. package/dist/data/assistants.d.ts +24 -0
  21. package/dist/data/assistants.js +21 -0
  22. package/dist/data/group-member-roles.d.ts +9 -0
  23. package/dist/data/group-member-roles.js +9 -0
  24. package/dist/data/group-permissions.d.ts +55 -1
  25. package/dist/data/group-permissions.js +76 -6
  26. package/dist/data/index.d.ts +3 -0
  27. package/dist/data/index.js +3 -0
  28. package/dist/data/orm/sql.data-source.d.ts +10 -0
  29. package/dist/data/orm/sql.data-source.js +48 -30
  30. package/dist/data/orm/sql.data-source.test.js +13 -0
  31. package/dist/data/package-version-resolver.test.js +2 -0
  32. package/dist/data/tool-access-approvals.d.ts +126 -0
  33. package/dist/data/tool-access-approvals.js +86 -0
  34. package/dist/data/tool-access.d.ts +162 -0
  35. package/dist/data/tool-access.js +235 -0
  36. package/dist/data/tool-access.test.d.ts +1 -0
  37. package/dist/data/tool-access.test.js +159 -0
  38. package/dist/data/tools.d.ts +15 -0
  39. package/dist/data/tools.js +11 -0
  40. package/dist/data/workflow-logs.d.ts +5 -5
  41. package/dist/data/workflow-runs.d.ts +2 -2
  42. package/dist/device-pairing/types.d.ts +6 -6
  43. package/dist/system-ids.d.ts +18 -0
  44. package/dist/system-ids.js +19 -1
  45. package/package.json +1 -1
@@ -245,13 +245,7 @@ class SQLDataSource {
245
245
  // @ts-expect-error - need to figure out how to get typescript to understand what's going on here
246
246
  record[this.metaData.primaryKeyName] = (0, utils_1.newid)();
247
247
  }
248
- // validate data
249
- try {
250
- this.schema.parse(record);
251
- }
252
- catch (e) {
253
- throw new Error(`Validation on insert failed for ${this.tableName}: ${e}`);
254
- }
248
+ this.applySchemaDefaults(record);
255
249
  const fields = this.metaData.fields.map((field) => `"${field.name}"`).join(", ");
256
250
  const values = this.metaData.fields.map((field) => jsValueToSqlValue(record[field.name]));
257
251
  const placeholders = values.map((_v) => "?").join(", ");
@@ -265,16 +259,14 @@ class SQLDataSource {
265
259
  // @ts-expect-error - need to figure out how to get typescript to understand what's going on here
266
260
  record[this.metaData.primaryKeyName] = (0, utils_1.newid)();
267
261
  }
268
- // validate data
269
262
  this.schema.parse(record);
270
263
  const primaryKey = record[this.metaData.primaryKeyName];
271
- const fields = this.metaData.fields
272
- .filter((field) => field.name !== this.metaData.primaryKeyName)
273
- .map((field) => `"${field.name}" = ?`)
274
- .join(",\n");
275
- const values = this.metaData.fields
276
- .filter((field) => field.name !== this.metaData.primaryKeyName)
277
- .map((field) => jsValueToSqlValue(record[field.name]));
264
+ const updateFields = this.fieldsForUpdate(record);
265
+ if (updateFields.length === 0) {
266
+ return record;
267
+ }
268
+ const fields = updateFields.map((field) => `"${field.name}" = ?`).join(",\n");
269
+ const values = updateFields.map((field) => jsValueToSqlValue(record[field.name]));
278
270
  const sql = [
279
271
  `UPDATE "${this.tableName}"`,
280
272
  `SET ${fields}`,
@@ -299,6 +291,40 @@ class SQLDataSource {
299
291
  const sql = `DELETE FROM "${this.tableName}"`;
300
292
  await this.db.exec(sql, []);
301
293
  }
294
+ /**
295
+ * Validate `record` and copy Zod defaults onto missing keys so NOT NULL
296
+ * columns (for example `accessLevel`) are written on insert.
297
+ */
298
+ applySchemaDefaults(record) {
299
+ let parsed;
300
+ try {
301
+ parsed = this.schema.parse(record);
302
+ }
303
+ catch (e) {
304
+ throw new Error(`Validation on insert failed for ${this.tableName}: ${e}`);
305
+ }
306
+ const writable = record;
307
+ for (const field of this.metaData.fields) {
308
+ if (writable[field.name] === undefined && parsed[field.name] !== undefined) {
309
+ writable[field.name] = parsed[field.name];
310
+ }
311
+ }
312
+ }
313
+ /**
314
+ * Columns to SET on update. Required fields that are missing are omitted so
315
+ * older peers without a new column do not overwrite a local value with NULL.
316
+ */
317
+ fieldsForUpdate(record) {
318
+ return this.metaData.fields.filter((field) => {
319
+ if (field.name === this.metaData.primaryKeyName) {
320
+ return false;
321
+ }
322
+ if (record[field.name] === undefined && !field.optional) {
323
+ return false;
324
+ }
325
+ return true;
326
+ });
327
+ }
302
328
  initRecord(data = {}) {
303
329
  const defaults = {};
304
330
  for (const field of this.metaData.fields) {
@@ -323,13 +349,7 @@ class SQLDataSource {
323
349
  // @ts-expect-error - need to figure out how to get typescript to understand what's going on here
324
350
  record[this.metaData.primaryKeyName] = (0, utils_1.newid)();
325
351
  }
326
- // validate data
327
- try {
328
- this.schema.parse(record);
329
- }
330
- catch (e) {
331
- throw new Error(`Validation on insert failed for ${this.tableName}: ${e}`);
332
- }
352
+ this.applySchemaDefaults(record);
333
353
  const fields = this.metaData.fields.map((field) => `"${field.name}"`).join(", ");
334
354
  const values = this.metaData.fields.map((field) => jsValueToSqlValue(record[field.name]));
335
355
  const placeholders = values.map((_v) => "?").join(", ");
@@ -346,16 +366,14 @@ class SQLDataSource {
346
366
  // @ts-expect-error - need to figure out how to get typescript to understand what's going on here
347
367
  record[this.metaData.primaryKeyName] = (0, utils_1.newid)();
348
368
  }
349
- // validate data
350
369
  this.schema.parse(record);
351
370
  const primaryKey = record[this.metaData.primaryKeyName];
352
- const fields = this.metaData.fields
353
- .filter((field) => field.name !== this.metaData.primaryKeyName)
354
- .map((field) => `"${field.name}" = ?`)
355
- .join(",\n");
356
- const values = this.metaData.fields
357
- .filter((field) => field.name !== this.metaData.primaryKeyName)
358
- .map((field) => jsValueToSqlValue(record[field.name]));
371
+ const updateFields = this.fieldsForUpdate(record);
372
+ if (updateFields.length === 0) {
373
+ return record;
374
+ }
375
+ const fields = updateFields.map((field) => `"${field.name}" = ?`).join(",\n");
376
+ const values = updateFields.map((field) => jsValueToSqlValue(record[field.name]));
359
377
  const sql = [
360
378
  `UPDATE "${this.tableName}"`,
361
379
  `SET ${fields}`,
@@ -205,6 +205,19 @@ describe("table", () => {
205
205
  newTask.title = "Test Task";
206
206
  expect(() => TasksTable.schema.parse(newTask)).not.toThrow();
207
207
  });
208
+ it("applies schema defaults on insert and preserves required fields on partial update", async () => {
209
+ const inserted = await TasksTable.insert({ title: "Defaulted body" });
210
+ expect(inserted.body).toBe("");
211
+ const stored = await TasksTable.get(inserted.taskId);
212
+ expect(stored?.body).toBe("");
213
+ await TasksTable.update({
214
+ taskId: inserted.taskId,
215
+ title: "Renamed",
216
+ });
217
+ const afterUpdate = await TasksTable.get(inserted.taskId);
218
+ expect(afterUpdate?.title).toBe("Renamed");
219
+ expect(afterUpdate?.body).toBe("");
220
+ });
208
221
  afterAll(async () => {
209
222
  await TasksTable.dropTableIfExists();
210
223
  await TasksTable.db.close();
@@ -7,6 +7,7 @@ const SQLiteDB = require("better-sqlite3");
7
7
  const user_context_1 = require("../context/user-context");
8
8
  const user_context_singleton_1 = require("../context/user-context-singleton");
9
9
  const utils_1 = require("../utils");
10
+ const access_level_1 = require("./access-level");
10
11
  const assistants_1 = require("./assistants");
11
12
  const group_member_roles_1 = require("./group-member-roles");
12
13
  const groups_1 = require("./groups");
@@ -375,6 +376,7 @@ describe("resolveDevicePackageVersion — expected behavior (control)", () => {
375
376
  const savedAssistant = await (0, assistants_1.Assistants)(dc).get(testAssistantId);
376
377
  expect(savedAssistant).toBeDefined();
377
378
  expect(savedAssistant?.name).toBe("Upgrade Test Assistant");
379
+ expect(savedAssistant?.accessLevel).toBe(access_level_1.DEFAULT_ACCESS_LEVEL);
378
380
  const savedWorkflow = await (0, workflows_1.Workflows)(dc).get(testWorkflowId);
379
381
  expect(savedWorkflow).toBeDefined();
380
382
  expect(savedWorkflow?.name).toBe("Upgrade Test Workflow");
@@ -0,0 +1,126 @@
1
+ import { z } from "zod";
2
+ import type { DataContext } from "../context/data-context";
3
+ /** Lifecycle of a tool-access approval request or reusable grant. */
4
+ export declare enum ToolAccessApprovalStatus {
5
+ pending = "pending",
6
+ approved = "approved",
7
+ executed = "executed",
8
+ rejected = "rejected",
9
+ expired = "expired",
10
+ failed = "failed"
11
+ }
12
+ /** How far a granted approval applies after the first execution. */
13
+ export declare enum ToolAccessApprovalScope {
14
+ once = "once",
15
+ thread = "thread",
16
+ context = "context"
17
+ }
18
+ /**
19
+ * Local-only record of a step-up tool approval.
20
+ *
21
+ * Stores identifiers, a frozen argument hash, and sanitized preview text.
22
+ * Do not put secrets, tokens, or raw log bodies in this table.
23
+ */
24
+ export declare const toolAccessApprovalSchema: z.ZodObject<{
25
+ toolAccessApprovalId: z.ZodEffects<z.ZodString, string, string>;
26
+ userId: z.ZodEffects<z.ZodString, string, string>;
27
+ assistantId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
28
+ toolId: z.ZodEffects<z.ZodString, string, string>;
29
+ toolName: z.ZodString;
30
+ dataContextId: z.ZodString;
31
+ workflowRunId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
32
+ threadMessageId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
33
+ workflowLogId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
34
+ argsHash: z.ZodString;
35
+ argsPreview: z.ZodDefault<z.ZodString>;
36
+ frozenArgs: z.ZodObject<{}, "strip", z.ZodAny, z.objectOutputType<{}, z.ZodAny, "strip">, z.objectInputType<{}, z.ZodAny, "strip">>;
37
+ requiredAccessLevel: z.ZodDefault<z.ZodNumber>;
38
+ scope: z.ZodDefault<z.ZodNativeEnum<typeof ToolAccessApprovalScope>>;
39
+ status: z.ZodDefault<z.ZodNativeEnum<typeof ToolAccessApprovalStatus>>;
40
+ nonce: z.ZodString;
41
+ expiresAt: z.ZodDate;
42
+ createdAt: z.ZodDefault<z.ZodDate>;
43
+ decidedAt: z.ZodOptional<z.ZodDate>;
44
+ executedAt: z.ZodOptional<z.ZodDate>;
45
+ resultSummary: z.ZodOptional<z.ZodString>;
46
+ }, "strip", z.ZodTypeAny, {
47
+ nonce: string;
48
+ status: ToolAccessApprovalStatus;
49
+ scope: ToolAccessApprovalScope;
50
+ userId: string;
51
+ expiresAt: Date;
52
+ toolId: string;
53
+ createdAt: Date;
54
+ dataContextId: string;
55
+ toolAccessApprovalId: string;
56
+ toolName: string;
57
+ argsHash: string;
58
+ argsPreview: string;
59
+ frozenArgs: {} & {
60
+ [k: string]: any;
61
+ };
62
+ requiredAccessLevel: number;
63
+ assistantId?: string | undefined;
64
+ threadMessageId?: string | undefined;
65
+ workflowRunId?: string | undefined;
66
+ workflowLogId?: string | undefined;
67
+ decidedAt?: Date | undefined;
68
+ executedAt?: Date | undefined;
69
+ resultSummary?: string | undefined;
70
+ }, {
71
+ nonce: string;
72
+ userId: string;
73
+ expiresAt: Date;
74
+ toolId: string;
75
+ dataContextId: string;
76
+ toolAccessApprovalId: string;
77
+ toolName: string;
78
+ argsHash: string;
79
+ frozenArgs: {} & {
80
+ [k: string]: any;
81
+ };
82
+ status?: ToolAccessApprovalStatus | undefined;
83
+ scope?: ToolAccessApprovalScope | undefined;
84
+ assistantId?: string | undefined;
85
+ createdAt?: Date | undefined;
86
+ threadMessageId?: string | undefined;
87
+ workflowRunId?: string | undefined;
88
+ workflowLogId?: string | undefined;
89
+ argsPreview?: string | undefined;
90
+ requiredAccessLevel?: number | undefined;
91
+ decidedAt?: Date | undefined;
92
+ executedAt?: Date | undefined;
93
+ resultSummary?: string | undefined;
94
+ }>;
95
+ /** A local-only tool-access approval or grant. */
96
+ export type IToolAccessApproval = z.infer<typeof toolAccessApprovalSchema>;
97
+ /**
98
+ * Accessor for the local-only {@link ToolAccessApprovals} table.
99
+ *
100
+ * @param dataContext - Optional data context; defaults to the current singleton.
101
+ */
102
+ export declare function ToolAccessApprovals(dataContext?: DataContext): import("..").Table<{
103
+ nonce: string;
104
+ status: ToolAccessApprovalStatus;
105
+ scope: ToolAccessApprovalScope;
106
+ userId: string;
107
+ expiresAt: Date;
108
+ toolId: string;
109
+ createdAt: Date;
110
+ dataContextId: string;
111
+ toolAccessApprovalId: string;
112
+ toolName: string;
113
+ argsHash: string;
114
+ argsPreview: string;
115
+ frozenArgs: {} & {
116
+ [k: string]: any;
117
+ };
118
+ requiredAccessLevel: number;
119
+ assistantId?: string | undefined;
120
+ threadMessageId?: string | undefined;
121
+ workflowRunId?: string | undefined;
122
+ workflowLogId?: string | undefined;
123
+ decidedAt?: Date | undefined;
124
+ executedAt?: Date | undefined;
125
+ resultSummary?: string | undefined;
126
+ }>;
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toolAccessApprovalSchema = exports.ToolAccessApprovalScope = exports.ToolAccessApprovalStatus = void 0;
4
+ exports.ToolAccessApprovals = ToolAccessApprovals;
5
+ const zod_1 = require("zod");
6
+ const user_context_singleton_1 = require("../context/user-context-singleton");
7
+ const zod_types_1 = require("../types/zod-types");
8
+ const access_level_1 = require("./access-level");
9
+ const table_definitions_system_1 = require("./orm/table-definitions.system");
10
+ const types_1 = require("./orm/types");
11
+ /** Lifecycle of a tool-access approval request or reusable grant. */
12
+ var ToolAccessApprovalStatus;
13
+ (function (ToolAccessApprovalStatus) {
14
+ ToolAccessApprovalStatus["pending"] = "pending";
15
+ ToolAccessApprovalStatus["approved"] = "approved";
16
+ ToolAccessApprovalStatus["executed"] = "executed";
17
+ ToolAccessApprovalStatus["rejected"] = "rejected";
18
+ ToolAccessApprovalStatus["expired"] = "expired";
19
+ ToolAccessApprovalStatus["failed"] = "failed";
20
+ })(ToolAccessApprovalStatus || (exports.ToolAccessApprovalStatus = ToolAccessApprovalStatus = {}));
21
+ /** How far a granted approval applies after the first execution. */
22
+ var ToolAccessApprovalScope;
23
+ (function (ToolAccessApprovalScope) {
24
+ ToolAccessApprovalScope["once"] = "once";
25
+ ToolAccessApprovalScope["thread"] = "thread";
26
+ ToolAccessApprovalScope["context"] = "context";
27
+ })(ToolAccessApprovalScope || (exports.ToolAccessApprovalScope = ToolAccessApprovalScope = {}));
28
+ /**
29
+ * Local-only record of a step-up tool approval.
30
+ *
31
+ * Stores identifiers, a frozen argument hash, and sanitized preview text.
32
+ * Do not put secrets, tokens, or raw log bodies in this table.
33
+ */
34
+ exports.toolAccessApprovalSchema = zod_1.z.object({
35
+ toolAccessApprovalId: zod_types_1.zodPeerId,
36
+ userId: zod_types_1.zodPeerId.describe("User who must approve and who requested the elevation"),
37
+ assistantId: zod_types_1.zodPeerId
38
+ .optional()
39
+ .describe("Assistant that requested the tool; omitted for direct user calls"),
40
+ toolId: zod_types_1.zodPeerId,
41
+ toolName: zod_1.z.string().describe("Display name of the tool at request time"),
42
+ dataContextId: zod_1.z.string().describe("Data context the tool would run in"),
43
+ workflowRunId: zod_types_1.zodPeerId.optional(),
44
+ threadMessageId: zod_types_1.zodPeerId
45
+ .optional()
46
+ .describe("User message / thread root that owns the workflow"),
47
+ workflowLogId: zod_types_1.zodPeerId.optional(),
48
+ argsHash: zod_1.z.string().describe("Canonical hash of the frozen tool arguments"),
49
+ argsPreview: zod_1.z
50
+ .string()
51
+ .default("")
52
+ .describe("Sanitized, truncated argument summary for the approval card"),
53
+ frozenArgs: zod_types_1.zodAnyObject.describe("Frozen arguments executed on approve; no secrets"),
54
+ requiredAccessLevel: access_level_1.accessLevelSchema,
55
+ scope: zod_1.z.nativeEnum(ToolAccessApprovalScope).default(ToolAccessApprovalScope.once),
56
+ status: zod_1.z.nativeEnum(ToolAccessApprovalStatus).default(ToolAccessApprovalStatus.pending),
57
+ nonce: zod_1.z.string().describe("Single-use token; empty after consume"),
58
+ expiresAt: zod_1.z.date(),
59
+ createdAt: zod_1.z.date().default(() => new Date()),
60
+ decidedAt: zod_1.z.date().optional(),
61
+ executedAt: zod_1.z.date().optional(),
62
+ resultSummary: zod_1.z.string().optional().describe("Sanitized outcome after execute or deny"),
63
+ });
64
+ const metaData = {
65
+ name: "ToolAccessApprovals",
66
+ description: "Local-only pending and granted step-up approvals for privileged tools.",
67
+ primaryKeyName: "toolAccessApprovalId",
68
+ fields: (0, types_1.schemaToFields)(exports.toolAccessApprovalSchema),
69
+ iconClassName: "bi bi-shield-lock",
70
+ localOnly: true,
71
+ indexes: [
72
+ { fields: ["threadMessageId"] },
73
+ { fields: ["workflowRunId"] },
74
+ { fields: ["status"] },
75
+ { fields: ["toolId"] },
76
+ ],
77
+ };
78
+ (0, table_definitions_system_1.registerSystemTableDefinition)(metaData, exports.toolAccessApprovalSchema);
79
+ /**
80
+ * Accessor for the local-only {@link ToolAccessApprovals} table.
81
+ *
82
+ * @param dataContext - Optional data context; defaults to the current singleton.
83
+ */
84
+ function ToolAccessApprovals(dataContext) {
85
+ return (0, user_context_singleton_1.getTableContainer)(dataContext).getTable(metaData, exports.toolAccessApprovalSchema);
86
+ }
@@ -0,0 +1,162 @@
1
+ /** Workflow-run var naming the Assistant whose delegated authority applies. */
2
+ export declare const ACCESS_ASSISTANT_ID_VAR = "accessAssistantId";
3
+ /** Workflow-run var used as a display / fallback Assistant id. */
4
+ export declare const ASSISTANT_ID_VAR = "assistantId";
5
+ /** Workflow-run var set when the user invoked a tool directly (CLI/UI/RPC). */
6
+ export declare const DIRECT_USER_INVOCATION_VAR = "directUserInvocation";
7
+ /** Workflow-run var pointing at a host-consumed approval that authorizes this run. */
8
+ export declare const HOST_APPROVED_APPROVAL_ID_VAR = "hostApprovedApprovalId";
9
+ /**
10
+ * Host-owned access keys. Models must not set these via `set-variable` or
11
+ * `run-a-workflow` child vars.
12
+ */
13
+ export declare const RESERVED_ACCESS_VAR_KEYS: readonly ["accessAssistantId", "assistantId", "directUserInvocation", "hostApprovedApprovalId"];
14
+ /** How long a pending approval stays actionable. */
15
+ export declare const TOOL_ACCESS_APPROVAL_TTL_MS: number;
16
+ /** How long an approved thread- or context-scoped grant remains reusable. */
17
+ export declare const TOOL_ACCESS_GRANT_TTL_MS: number;
18
+ /** Outcome of {@link decideToolAccess}. */
19
+ export type ToolAccessDecision = {
20
+ kind: "allow";
21
+ } | {
22
+ kind: "deny";
23
+ reason: string;
24
+ } | {
25
+ kind: "approval_required";
26
+ reason: string;
27
+ };
28
+ /**
29
+ * Decide whether a tool may run automatically, needs step-up approval, or is denied.
30
+ *
31
+ * Policy (`U` user, `A` Assistant, `T` tool):
32
+ * - Direct user invocation: allow when `T <= U`, otherwise deny.
33
+ * - Assistant invocation: deny when `T > U`; allow when `T <= A` or a matching
34
+ * grant exists; require approval when `A < T <= U`.
35
+ *
36
+ * @param args.userAccessLevel - Current user's group/personal access.
37
+ * @param args.toolAccessLevel - Required level declared on the tool.
38
+ * @param args.assistantAccessLevel - Assistant delegated level; omit for direct user calls.
39
+ * @param args.hasMatchingGrant - True when a reusable scoped grant already covers this call.
40
+ */
41
+ export declare function decideToolAccess(args: {
42
+ userAccessLevel: number;
43
+ toolAccessLevel: number;
44
+ assistantAccessLevel?: number;
45
+ hasMatchingGrant?: boolean;
46
+ }): ToolAccessDecision;
47
+ /**
48
+ * Return whether a user may invoke an Assistant in the current context.
49
+ *
50
+ * @param userAccessLevel - Current user's access.
51
+ * @param assistantAccessLevel - Assistant minimum / delegated level.
52
+ */
53
+ export declare function canInvokeAssistant(userAccessLevel: number, assistantAccessLevel: number): boolean;
54
+ /**
55
+ * Canonical hash of tool arguments used to bind one-time approvals.
56
+ *
57
+ * @param args - Tool input object; `undefined` hashes as an empty object.
58
+ */
59
+ export declare function hashToolArgs(args: Record<string, unknown> | undefined): string;
60
+ /**
61
+ * Append the required access level to a model-facing tool description.
62
+ *
63
+ * @param usageDescription - Existing tool usage text.
64
+ * @param accessLevel - Required level, already resolved or raw.
65
+ */
66
+ export declare function annotateToolAccessDescription(usageDescription: string, accessLevel: unknown): string;
67
+ /**
68
+ * Return the fail-closed access level for a record that may omit the field.
69
+ *
70
+ * @param record - Tool or Assistant-like object.
71
+ */
72
+ export declare function recordAccessLevel(record: {
73
+ accessLevel?: unknown;
74
+ } | undefined): number;
75
+ /**
76
+ * Choose the delegated Assistant ceiling for a run.
77
+ *
78
+ * Direct user calls have no Assistant ceiling (`undefined`). Otherwise only
79
+ * levels from existing Assistant records are considered; a missing record
80
+ * does not default to Self. When both an access-assistant and the run default
81
+ * resolve, the lower level wins so vars cannot escalate past the host-owned
82
+ * default Assistant.
83
+ *
84
+ * @returns `undefined` for direct user calls; otherwise 0–100 (`0` if none resolve).
85
+ */
86
+ export declare function resolveDelegatedAccessLevel(args: {
87
+ directUser: boolean;
88
+ accessAssistantLevel?: number;
89
+ defaultAssistantLevel?: number;
90
+ }): number | undefined;
91
+ /**
92
+ * Return whether `name` is a host-owned access-control workflow var.
93
+ *
94
+ * @param name - Candidate variable name.
95
+ */
96
+ export declare function isReservedAccessVarName(name: string): boolean;
97
+ /**
98
+ * Return the thread root id for a message: its parent, or itself if it is the root.
99
+ *
100
+ * Thread-scoped grants must key off this id so a follow-up reply in the same
101
+ * thread matches the original approval.
102
+ *
103
+ * @param message - Message or message-like object; `undefined` returns `undefined`.
104
+ */
105
+ export declare function threadRootMessageId(message: {
106
+ messageId?: string;
107
+ messageParentId?: string;
108
+ } | undefined): string | undefined;
109
+ /**
110
+ * Structured result returned to a model when a tool needs user approval.
111
+ */
112
+ export interface IToolAccessApprovalRequiredResult {
113
+ status: "approval_required";
114
+ approvalId: string;
115
+ toolId: string;
116
+ toolName: string;
117
+ requiredAccessLevel: number;
118
+ requiredAccessLabel: string;
119
+ message: string;
120
+ }
121
+ /**
122
+ * Build the model-visible payload for a pending approval.
123
+ */
124
+ export declare function approvalRequiredResult(args: {
125
+ approvalId: string;
126
+ toolId: string;
127
+ toolName: string;
128
+ requiredAccessLevel: number;
129
+ message: string;
130
+ }): IToolAccessApprovalRequiredResult;
131
+ /** Workflow plumbing / assistant-runner tools that must not block invocation. */
132
+ export declare const INFRASTRUCTURE_ACCESS_LEVEL: 0;
133
+ /**
134
+ * Remove one-shot host access tickets from a vars object.
135
+ *
136
+ * `directUserInvocation` and `hostApprovedApprovalId` authorize a single
137
+ * workflow run. Persisting them on a thread message lets later calls reuse a
138
+ * once-approval or skip Assistant-level checks.
139
+ *
140
+ * @param vars - Workflow or message vars; `undefined` becomes `{}`.
141
+ */
142
+ export declare function omitEphemeralAccessVars(vars: Record<string, unknown> | undefined): Record<string, unknown>;
143
+ /**
144
+ * Strip every host-owned access key, including Assistant identity vars.
145
+ *
146
+ * Use this before showing vars to a model or copying caller-supplied child
147
+ * vars onto a nested run.
148
+ *
149
+ * @param vars - Workflow or message vars; `undefined` becomes `{}`.
150
+ */
151
+ export declare function omitReservedAccessVars(vars: Record<string, unknown> | undefined): Record<string, unknown>;
152
+ /**
153
+ * Copy access-authority vars onto a child workflow so nested runs cannot escalate.
154
+ *
155
+ * Caller-supplied reserved keys are stripped. The child keeps the parent's
156
+ * Assistant id and whether the *parent* was a direct user invocation.
157
+ *
158
+ * @param parentVars - Parent workflow vars.
159
+ * @param parentDefaultAssistantId - Parent run's default Assistant.
160
+ * @param childVars - Vars about to be stored on the child.
161
+ */
162
+ export declare function inheritAccessVars(parentVars: Record<string, unknown> | undefined, parentDefaultAssistantId: string | undefined, childVars: Record<string, unknown>): Record<string, unknown>;