@nullsquare/agent-authority 0.4.6 → 0.4.8

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/src/task.js CHANGED
@@ -2,7 +2,11 @@ import { randomUUID } from 'node:crypto';
2
2
 
3
3
  import { AuthorityRuntime } from './index.js';
4
4
  import { createTaskLease } from './task-lease.js';
5
- import { createTaskLeaseGuard } from './guard.js';
5
+ import {
6
+ AuthorityApprovalRequiredError,
7
+ AuthorityDeniedError,
8
+ createTaskLeaseGuard
9
+ } from './guard.js';
6
10
  import { createDurableTaskLeaseSession } from './durable-task-lease.js';
7
11
 
8
12
  function requiredString(value, label) {
@@ -113,13 +117,32 @@ function resultFrom(value) {
113
117
  return null;
114
118
  }
115
119
 
120
+ function assertAllowedExecution(execution) {
121
+ const decision = execution?.result?.decision;
122
+ if (decision === 'deny') throw new AuthorityDeniedError(execution);
123
+ if (decision === 'require_approval') throw new AuthorityApprovalRequiredError(execution);
124
+ if (decision !== 'allow') {
125
+ throw new AuthorityDeniedError({
126
+ ...execution,
127
+ result: {
128
+ ...(execution?.result || {}),
129
+ decision: 'deny',
130
+ code: 'unknown_decision',
131
+ reason: 'authority returned an unsupported decision'
132
+ }
133
+ });
134
+ }
135
+ return execution;
136
+ }
137
+
116
138
  /**
117
139
  * Product-facing task authority facade.
118
140
  *
119
141
  * It intentionally does not replace Mission/TaskLease. It composes those
120
142
  * primitives into the small surface most agent developers need: run an effect,
121
- * derive named authority from guarded output, bind that authority to later
122
- * effects, explain step-up decisions, and complete the task.
143
+ * execute through a connected provider, derive named authority from guarded
144
+ * output, bind that authority to later effects, explain step-up decisions, and
145
+ * complete the task.
123
146
  */
124
147
  export class AgentTask {
125
148
  constructor({ lease, runtime = new AuthorityRuntime() } = {}) {
@@ -134,13 +157,31 @@ export class AgentTask {
134
157
  get status() { return this._lease.status; }
135
158
  get mission() { return structuredClone(this._lease.mission); }
136
159
 
160
+ /**
161
+ * Guard an application-owned effect callback.
162
+ */
137
163
  run(request, effect) {
138
164
  return this.guard.run(request, effect);
139
165
  }
140
166
 
167
+ /**
168
+ * Execute through an Agent Authority connected-provider runtime.
169
+ *
170
+ * Credentials remain inside the runtime/broker. The caller receives only the
171
+ * sanitized provider output, ALLOW receipt and execution evidence. Deny and
172
+ * step-up decisions use the same public error classes as run().
173
+ */
174
+ async execute(request) {
175
+ if (typeof this.runtime.executeTaskLease !== 'function') {
176
+ throw new Error('task runtime does not support connected provider execution');
177
+ }
178
+ const execution = await this.runtime.executeTaskLease(this._lease, request);
179
+ return assertAllowedExecution(execution);
180
+ }
181
+
141
182
  authorityFrom(execution, { name, fact_id, kind = 'opaque', from = [], extractor } = {}) {
142
183
  if (!execution?.receipt || !execution?.evidence || !Object.hasOwn(execution, 'output')) {
143
- throw new Error('authorityFrom() requires the result returned by task.run()');
184
+ throw new Error('authorityFrom() requires the result returned by task.run() or task.execute()');
144
185
  }
145
186
  const parents = Array.isArray(from) ? from : [from];
146
187
  return this._lease.deriveFromEvidence({