@heddleagent/execution-host-client 6.3.0 → 6.5.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 +121 -20
- package/dist/coordinator/contracts.d.ts +130 -0
- package/dist/coordinator/contracts.d.ts.map +1 -0
- package/dist/coordinator/contracts.js +112 -0
- package/dist/coordinator/contracts.js.map +1 -0
- package/dist/coordinator/hosted-heartbeat-coordinator-client.d.ts +20 -0
- package/dist/coordinator/hosted-heartbeat-coordinator-client.d.ts.map +1 -0
- package/dist/coordinator/hosted-heartbeat-coordinator-client.js +77 -0
- package/dist/coordinator/hosted-heartbeat-coordinator-client.js.map +1 -0
- package/dist/coordinator/hosted-heartbeat-delegation-client.d.ts +21 -0
- package/dist/coordinator/hosted-heartbeat-delegation-client.d.ts.map +1 -0
- package/dist/coordinator/hosted-heartbeat-delegation-client.js +117 -0
- package/dist/coordinator/hosted-heartbeat-delegation-client.js.map +1 -0
- package/dist/coordinator/hosted-heartbeat-delegation-service.d.ts +15 -0
- package/dist/coordinator/hosted-heartbeat-delegation-service.d.ts.map +1 -0
- package/dist/coordinator/hosted-heartbeat-delegation-service.js +81 -0
- package/dist/coordinator/hosted-heartbeat-delegation-service.js.map +1 -0
- package/dist/coordinator/hosted-heartbeat-task-reconciler.d.ts +11 -0
- package/dist/coordinator/hosted-heartbeat-task-reconciler.d.ts.map +1 -0
- package/dist/coordinator/hosted-heartbeat-task-reconciler.js +38 -0
- package/dist/coordinator/hosted-heartbeat-task-reconciler.js.map +1 -0
- package/dist/coordinator/index.d.ts +9 -0
- package/dist/coordinator/index.d.ts.map +1 -0
- package/dist/coordinator/index.js +7 -0
- package/dist/coordinator/index.js.map +1 -0
- package/dist/coordinator/node/delegation-http-service.d.ts +11 -0
- package/dist/coordinator/node/delegation-http-service.d.ts.map +1 -0
- package/dist/coordinator/node/delegation-http-service.js +131 -0
- package/dist/coordinator/node/delegation-http-service.js.map +1 -0
- package/dist/coordinator/node/environment.d.ts +3 -0
- package/dist/coordinator/node/environment.d.ts.map +1 -0
- package/dist/coordinator/node/environment.js +13 -0
- package/dist/coordinator/node/environment.js.map +1 -0
- package/dist/coordinator/node/index.d.ts +4 -0
- package/dist/coordinator/node/index.d.ts.map +1 -0
- package/dist/coordinator/node/index.js +3 -0
- package/dist/coordinator/node/index.js.map +1 -0
- package/dist/coordinator/node/types.d.ts +20 -0
- package/dist/coordinator/node/types.d.ts.map +1 -0
- package/dist/coordinator/node/types.js +2 -0
- package/dist/coordinator/node/types.js.map +1 -0
- package/dist/coordinator/runtime-session.d.ts +13 -0
- package/dist/coordinator/runtime-session.d.ts.map +1 -0
- package/dist/coordinator/runtime-session.js +23 -0
- package/dist/coordinator/runtime-session.js.map +1 -0
- package/dist/coordinator/service-token.d.ts +3 -0
- package/dist/coordinator/service-token.d.ts.map +1 -0
- package/dist/coordinator/service-token.js +7 -0
- package/dist/coordinator/service-token.js.map +1 -0
- package/dist/coordinator/types.d.ts +63 -0
- package/dist/coordinator/types.d.ts.map +1 -0
- package/dist/coordinator/types.js +2 -0
- package/dist/coordinator/types.js.map +1 -0
- package/dist/host/errors.d.ts +23 -0
- package/dist/host/errors.d.ts.map +1 -0
- package/dist/host/errors.js +32 -0
- package/dist/host/errors.js.map +1 -0
- package/dist/host/index.d.ts +7 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +6 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/jwt-execution-host-mcp-capability-verifier.d.ts +8 -0
- package/dist/host/jwt-execution-host-mcp-capability-verifier.d.ts.map +1 -0
- package/dist/host/jwt-execution-host-mcp-capability-verifier.js +86 -0
- package/dist/host/jwt-execution-host-mcp-capability-verifier.js.map +1 -0
- package/dist/host/jwt-execution-identity-verifier.d.ts +8 -0
- package/dist/host/jwt-execution-identity-verifier.d.ts.map +1 -0
- package/dist/host/jwt-execution-identity-verifier.js +76 -0
- package/dist/host/jwt-execution-identity-verifier.js.map +1 -0
- package/dist/host/schemas.d.ts +37 -0
- package/dist/host/schemas.d.ts.map +1 -0
- package/dist/host/schemas.js +24 -0
- package/dist/host/schemas.js.map +1 -0
- package/dist/host/types.d.ts +62 -0
- package/dist/host/types.d.ts.map +1 -0
- package/dist/host/types.js +7 -0
- package/dist/host/types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/jwt-verification.d.ts +5 -0
- package/dist/internal/jwt-verification.d.ts.map +1 -0
- package/dist/internal/jwt-verification.js +25 -0
- package/dist/internal/jwt-verification.js.map +1 -0
- package/dist/mcp/jwt-capability-verifier.d.ts.map +1 -1
- package/dist/mcp/jwt-capability-verifier.js +6 -25
- package/dist/mcp/jwt-capability-verifier.js.map +1 -1
- package/dist/node/http-service.d.ts.map +1 -1
- package/dist/node/http-service.js +5 -108
- package/dist/node/http-service.js.map +1 -1
- package/dist/node/http-utils.d.ts +15 -0
- package/dist/node/http-utils.d.ts.map +1 -0
- package/dist/node/http-utils.js +109 -0
- package/dist/node/http-utils.js.map +1 -0
- package/package.json +13 -1
package/README.md
CHANGED
|
@@ -5,7 +5,8 @@ products that invoke a separately deployed Heddle Execution Host. It lets an
|
|
|
5
5
|
adopter keep its own language stack, authentication, database, product policy,
|
|
6
6
|
MCP tools, and UI while reusing the security-sensitive v1 contract machinery.
|
|
7
7
|
|
|
8
|
-
> **Current availability:**
|
|
8
|
+
> **Current availability:** `6.5.0` is the next manual release from this
|
|
9
|
+
> repository; `6.4.0` remains the latest published version until then. The former
|
|
9
10
|
> `@roackb2/heddle-adopter@5.13.0` coordinate is deprecated and remains
|
|
10
11
|
> installable only for existing consumers. Heddle does not currently distribute
|
|
11
12
|
> the compatible Execution Host implementation or offer a hosted service. The
|
|
@@ -31,10 +32,13 @@ modular AWS SDK for its AgentCore transport and the official MCP SDK, plus
|
|
|
31
32
|
| `@heddleagent/execution-host-client/authority` | ES256 execution assertion and optional MCP capability issuance plus public JWKS projection |
|
|
32
33
|
| `@heddleagent/execution-host-client/conversation` | Turn orchestration across authority, model credentials, optional MCP policy, an `ExecutionHost`, and an optional adopter-implemented durable lifecycle store |
|
|
33
34
|
| `@heddleagent/execution-host-client/heartbeat` | Remote heartbeat orchestration that keeps durable task authority in a coordinator while a compatible Execution Host runs the agent cycle |
|
|
35
|
+
| `@heddleagent/execution-host-client/coordinator` | Authenticated task publication, pause-first desired-state reconciliation, product delegation, and delegated heartbeat execution |
|
|
36
|
+
| `@heddleagent/execution-host-client/coordinator/node` | Standard authenticated Node HTTP edge for product-owned heartbeat authorization |
|
|
34
37
|
| `@heddleagent/execution-host-client/mcp` | Independent capability verification at the adopter's MCP edge |
|
|
35
38
|
| `@heddleagent/execution-host-client/mcp/node` | Stateless official-SDK Streamable HTTP lifecycle around adopter-defined toolsets |
|
|
36
39
|
| `@heddleagent/execution-host-client/http-sse` | Transport-neutral conversation and heartbeat ports plus the strict direct-development HTTP/SSE client |
|
|
37
40
|
| `@heddleagent/execution-host-client/agentcore` | Official AWS AgentCore/SigV4 implementation of the same conversation and heartbeat ports |
|
|
41
|
+
| `@heddleagent/execution-host-client/host` | Invocation-bound execution-identity and MCP-capability verification shared by compatible Execution Host implementations |
|
|
38
42
|
| `@heddleagent/execution-host-client/testing` | Node-only loopback v1 fixture plus durable-turn store conformance for real adapters |
|
|
39
43
|
| `@heddleagent/execution-host-client/node` | Optional Node JWKS/conversation HTTP edge plus safe local signing-key helpers |
|
|
40
44
|
|
|
@@ -228,6 +232,50 @@ const productMcp = new NodeStreamableHttpMcpService({
|
|
|
228
232
|
Use the lower-level `NodeMcpToolset` interface only when a tool needs custom MCP
|
|
229
233
|
content or lifecycle semantics.
|
|
230
234
|
|
|
235
|
+
## Verify authority inside a compatible Execution Host
|
|
236
|
+
|
|
237
|
+
The host must independently verify the adopter's execution assertion before it
|
|
238
|
+
trusts product scope, then bind any optional MCP capability to that same
|
|
239
|
+
verified invocation. Compatible host implementations can reuse that generic
|
|
240
|
+
security boundary instead of maintaining their own JOSE logic:
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
import {
|
|
244
|
+
JwtExecutionHostMcpCapabilityVerifier,
|
|
245
|
+
JwtExecutionIdentityVerifier,
|
|
246
|
+
} from '@heddleagent/execution-host-client/host'
|
|
247
|
+
|
|
248
|
+
const identity = await new JwtExecutionIdentityVerifier({
|
|
249
|
+
executionIssuer: 'https://api.example.com',
|
|
250
|
+
executionAudience: 'heddle-execution-host',
|
|
251
|
+
executionJwksUrl: new URL('https://api.example.com/.well-known/jwks.json'),
|
|
252
|
+
executionJwtAlgorithms: ['ES256'],
|
|
253
|
+
trustedAdopterId: 'example-product',
|
|
254
|
+
maxAssertionAgeSeconds: 300,
|
|
255
|
+
assertionClockToleranceSeconds: 5,
|
|
256
|
+
}).verify({
|
|
257
|
+
assertion: executionAssertion,
|
|
258
|
+
runtimeSessionId,
|
|
259
|
+
invocationId,
|
|
260
|
+
workflow: 'conversation-turn',
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
const capability = await new JwtExecutionHostMcpCapabilityVerifier({
|
|
264
|
+
issuer: 'https://api.example.com',
|
|
265
|
+
audience: 'example-product-mcp',
|
|
266
|
+
jwksUrl: new URL('https://api.example.com/.well-known/jwks.json'),
|
|
267
|
+
jwtAlgorithms: ['ES256'],
|
|
268
|
+
trustedAdopterId: 'example-product',
|
|
269
|
+
serverId: 'product_capabilities',
|
|
270
|
+
maxCapabilityAgeSeconds: 900,
|
|
271
|
+
clockToleranceSeconds: 5,
|
|
272
|
+
}).verify({ assertion: mcpCapability, identity })
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
This surface owns credential verification and exact scope binding. It does not
|
|
276
|
+
own HTTP ingress, Runtime-session isolation, model credentials, streaming,
|
|
277
|
+
provider bootstrap, or deployment.
|
|
278
|
+
|
|
231
279
|
## Invoke an Execution Host
|
|
232
280
|
|
|
233
281
|
Use the official AgentCore client for a Runtime deployed in the adopter's AWS
|
|
@@ -279,30 +327,81 @@ The client refuses redirects, bounds parser and error bodies, validates ordered
|
|
|
279
327
|
SSE identity, streams accepted/activity events incrementally, and withholds the
|
|
280
328
|
terminal event until clean EOF. It never retries an ambiguous invocation.
|
|
281
329
|
|
|
282
|
-
##
|
|
330
|
+
## Connect a product to the heartbeat coordinator
|
|
331
|
+
|
|
332
|
+
The product publishes only its desired task state and authorizes individual
|
|
333
|
+
runs. Heddle owns the coordinator protocol, safe reconciliation order, Runtime
|
|
334
|
+
session derivation, short-lived authority bundle, and execution composition.
|
|
335
|
+
|
|
336
|
+
```ts
|
|
337
|
+
import {
|
|
338
|
+
HostedHeartbeatCoordinatorClient,
|
|
339
|
+
HostedHeartbeatDelegationService,
|
|
340
|
+
HostedHeartbeatTaskReconciler,
|
|
341
|
+
} from '@heddleagent/execution-host-client/coordinator'
|
|
342
|
+
import {
|
|
343
|
+
NodeHostedHeartbeatDelegationHttpService,
|
|
344
|
+
} from '@heddleagent/execution-host-client/coordinator/node'
|
|
345
|
+
|
|
346
|
+
const coordinator = new HostedHeartbeatCoordinatorClient({
|
|
347
|
+
baseUrl: coordinatorUrl,
|
|
348
|
+
apiToken: coordinatorApiToken,
|
|
349
|
+
})
|
|
350
|
+
await new HostedHeartbeatTaskReconciler({ coordinator }).reconcile({
|
|
351
|
+
desiredTasks: await projectDesiredHeartbeatTasks(),
|
|
352
|
+
resume: backgroundChecksEnabled,
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
const delegations = new HostedHeartbeatDelegationService({
|
|
356
|
+
authority,
|
|
357
|
+
runtimeSessionNamespace: 'example-product',
|
|
358
|
+
maxExecutionMs: 300_000,
|
|
359
|
+
authorizer: {
|
|
360
|
+
authorize: ({ taskId, signal }) =>
|
|
361
|
+
authorizeProductHeartbeat({ taskId, signal }),
|
|
362
|
+
},
|
|
363
|
+
})
|
|
364
|
+
const delegationHttp = new NodeHostedHeartbeatDelegationHttpService({
|
|
365
|
+
delegations,
|
|
366
|
+
apiToken: coordinatorDelegationToken,
|
|
367
|
+
})
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
`projectDesiredHeartbeatTasks` remains product-owned because it translates
|
|
371
|
+
product records into desired Heddle tasks. `authorizeProductHeartbeat` remains
|
|
372
|
+
product-owned because it decides whether the task may run and returns only the
|
|
373
|
+
authorized tenant/subject/product-session scope and exact MCP tool set. Product
|
|
374
|
+
code does not construct coordinator requests, Runtime-session IDs, deadlines,
|
|
375
|
+
JWTs, or delegation response objects.
|
|
376
|
+
|
|
377
|
+
The Node handler can be mounted before an existing router through
|
|
378
|
+
`delegationHttp.handle(request, response)`. See the
|
|
379
|
+
[coordinator boundary](src/coordinator/README.md) for the corresponding
|
|
380
|
+
coordinator-side client and execution transport.
|
|
381
|
+
|
|
382
|
+
## Compose the coordinator execution transport
|
|
283
383
|
|
|
284
384
|
For autonomous work, keep the durable task store and scheduler in one
|
|
285
385
|
long-running coordinator. Inject the hosted transport only at the point where
|
|
286
|
-
the scheduler would otherwise run the local heartbeat agent
|
|
386
|
+
the scheduler would otherwise run the local heartbeat agent. The coordinator
|
|
387
|
+
uses the product delegation endpoint rather than receiving product signing
|
|
388
|
+
keys or reimplementing its authority shape:
|
|
287
389
|
|
|
288
390
|
```ts
|
|
289
391
|
import { HeartbeatSchedulerService } from '@heddleagent/runtime/advanced'
|
|
290
392
|
import {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
} from '@heddleagent/execution-host-client/
|
|
393
|
+
HostedHeartbeatDelegatedExecutionTransport,
|
|
394
|
+
HostedHeartbeatDelegationClient,
|
|
395
|
+
} from '@heddleagent/execution-host-client/coordinator'
|
|
294
396
|
|
|
295
|
-
const
|
|
296
|
-
|
|
397
|
+
const delegations = new HostedHeartbeatDelegationClient({
|
|
398
|
+
baseUrl: productBackendUrl,
|
|
399
|
+
apiToken: productDelegationToken,
|
|
400
|
+
})
|
|
401
|
+
const agentExecutionTransport = new HostedHeartbeatDelegatedExecutionTransport({
|
|
402
|
+
delegations,
|
|
297
403
|
executionHost: agentCoreExecutionHost,
|
|
298
404
|
modelCredentials,
|
|
299
|
-
mcp: { allowedTools: ['read_workspace_snapshot'] },
|
|
300
|
-
})
|
|
301
|
-
const agentExecutionTransport = new HostedHeartbeatAgentExecutionTransport({
|
|
302
|
-
runner: hostedHeartbeat,
|
|
303
|
-
resolveInvocationContext: ({ taskId, executionId, signal }) => (
|
|
304
|
-
resolveAuthorizedHeartbeatInvocation({ taskId, executionId, signal })
|
|
305
|
-
),
|
|
306
405
|
})
|
|
307
406
|
|
|
308
407
|
const scheduler = HeartbeatSchedulerService.start({
|
|
@@ -311,11 +410,13 @@ const scheduler = HeartbeatSchedulerService.start({
|
|
|
311
410
|
})
|
|
312
411
|
```
|
|
313
412
|
|
|
314
|
-
The coordinator still owns task lookup, claims, checkpoint loading,
|
|
315
|
-
claim-fenced settlement, history, and recovery. The Runtime
|
|
316
|
-
task/checkpoint request plus invocation-scoped authority and
|
|
317
|
-
it receives no Heddle database credential. Omitting
|
|
318
|
-
preserves the existing in-process runner.
|
|
413
|
+
The coordinator still owns task lookup, claims, checkpoint loading,
|
|
414
|
+
cancellation, claim-fenced settlement, history, and recovery. The Runtime
|
|
415
|
+
receives a bounded task/checkpoint request plus invocation-scoped authority and
|
|
416
|
+
model credentials; it receives no Heddle database credential. Omitting
|
|
417
|
+
`agentExecutionTransport` preserves the existing in-process runner. The lower
|
|
418
|
+
level `/heartbeat` composition remains available for deployments whose
|
|
419
|
+
coordinator and product authority live in the same process.
|
|
319
420
|
|
|
320
421
|
## Verify an adopter integration locally
|
|
321
422
|
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const HOSTED_HEARTBEAT_COORDINATOR_PATHS: Readonly<{
|
|
3
|
+
tasks: "/v1/heartbeat/tasks";
|
|
4
|
+
pause: "/v1/control/pause";
|
|
5
|
+
resume: "/v1/control/resume";
|
|
6
|
+
}>;
|
|
7
|
+
export declare const HOSTED_HEARTBEAT_DELEGATIONS_PATH = "/hosted-execution/internal/heartbeat-delegations";
|
|
8
|
+
export declare const HostedHeartbeatCoordinatorTaskInputSchema: z.ZodObject<{
|
|
9
|
+
workspaceId: z.ZodOptional<z.ZodString>;
|
|
10
|
+
name: z.ZodOptional<z.ZodString>;
|
|
11
|
+
task: z.ZodString;
|
|
12
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
13
|
+
continuationMode: z.ZodOptional<z.ZodEnum<{
|
|
14
|
+
operator: "operator";
|
|
15
|
+
agent: "agent";
|
|
16
|
+
}>>;
|
|
17
|
+
intervalMs: z.ZodOptional<z.ZodNumber>;
|
|
18
|
+
defer: z.ZodOptional<z.ZodBoolean>;
|
|
19
|
+
model: z.ZodOptional<z.ZodString>;
|
|
20
|
+
maxSteps: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
searchIgnoreDirs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
22
|
+
systemContext: z.ZodOptional<z.ZodString>;
|
|
23
|
+
}, z.core.$strict>;
|
|
24
|
+
export declare const HostedHeartbeatCoordinatorTaskSummarySchema: z.ZodObject<{
|
|
25
|
+
id: z.ZodString;
|
|
26
|
+
workspaceId: z.ZodOptional<z.ZodString>;
|
|
27
|
+
}, z.core.$loose>;
|
|
28
|
+
export declare const HostedHeartbeatCoordinatorTaskListSchema: z.ZodObject<{
|
|
29
|
+
tasks: z.ZodArray<z.ZodObject<{
|
|
30
|
+
id: z.ZodString;
|
|
31
|
+
workspaceId: z.ZodOptional<z.ZodString>;
|
|
32
|
+
}, z.core.$loose>>;
|
|
33
|
+
}, z.core.$strict>;
|
|
34
|
+
export declare const HostedHeartbeatDesiredTaskSchema: z.ZodObject<{
|
|
35
|
+
taskId: z.ZodString;
|
|
36
|
+
input: z.ZodObject<{
|
|
37
|
+
workspaceId: z.ZodOptional<z.ZodString>;
|
|
38
|
+
name: z.ZodOptional<z.ZodString>;
|
|
39
|
+
task: z.ZodString;
|
|
40
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
41
|
+
continuationMode: z.ZodOptional<z.ZodEnum<{
|
|
42
|
+
operator: "operator";
|
|
43
|
+
agent: "agent";
|
|
44
|
+
}>>;
|
|
45
|
+
intervalMs: z.ZodOptional<z.ZodNumber>;
|
|
46
|
+
defer: z.ZodOptional<z.ZodBoolean>;
|
|
47
|
+
model: z.ZodOptional<z.ZodString>;
|
|
48
|
+
maxSteps: z.ZodOptional<z.ZodNumber>;
|
|
49
|
+
searchIgnoreDirs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
50
|
+
systemContext: z.ZodOptional<z.ZodString>;
|
|
51
|
+
}, z.core.$strict>;
|
|
52
|
+
}, z.core.$strict>;
|
|
53
|
+
export declare const HostedHeartbeatDesiredTaskCatalogSchema: z.ZodObject<{
|
|
54
|
+
tasks: z.ZodArray<z.ZodObject<{
|
|
55
|
+
taskId: z.ZodString;
|
|
56
|
+
input: z.ZodObject<{
|
|
57
|
+
workspaceId: z.ZodOptional<z.ZodString>;
|
|
58
|
+
name: z.ZodOptional<z.ZodString>;
|
|
59
|
+
task: z.ZodString;
|
|
60
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
61
|
+
continuationMode: z.ZodOptional<z.ZodEnum<{
|
|
62
|
+
operator: "operator";
|
|
63
|
+
agent: "agent";
|
|
64
|
+
}>>;
|
|
65
|
+
intervalMs: z.ZodOptional<z.ZodNumber>;
|
|
66
|
+
defer: z.ZodOptional<z.ZodBoolean>;
|
|
67
|
+
model: z.ZodOptional<z.ZodString>;
|
|
68
|
+
maxSteps: z.ZodOptional<z.ZodNumber>;
|
|
69
|
+
searchIgnoreDirs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
70
|
+
systemContext: z.ZodOptional<z.ZodString>;
|
|
71
|
+
}, z.core.$strict>;
|
|
72
|
+
}, z.core.$strict>>;
|
|
73
|
+
resume: z.ZodBoolean;
|
|
74
|
+
}, z.core.$strict>;
|
|
75
|
+
export declare const HostedHeartbeatDelegationRequestSchema: z.ZodObject<{
|
|
76
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
77
|
+
taskId: z.ZodString;
|
|
78
|
+
executionId: z.ZodString;
|
|
79
|
+
}, z.core.$strict>;
|
|
80
|
+
export declare const HostedHeartbeatDelegationSchema: z.ZodObject<{
|
|
81
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
82
|
+
taskId: z.ZodString;
|
|
83
|
+
executionId: z.ZodString;
|
|
84
|
+
scope: z.ZodObject<{
|
|
85
|
+
tenantId: z.ZodString;
|
|
86
|
+
subjectId: z.ZodString;
|
|
87
|
+
productSessionId: z.ZodString;
|
|
88
|
+
}, z.core.$strict>;
|
|
89
|
+
runtimeSessionId: z.ZodString;
|
|
90
|
+
deadlineAt: z.ZodISODateTime;
|
|
91
|
+
authority: z.ZodObject<{
|
|
92
|
+
metadata: z.ZodObject<{
|
|
93
|
+
scope: z.ZodObject<{
|
|
94
|
+
adopterId: z.ZodString;
|
|
95
|
+
tenantId: z.ZodString;
|
|
96
|
+
subjectId: z.ZodString;
|
|
97
|
+
productSessionId: z.ZodString;
|
|
98
|
+
}, z.core.$strict>;
|
|
99
|
+
runtimeSessionId: z.ZodString;
|
|
100
|
+
invocationId: z.ZodString;
|
|
101
|
+
workflow: z.ZodLiteral<"heartbeat-task">;
|
|
102
|
+
issuedAt: z.ZodISODateTime;
|
|
103
|
+
executionExpiresAt: z.ZodISODateTime;
|
|
104
|
+
mcp: z.ZodObject<{
|
|
105
|
+
capabilityId: z.ZodString;
|
|
106
|
+
serverId: z.ZodString;
|
|
107
|
+
allowedTools: z.ZodArray<z.ZodString>;
|
|
108
|
+
expiresAt: z.ZodISODateTime;
|
|
109
|
+
}, z.core.$strict>;
|
|
110
|
+
}, z.core.$strict>;
|
|
111
|
+
executionAssertion: z.ZodString;
|
|
112
|
+
mcpCapability: z.ZodString;
|
|
113
|
+
}, z.core.$strict>;
|
|
114
|
+
}, z.core.$strict>;
|
|
115
|
+
export declare const HostedHeartbeatDelegationAuthorizationSchema: z.ZodObject<{
|
|
116
|
+
scope: z.ZodObject<{
|
|
117
|
+
tenantId: z.ZodString;
|
|
118
|
+
subjectId: z.ZodString;
|
|
119
|
+
productSessionId: z.ZodString;
|
|
120
|
+
}, z.core.$strict>;
|
|
121
|
+
allowedTools: z.ZodArray<z.ZodString>;
|
|
122
|
+
}, z.core.$strict>;
|
|
123
|
+
export type HostedHeartbeatCoordinatorTaskInput = z.infer<typeof HostedHeartbeatCoordinatorTaskInputSchema>;
|
|
124
|
+
export type HostedHeartbeatCoordinatorTaskSummary = z.infer<typeof HostedHeartbeatCoordinatorTaskSummarySchema>;
|
|
125
|
+
export type HostedHeartbeatDesiredTask = z.infer<typeof HostedHeartbeatDesiredTaskSchema>;
|
|
126
|
+
export type HostedHeartbeatDesiredTaskCatalog = z.infer<typeof HostedHeartbeatDesiredTaskCatalogSchema>;
|
|
127
|
+
export type HostedHeartbeatDelegationRequest = z.infer<typeof HostedHeartbeatDelegationRequestSchema>;
|
|
128
|
+
export type HostedHeartbeatDelegation = z.infer<typeof HostedHeartbeatDelegationSchema>;
|
|
129
|
+
export type HostedHeartbeatDelegationAuthorization = z.infer<typeof HostedHeartbeatDelegationAuthorizationSchema>;
|
|
130
|
+
//# sourceMappingURL=contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/coordinator/contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAexB,eAAO,MAAM,kCAAkC;;;;EAI7C,CAAC;AAEH,eAAO,MAAM,iCAAiC,qDACM,CAAC;AAErD,eAAO,MAAM,yCAAyC;;;;;;;;;;;;;;;kBAc3C,CAAC;AAEZ,eAAO,MAAM,2CAA2C;;;iBAGxC,CAAC;AAEjB,eAAO,MAAM,wCAAwC;;;;;kBAE1C,CAAC;AAEZ,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;kBAGlC,CAAC;AAEZ,eAAO,MAAM,uCAAuC;;;;;;;;;;;;;;;;;;;;;kBAelD,CAAC;AAEH,eAAO,MAAM,sCAAsC;;;;kBAIxC,CAAC;AAiBZ,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA6B1C,CAAC;AAEH,eAAO,MAAM,4CAA4C;;;;;;;kBAG9C,CAAC;AAEZ,MAAM,MAAM,mCAAmC,GAAG,CAAC,CAAC,KAAK,CACvD,OAAO,yCAAyC,CACjD,CAAC;AACF,MAAM,MAAM,qCAAqC,GAAG,CAAC,CAAC,KAAK,CACzD,OAAO,2CAA2C,CACnD,CAAC;AACF,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAC9C,OAAO,gCAAgC,CACxC,CAAC;AACF,MAAM,MAAM,iCAAiC,GAAG,CAAC,CAAC,KAAK,CACrD,OAAO,uCAAuC,CAC/C,CAAC;AACF,MAAM,MAAM,gCAAgC,GAAG,CAAC,CAAC,KAAK,CACpD,OAAO,sCAAsC,CAC9C,CAAC;AACF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAC7C,OAAO,+BAA+B,CACvC,CAAC;AACF,MAAM,MAAM,sCAAsC,GAAG,CAAC,CAAC,KAAK,CAC1D,OAAO,4CAA4C,CACpD,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ExecutionScopeSchema, HEARTBEAT_TASK_WORKFLOW, McpAllowedToolsSchema, McpServerIdSchema, OpaqueIdSchema, RuntimeSessionIdSchema, TimestampSchema, } from '../contracts/index.js';
|
|
3
|
+
const ProductExecutionScopeSchema = ExecutionScopeSchema.omit({
|
|
4
|
+
adopterId: true,
|
|
5
|
+
});
|
|
6
|
+
export const HOSTED_HEARTBEAT_COORDINATOR_PATHS = Object.freeze({
|
|
7
|
+
tasks: '/v1/heartbeat/tasks',
|
|
8
|
+
pause: '/v1/control/pause',
|
|
9
|
+
resume: '/v1/control/resume',
|
|
10
|
+
});
|
|
11
|
+
export const HOSTED_HEARTBEAT_DELEGATIONS_PATH = '/hosted-execution/internal/heartbeat-delegations';
|
|
12
|
+
export const HostedHeartbeatCoordinatorTaskInputSchema = z.object({
|
|
13
|
+
workspaceId: OpaqueIdSchema.optional(),
|
|
14
|
+
name: z.string().trim().min(1).max(200).optional(),
|
|
15
|
+
task: z.string().trim().min(1).max(200_000),
|
|
16
|
+
enabled: z.boolean().optional(),
|
|
17
|
+
continuationMode: z.enum(['operator', 'agent']).optional(),
|
|
18
|
+
intervalMs: z.number().int().min(1_000).max(Number.MAX_SAFE_INTEGER)
|
|
19
|
+
.optional(),
|
|
20
|
+
defer: z.boolean().optional(),
|
|
21
|
+
model: z.string().trim().min(1).max(512).optional(),
|
|
22
|
+
maxSteps: z.number().int().positive().max(10_000).optional(),
|
|
23
|
+
searchIgnoreDirs: z.array(z.string().min(1).max(1_024)).max(1_000)
|
|
24
|
+
.optional(),
|
|
25
|
+
systemContext: z.string().max(200_000).optional(),
|
|
26
|
+
}).strict();
|
|
27
|
+
export const HostedHeartbeatCoordinatorTaskSummarySchema = z.object({
|
|
28
|
+
id: OpaqueIdSchema,
|
|
29
|
+
workspaceId: OpaqueIdSchema.optional(),
|
|
30
|
+
}).passthrough();
|
|
31
|
+
export const HostedHeartbeatCoordinatorTaskListSchema = z.object({
|
|
32
|
+
tasks: z.array(HostedHeartbeatCoordinatorTaskSummarySchema),
|
|
33
|
+
}).strict();
|
|
34
|
+
export const HostedHeartbeatDesiredTaskSchema = z.object({
|
|
35
|
+
taskId: OpaqueIdSchema,
|
|
36
|
+
input: HostedHeartbeatCoordinatorTaskInputSchema,
|
|
37
|
+
}).strict();
|
|
38
|
+
export const HostedHeartbeatDesiredTaskCatalogSchema = z.object({
|
|
39
|
+
tasks: z.array(HostedHeartbeatDesiredTaskSchema).max(10_000),
|
|
40
|
+
resume: z.boolean(),
|
|
41
|
+
}).strict().superRefine(({ tasks }, context) => {
|
|
42
|
+
const seen = new Set();
|
|
43
|
+
tasks.forEach(({ taskId }, index) => {
|
|
44
|
+
if (seen.has(taskId)) {
|
|
45
|
+
context.addIssue({
|
|
46
|
+
code: 'custom',
|
|
47
|
+
path: ['tasks', index, 'taskId'],
|
|
48
|
+
message: 'must be unique within the desired task catalog',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
seen.add(taskId);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
export const HostedHeartbeatDelegationRequestSchema = z.object({
|
|
55
|
+
schemaVersion: z.literal(1),
|
|
56
|
+
taskId: OpaqueIdSchema,
|
|
57
|
+
executionId: OpaqueIdSchema,
|
|
58
|
+
}).strict();
|
|
59
|
+
const DelegatedAuthorityMetadataSchema = z.object({
|
|
60
|
+
scope: ExecutionScopeSchema,
|
|
61
|
+
runtimeSessionId: RuntimeSessionIdSchema,
|
|
62
|
+
invocationId: OpaqueIdSchema,
|
|
63
|
+
workflow: z.literal(HEARTBEAT_TASK_WORKFLOW),
|
|
64
|
+
issuedAt: TimestampSchema,
|
|
65
|
+
executionExpiresAt: TimestampSchema,
|
|
66
|
+
mcp: z.object({
|
|
67
|
+
capabilityId: OpaqueIdSchema,
|
|
68
|
+
serverId: McpServerIdSchema,
|
|
69
|
+
allowedTools: McpAllowedToolsSchema,
|
|
70
|
+
expiresAt: TimestampSchema,
|
|
71
|
+
}).strict(),
|
|
72
|
+
}).strict();
|
|
73
|
+
export const HostedHeartbeatDelegationSchema = z.object({
|
|
74
|
+
schemaVersion: z.literal(1),
|
|
75
|
+
taskId: OpaqueIdSchema,
|
|
76
|
+
executionId: OpaqueIdSchema,
|
|
77
|
+
scope: ProductExecutionScopeSchema,
|
|
78
|
+
runtimeSessionId: RuntimeSessionIdSchema,
|
|
79
|
+
deadlineAt: TimestampSchema,
|
|
80
|
+
authority: z.object({
|
|
81
|
+
metadata: DelegatedAuthorityMetadataSchema,
|
|
82
|
+
executionAssertion: z.string().min(1).max(16_384),
|
|
83
|
+
mcpCapability: z.string().min(1).max(16_384),
|
|
84
|
+
}).strict(),
|
|
85
|
+
}).strict().superRefine((delegation, context) => {
|
|
86
|
+
const metadata = delegation.authority.metadata;
|
|
87
|
+
const mismatches = [
|
|
88
|
+
['executionId', metadata.invocationId !== delegation.executionId],
|
|
89
|
+
[
|
|
90
|
+
'runtimeSessionId',
|
|
91
|
+
metadata.runtimeSessionId !== delegation.runtimeSessionId,
|
|
92
|
+
],
|
|
93
|
+
['scope', !sameProductScope(metadata.scope, delegation.scope)],
|
|
94
|
+
];
|
|
95
|
+
mismatches
|
|
96
|
+
.filter(([, mismatched]) => mismatched)
|
|
97
|
+
.forEach(([path]) => context.addIssue({
|
|
98
|
+
code: 'custom',
|
|
99
|
+
path: [path],
|
|
100
|
+
message: 'must match the delegated execution authority metadata',
|
|
101
|
+
}));
|
|
102
|
+
});
|
|
103
|
+
export const HostedHeartbeatDelegationAuthorizationSchema = z.object({
|
|
104
|
+
scope: ProductExecutionScopeSchema,
|
|
105
|
+
allowedTools: McpAllowedToolsSchema,
|
|
106
|
+
}).strict();
|
|
107
|
+
function sameProductScope(left, right) {
|
|
108
|
+
return left.tenantId === right.tenantId
|
|
109
|
+
&& left.subjectId === right.subjectId
|
|
110
|
+
&& left.productSessionId === right.productSessionId;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/coordinator/contracts.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {\n ExecutionScopeSchema,\n HEARTBEAT_TASK_WORKFLOW,\n McpAllowedToolsSchema,\n McpServerIdSchema,\n OpaqueIdSchema,\n RuntimeSessionIdSchema,\n TimestampSchema,\n} from '../contracts/index.js';\n\nconst ProductExecutionScopeSchema = ExecutionScopeSchema.omit({\n adopterId: true,\n});\n\nexport const HOSTED_HEARTBEAT_COORDINATOR_PATHS = Object.freeze({\n tasks: '/v1/heartbeat/tasks',\n pause: '/v1/control/pause',\n resume: '/v1/control/resume',\n});\n\nexport const HOSTED_HEARTBEAT_DELEGATIONS_PATH =\n '/hosted-execution/internal/heartbeat-delegations';\n\nexport const HostedHeartbeatCoordinatorTaskInputSchema = z.object({\n workspaceId: OpaqueIdSchema.optional(),\n name: z.string().trim().min(1).max(200).optional(),\n task: z.string().trim().min(1).max(200_000),\n enabled: z.boolean().optional(),\n continuationMode: z.enum(['operator', 'agent']).optional(),\n intervalMs: z.number().int().min(1_000).max(Number.MAX_SAFE_INTEGER)\n .optional(),\n defer: z.boolean().optional(),\n model: z.string().trim().min(1).max(512).optional(),\n maxSteps: z.number().int().positive().max(10_000).optional(),\n searchIgnoreDirs: z.array(z.string().min(1).max(1_024)).max(1_000)\n .optional(),\n systemContext: z.string().max(200_000).optional(),\n}).strict();\n\nexport const HostedHeartbeatCoordinatorTaskSummarySchema = z.object({\n id: OpaqueIdSchema,\n workspaceId: OpaqueIdSchema.optional(),\n}).passthrough();\n\nexport const HostedHeartbeatCoordinatorTaskListSchema = z.object({\n tasks: z.array(HostedHeartbeatCoordinatorTaskSummarySchema),\n}).strict();\n\nexport const HostedHeartbeatDesiredTaskSchema = z.object({\n taskId: OpaqueIdSchema,\n input: HostedHeartbeatCoordinatorTaskInputSchema,\n}).strict();\n\nexport const HostedHeartbeatDesiredTaskCatalogSchema = z.object({\n tasks: z.array(HostedHeartbeatDesiredTaskSchema).max(10_000),\n resume: z.boolean(),\n}).strict().superRefine(({ tasks }, context) => {\n const seen = new Set<string>();\n tasks.forEach(({ taskId }, index) => {\n if (seen.has(taskId)) {\n context.addIssue({\n code: 'custom',\n path: ['tasks', index, 'taskId'],\n message: 'must be unique within the desired task catalog',\n });\n }\n seen.add(taskId);\n });\n});\n\nexport const HostedHeartbeatDelegationRequestSchema = z.object({\n schemaVersion: z.literal(1),\n taskId: OpaqueIdSchema,\n executionId: OpaqueIdSchema,\n}).strict();\n\nconst DelegatedAuthorityMetadataSchema = z.object({\n scope: ExecutionScopeSchema,\n runtimeSessionId: RuntimeSessionIdSchema,\n invocationId: OpaqueIdSchema,\n workflow: z.literal(HEARTBEAT_TASK_WORKFLOW),\n issuedAt: TimestampSchema,\n executionExpiresAt: TimestampSchema,\n mcp: z.object({\n capabilityId: OpaqueIdSchema,\n serverId: McpServerIdSchema,\n allowedTools: McpAllowedToolsSchema,\n expiresAt: TimestampSchema,\n }).strict(),\n}).strict();\n\nexport const HostedHeartbeatDelegationSchema = z.object({\n schemaVersion: z.literal(1),\n taskId: OpaqueIdSchema,\n executionId: OpaqueIdSchema,\n scope: ProductExecutionScopeSchema,\n runtimeSessionId: RuntimeSessionIdSchema,\n deadlineAt: TimestampSchema,\n authority: z.object({\n metadata: DelegatedAuthorityMetadataSchema,\n executionAssertion: z.string().min(1).max(16_384),\n mcpCapability: z.string().min(1).max(16_384),\n }).strict(),\n}).strict().superRefine((delegation, context) => {\n const metadata = delegation.authority.metadata;\n const mismatches: Array<[path: string, mismatched: boolean]> = [\n ['executionId', metadata.invocationId !== delegation.executionId],\n [\n 'runtimeSessionId',\n metadata.runtimeSessionId !== delegation.runtimeSessionId,\n ],\n ['scope', !sameProductScope(metadata.scope, delegation.scope)],\n ];\n mismatches\n .filter(([, mismatched]) => mismatched)\n .forEach(([path]) => context.addIssue({\n code: 'custom',\n path: [path],\n message: 'must match the delegated execution authority metadata',\n }));\n});\n\nexport const HostedHeartbeatDelegationAuthorizationSchema = z.object({\n scope: ProductExecutionScopeSchema,\n allowedTools: McpAllowedToolsSchema,\n}).strict();\n\nexport type HostedHeartbeatCoordinatorTaskInput = z.infer<\n typeof HostedHeartbeatCoordinatorTaskInputSchema\n>;\nexport type HostedHeartbeatCoordinatorTaskSummary = z.infer<\n typeof HostedHeartbeatCoordinatorTaskSummarySchema\n>;\nexport type HostedHeartbeatDesiredTask = z.infer<\n typeof HostedHeartbeatDesiredTaskSchema\n>;\nexport type HostedHeartbeatDesiredTaskCatalog = z.infer<\n typeof HostedHeartbeatDesiredTaskCatalogSchema\n>;\nexport type HostedHeartbeatDelegationRequest = z.infer<\n typeof HostedHeartbeatDelegationRequestSchema\n>;\nexport type HostedHeartbeatDelegation = z.infer<\n typeof HostedHeartbeatDelegationSchema\n>;\nexport type HostedHeartbeatDelegationAuthorization = z.infer<\n typeof HostedHeartbeatDelegationAuthorizationSchema\n>;\n\nfunction sameProductScope(\n left: z.infer<typeof ExecutionScopeSchema>,\n right: z.infer<typeof ProductExecutionScopeSchema>,\n): boolean {\n return left.tenantId === right.tenantId\n && left.subjectId === right.subjectId\n && left.productSessionId === right.productSessionId;\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type HostedHeartbeatCoordinatorTaskInput, type HostedHeartbeatCoordinatorTaskSummary } from './contracts.js';
|
|
2
|
+
import type { HostedHeartbeatCoordinatorClientConfig, HostedHeartbeatCoordinatorTaskApi } from './types.js';
|
|
3
|
+
export declare class HostedHeartbeatCoordinatorRequestError extends Error {
|
|
4
|
+
readonly method: string;
|
|
5
|
+
readonly path: string;
|
|
6
|
+
readonly status: number;
|
|
7
|
+
readonly name = "HostedHeartbeatCoordinatorRequestError";
|
|
8
|
+
constructor(method: string, path: string, status: number);
|
|
9
|
+
}
|
|
10
|
+
/** Authenticated desired-task and admission client for a Heddle Coordinator. */
|
|
11
|
+
export declare class HostedHeartbeatCoordinatorClient implements HostedHeartbeatCoordinatorTaskApi {
|
|
12
|
+
#private;
|
|
13
|
+
constructor(config: HostedHeartbeatCoordinatorClientConfig);
|
|
14
|
+
listTasks(signal?: AbortSignal): Promise<HostedHeartbeatCoordinatorTaskSummary[]>;
|
|
15
|
+
upsertTask(rawTaskId: string, rawTask: HostedHeartbeatCoordinatorTaskInput, signal?: AbortSignal): Promise<void>;
|
|
16
|
+
deleteTask(rawTaskId: string, signal?: AbortSignal): Promise<void>;
|
|
17
|
+
pause(signal?: AbortSignal): Promise<void>;
|
|
18
|
+
resume(signal?: AbortSignal): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=hosted-heartbeat-coordinator-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-heartbeat-coordinator-client.d.ts","sourceRoot":"","sources":["../../src/coordinator/hosted-heartbeat-coordinator-client.ts"],"names":[],"mappings":"AAKA,OAAO,EAIL,KAAK,mCAAmC,EACxC,KAAK,qCAAqC,EAC3C,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EACV,sCAAsC,EACtC,iCAAiC,EAClC,MAAM,YAAY,CAAC;AAOpB,qBAAa,sCAAuC,SAAQ,KAAK;IAI7D,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM;IALzB,QAAQ,CAAC,IAAI,4CAA4C;gBAG9C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM;CAI1B;AAED,gFAAgF;AAChF,qBAAa,gCACb,YAAW,iCAAiC;;gBAK9B,MAAM,EAAE,sCAAsC;IAQpD,SAAS,CACb,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,qCAAqC,EAAE,CAAC;IAU7C,UAAU,CACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,mCAAmC,EAC5C,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC;IAWV,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlE,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAO1C,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CA8BlD"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { OpaqueIdSchema, isSafeWebUrl, } from '../contracts/index.js';
|
|
3
|
+
import { HOSTED_HEARTBEAT_COORDINATOR_PATHS, HostedHeartbeatCoordinatorTaskInputSchema, HostedHeartbeatCoordinatorTaskListSchema, } from './contracts.js';
|
|
4
|
+
import { HostedHeartbeatServiceTokenSchema } from './service-token.js';
|
|
5
|
+
const SafeBaseUrlSchema = z.custom((value) => value instanceof URL && isSafeWebUrl(value), 'baseUrl must be a safe HTTPS or loopback HTTP URL');
|
|
6
|
+
export class HostedHeartbeatCoordinatorRequestError extends Error {
|
|
7
|
+
method;
|
|
8
|
+
path;
|
|
9
|
+
status;
|
|
10
|
+
name = 'HostedHeartbeatCoordinatorRequestError';
|
|
11
|
+
constructor(method, path, status) {
|
|
12
|
+
super(`Heddle Coordinator ${method} ${path} failed with status ${status}.`);
|
|
13
|
+
this.method = method;
|
|
14
|
+
this.path = path;
|
|
15
|
+
this.status = status;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** Authenticated desired-task and admission client for a Heddle Coordinator. */
|
|
19
|
+
export class HostedHeartbeatCoordinatorClient {
|
|
20
|
+
#baseUrl;
|
|
21
|
+
#authorization;
|
|
22
|
+
#fetch;
|
|
23
|
+
constructor(config) {
|
|
24
|
+
this.#baseUrl = new URL(SafeBaseUrlSchema.parse(config.baseUrl));
|
|
25
|
+
this.#authorization = `Bearer ${HostedHeartbeatServiceTokenSchema.parse(config.apiToken)}`;
|
|
26
|
+
this.#fetch = config.fetch ?? globalThis.fetch;
|
|
27
|
+
}
|
|
28
|
+
async listTasks(signal) {
|
|
29
|
+
const response = await this.#request(HOSTED_HEARTBEAT_COORDINATOR_PATHS.tasks, { method: 'GET', signal });
|
|
30
|
+
return HostedHeartbeatCoordinatorTaskListSchema.parse(await response.json()).tasks;
|
|
31
|
+
}
|
|
32
|
+
async upsertTask(rawTaskId, rawTask, signal) {
|
|
33
|
+
const taskId = OpaqueIdSchema.parse(rawTaskId);
|
|
34
|
+
const task = HostedHeartbeatCoordinatorTaskInputSchema.parse(rawTask);
|
|
35
|
+
await this.#request(this.#taskPath(taskId), {
|
|
36
|
+
method: 'PUT',
|
|
37
|
+
headers: { 'content-type': 'application/json' },
|
|
38
|
+
body: JSON.stringify(task),
|
|
39
|
+
signal,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
async deleteTask(rawTaskId, signal) {
|
|
43
|
+
await this.#request(this.#taskPath(OpaqueIdSchema.parse(rawTaskId)), {
|
|
44
|
+
method: 'DELETE',
|
|
45
|
+
signal,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async pause(signal) {
|
|
49
|
+
await this.#request(HOSTED_HEARTBEAT_COORDINATOR_PATHS.pause, {
|
|
50
|
+
method: 'POST',
|
|
51
|
+
signal,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
async resume(signal) {
|
|
55
|
+
await this.#request(HOSTED_HEARTBEAT_COORDINATOR_PATHS.resume, {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
signal,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
#taskPath(taskId) {
|
|
61
|
+
return `${HOSTED_HEARTBEAT_COORDINATOR_PATHS.tasks}/${encodeURIComponent(taskId)}`;
|
|
62
|
+
}
|
|
63
|
+
async #request(path, init) {
|
|
64
|
+
const headers = new Headers(init.headers);
|
|
65
|
+
headers.set('authorization', this.#authorization);
|
|
66
|
+
const response = await this.#fetch(new URL(path, this.#baseUrl), {
|
|
67
|
+
...init,
|
|
68
|
+
headers,
|
|
69
|
+
redirect: 'error',
|
|
70
|
+
});
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
throw new HostedHeartbeatCoordinatorRequestError(init.method ?? 'GET', path, response.status);
|
|
73
|
+
}
|
|
74
|
+
return response;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=hosted-heartbeat-coordinator-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-heartbeat-coordinator-client.js","sourceRoot":"","sources":["../../src/coordinator/hosted-heartbeat-coordinator-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {\n OpaqueIdSchema,\n isSafeWebUrl,\n} from '../contracts/index.js';\nimport {\n HOSTED_HEARTBEAT_COORDINATOR_PATHS,\n HostedHeartbeatCoordinatorTaskInputSchema,\n HostedHeartbeatCoordinatorTaskListSchema,\n type HostedHeartbeatCoordinatorTaskInput,\n type HostedHeartbeatCoordinatorTaskSummary,\n} from './contracts.js';\nimport { HostedHeartbeatServiceTokenSchema } from './service-token.js';\nimport type {\n HostedHeartbeatCoordinatorClientConfig,\n HostedHeartbeatCoordinatorTaskApi,\n} from './types.js';\n\nconst SafeBaseUrlSchema = z.custom<URL>(\n (value) => value instanceof URL && isSafeWebUrl(value),\n 'baseUrl must be a safe HTTPS or loopback HTTP URL',\n);\n\nexport class HostedHeartbeatCoordinatorRequestError extends Error {\n readonly name = 'HostedHeartbeatCoordinatorRequestError';\n\n constructor(\n readonly method: string,\n readonly path: string,\n readonly status: number,\n ) {\n super(`Heddle Coordinator ${method} ${path} failed with status ${status}.`);\n }\n}\n\n/** Authenticated desired-task and admission client for a Heddle Coordinator. */\nexport class HostedHeartbeatCoordinatorClient\nimplements HostedHeartbeatCoordinatorTaskApi {\n readonly #baseUrl: URL;\n readonly #authorization: string;\n readonly #fetch: typeof globalThis.fetch;\n\n constructor(config: HostedHeartbeatCoordinatorClientConfig) {\n this.#baseUrl = new URL(SafeBaseUrlSchema.parse(config.baseUrl));\n this.#authorization = `Bearer ${\n HostedHeartbeatServiceTokenSchema.parse(config.apiToken)\n }`;\n this.#fetch = config.fetch ?? globalThis.fetch;\n }\n\n async listTasks(\n signal?: AbortSignal,\n ): Promise<HostedHeartbeatCoordinatorTaskSummary[]> {\n const response = await this.#request(\n HOSTED_HEARTBEAT_COORDINATOR_PATHS.tasks,\n { method: 'GET', signal },\n );\n return HostedHeartbeatCoordinatorTaskListSchema.parse(\n await response.json(),\n ).tasks;\n }\n\n async upsertTask(\n rawTaskId: string,\n rawTask: HostedHeartbeatCoordinatorTaskInput,\n signal?: AbortSignal,\n ): Promise<void> {\n const taskId = OpaqueIdSchema.parse(rawTaskId);\n const task = HostedHeartbeatCoordinatorTaskInputSchema.parse(rawTask);\n await this.#request(this.#taskPath(taskId), {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(task),\n signal,\n });\n }\n\n async deleteTask(rawTaskId: string, signal?: AbortSignal): Promise<void> {\n await this.#request(this.#taskPath(OpaqueIdSchema.parse(rawTaskId)), {\n method: 'DELETE',\n signal,\n });\n }\n\n async pause(signal?: AbortSignal): Promise<void> {\n await this.#request(HOSTED_HEARTBEAT_COORDINATOR_PATHS.pause, {\n method: 'POST',\n signal,\n });\n }\n\n async resume(signal?: AbortSignal): Promise<void> {\n await this.#request(HOSTED_HEARTBEAT_COORDINATOR_PATHS.resume, {\n method: 'POST',\n signal,\n });\n }\n\n #taskPath(taskId: string): string {\n return `${HOSTED_HEARTBEAT_COORDINATOR_PATHS.tasks}/${\n encodeURIComponent(taskId)\n }`;\n }\n\n async #request(path: string, init: RequestInit): Promise<Response> {\n const headers = new Headers(init.headers);\n headers.set('authorization', this.#authorization);\n const response = await this.#fetch(new URL(path, this.#baseUrl), {\n ...init,\n headers,\n redirect: 'error',\n });\n if (!response.ok) {\n throw new HostedHeartbeatCoordinatorRequestError(\n init.method ?? 'GET',\n path,\n response.status,\n );\n }\n return response;\n }\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type HostedHeartbeatAgentExecutionTransportInput } from '../heartbeat/index.js';
|
|
2
|
+
import { type HostedHeartbeatDelegation, type HostedHeartbeatDelegationRequest } from './contracts.js';
|
|
3
|
+
import type { HostedHeartbeatDelegatedExecutionTransportConfig, HostedHeartbeatDelegatedExecutionTransportPort, HostedHeartbeatDelegationClientConfig, HostedHeartbeatDelegationIssuer } from './types.js';
|
|
4
|
+
export declare class HostedHeartbeatDelegationRequestError extends Error {
|
|
5
|
+
readonly status: number;
|
|
6
|
+
readonly name = "HostedHeartbeatDelegationRequestError";
|
|
7
|
+
constructor(status: number);
|
|
8
|
+
}
|
|
9
|
+
/** Authenticated coordinator client for one product-issued authority bundle. */
|
|
10
|
+
export declare class HostedHeartbeatDelegationClient implements HostedHeartbeatDelegationIssuer {
|
|
11
|
+
#private;
|
|
12
|
+
constructor(config: HostedHeartbeatDelegationClientConfig);
|
|
13
|
+
issue(rawInput: HostedHeartbeatDelegationRequest, signal?: AbortSignal): Promise<HostedHeartbeatDelegation>;
|
|
14
|
+
}
|
|
15
|
+
/** Executes a claimed task with the exact product-issued authority bundle. */
|
|
16
|
+
export declare class HostedHeartbeatDelegatedExecutionTransport implements HostedHeartbeatDelegatedExecutionTransportPort {
|
|
17
|
+
#private;
|
|
18
|
+
constructor(config: HostedHeartbeatDelegatedExecutionTransportConfig);
|
|
19
|
+
execute(input: HostedHeartbeatAgentExecutionTransportInput): Promise<unknown>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=hosted-heartbeat-delegation-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-heartbeat-delegation-client.d.ts","sourceRoot":"","sources":["../../src/coordinator/hosted-heartbeat-delegation-client.ts"],"names":[],"mappings":"AAWA,OAAO,EAGL,KAAK,2CAA2C,EACjD,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAIL,KAAK,yBAAyB,EAC9B,KAAK,gCAAgC,EACtC,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EACV,gDAAgD,EAChD,8CAA8C,EAC9C,qCAAqC,EACrC,+BAA+B,EAChC,MAAM,YAAY,CAAC;AAWpB,qBAAa,qCAAsC,SAAQ,KAAK;IAGlD,QAAQ,CAAC,MAAM,EAAE,MAAM;IAFnC,QAAQ,CAAC,IAAI,2CAA2C;gBAEnC,MAAM,EAAE,MAAM;CAGpC;AAED,gFAAgF;AAChF,qBAAa,+BACb,YAAW,+BAA+B;;gBAK5B,MAAM,EAAE,qCAAqC;IAcnD,KAAK,CACT,QAAQ,EAAE,gCAAgC,EAC1C,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,yBAAyB,CAAC;CA4BtC;AAED,8EAA8E;AAC9E,qBAAa,0CACb,YAAW,8CAA8C;;gBAG3C,MAAM,EAAE,gDAAgD;IAI9D,OAAO,CACX,KAAK,EAAE,2CAA2C,GACjD,OAAO,CAAC,OAAO,CAAC;CAwBpB"}
|