@heddleagent/execution-host-client 7.0.0 → 8.0.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 (79) hide show
  1. package/README.md +48 -34
  2. package/dist/cli/hostctl.d.ts +11 -0
  3. package/dist/cli/hostctl.d.ts.map +1 -0
  4. package/dist/cli/hostctl.js +62 -0
  5. package/dist/cli/hostctl.js.map +1 -0
  6. package/dist/contracts/index.d.ts +2 -0
  7. package/dist/contracts/index.d.ts.map +1 -1
  8. package/dist/contracts/index.js +9 -0
  9. package/dist/contracts/index.js.map +1 -1
  10. package/dist/coordinator/contracts.d.ts +148 -5
  11. package/dist/coordinator/contracts.d.ts.map +1 -1
  12. package/dist/coordinator/contracts.js +74 -3
  13. package/dist/coordinator/contracts.js.map +1 -1
  14. package/dist/coordinator/hosted-heartbeat-execution-client.d.ts +30 -0
  15. package/dist/coordinator/hosted-heartbeat-execution-client.d.ts.map +1 -0
  16. package/dist/coordinator/hosted-heartbeat-execution-client.js +240 -0
  17. package/dist/coordinator/hosted-heartbeat-execution-client.js.map +1 -0
  18. package/dist/coordinator/hosted-heartbeat-execution-service.d.ts +14 -0
  19. package/dist/coordinator/hosted-heartbeat-execution-service.d.ts.map +1 -0
  20. package/dist/coordinator/hosted-heartbeat-execution-service.js +100 -0
  21. package/dist/coordinator/hosted-heartbeat-execution-service.js.map +1 -0
  22. package/dist/coordinator/index.d.ts +5 -5
  23. package/dist/coordinator/index.d.ts.map +1 -1
  24. package/dist/coordinator/index.js +3 -3
  25. package/dist/coordinator/index.js.map +1 -1
  26. package/dist/coordinator/node/execution-http-service.d.ts +11 -0
  27. package/dist/coordinator/node/execution-http-service.d.ts.map +1 -0
  28. package/dist/coordinator/node/{delegation-http-service.js → execution-http-service.js} +52 -39
  29. package/dist/coordinator/node/execution-http-service.js.map +1 -0
  30. package/dist/coordinator/node/index.d.ts +2 -2
  31. package/dist/coordinator/node/index.d.ts.map +1 -1
  32. package/dist/coordinator/node/index.js +1 -1
  33. package/dist/coordinator/node/index.js.map +1 -1
  34. package/dist/coordinator/node/types.d.ts +10 -9
  35. package/dist/coordinator/node/types.d.ts.map +1 -1
  36. package/dist/coordinator/node/types.js.map +1 -1
  37. package/dist/coordinator/types.d.ts +51 -13
  38. package/dist/coordinator/types.d.ts.map +1 -1
  39. package/dist/coordinator/types.js.map +1 -1
  40. package/dist/host/schemas.d.ts.map +1 -1
  41. package/dist/host/schemas.js +2 -7
  42. package/dist/host/schemas.js.map +1 -1
  43. package/dist/http-sse/direct-http-execution-host.d.ts.map +1 -1
  44. package/dist/http-sse/direct-http-execution-host.js +6 -5
  45. package/dist/http-sse/direct-http-execution-host.js.map +1 -1
  46. package/dist/http-sse/types.d.ts +2 -0
  47. package/dist/http-sse/types.d.ts.map +1 -1
  48. package/dist/http-sse/types.js.map +1 -1
  49. package/dist/node/authority-key.d.ts.map +1 -1
  50. package/dist/node/authority-key.js +24 -49
  51. package/dist/node/authority-key.js.map +1 -1
  52. package/dist/node/environment-value.d.ts +17 -0
  53. package/dist/node/environment-value.d.ts.map +1 -0
  54. package/dist/node/environment-value.js +78 -0
  55. package/dist/node/environment-value.js.map +1 -0
  56. package/dist/node/index.d.ts +4 -0
  57. package/dist/node/index.d.ts.map +1 -1
  58. package/dist/node/index.js +2 -0
  59. package/dist/node/index.js.map +1 -1
  60. package/dist/node/local-credential-bundle.d.ts +33 -0
  61. package/dist/node/local-credential-bundle.d.ts.map +1 -0
  62. package/dist/node/local-credential-bundle.js +196 -0
  63. package/dist/node/local-credential-bundle.js.map +1 -0
  64. package/dist/node/owner-only-file.d.ts +17 -0
  65. package/dist/node/owner-only-file.d.ts.map +1 -0
  66. package/dist/node/owner-only-file.js +59 -0
  67. package/dist/node/owner-only-file.js.map +1 -0
  68. package/package.json +6 -1
  69. package/dist/coordinator/hosted-heartbeat-delegation-client.d.ts +0 -21
  70. package/dist/coordinator/hosted-heartbeat-delegation-client.d.ts.map +0 -1
  71. package/dist/coordinator/hosted-heartbeat-delegation-client.js +0 -117
  72. package/dist/coordinator/hosted-heartbeat-delegation-client.js.map +0 -1
  73. package/dist/coordinator/hosted-heartbeat-delegation-service.d.ts +0 -15
  74. package/dist/coordinator/hosted-heartbeat-delegation-service.d.ts.map +0 -1
  75. package/dist/coordinator/hosted-heartbeat-delegation-service.js +0 -81
  76. package/dist/coordinator/hosted-heartbeat-delegation-service.js.map +0 -1
  77. package/dist/coordinator/node/delegation-http-service.d.ts +0 -11
  78. package/dist/coordinator/node/delegation-http-service.d.ts.map +0 -1
  79. package/dist/coordinator/node/delegation-http-service.js.map +0 -1
@@ -10,7 +10,10 @@ export const HOSTED_HEARTBEAT_COORDINATOR_PATHS = Object.freeze({
10
10
  resume: '/v1/control/resume',
11
11
  drain: '/v1/control/drain',
12
12
  });
13
- export const HOSTED_HEARTBEAT_DELEGATIONS_PATH = '/hosted-execution/internal/heartbeat-delegations';
13
+ export const HOSTED_HEARTBEAT_EXECUTION_PATHS = Object.freeze({
14
+ prepare: '/hosted-execution/internal/heartbeat-executions/prepare',
15
+ settle: '/hosted-execution/internal/heartbeat-executions/settle',
16
+ });
14
17
  export const HostedHeartbeatCoordinatorTaskInputSchema = z.object({
15
18
  workspaceId: OpaqueIdSchema.optional(),
16
19
  name: z.string().trim().min(1).max(200).optional(),
@@ -121,10 +124,11 @@ export const HostedHeartbeatDesiredTaskCatalogSchema = z.object({
121
124
  seen.add(taskId);
122
125
  });
123
126
  });
124
- export const HostedHeartbeatDelegationRequestSchema = z.object({
127
+ export const HostedHeartbeatExecutionPreparationRequestSchema = z.object({
125
128
  schemaVersion: z.literal(1),
126
129
  taskId: OpaqueIdSchema,
127
130
  executionId: OpaqueIdSchema,
131
+ interruptedExecutionId: OpaqueIdSchema.optional(),
128
132
  }).strict();
129
133
  const DelegatedAuthorityMetadataSchema = z.object({
130
134
  scope: ExecutionScopeSchema,
@@ -170,10 +174,77 @@ export const HostedHeartbeatDelegationSchema = z.object({
170
174
  message: 'must match the delegated execution authority metadata',
171
175
  }));
172
176
  });
173
- export const HostedHeartbeatDelegationAuthorizationSchema = z.object({
177
+ export const HostedHeartbeatExecutionAuthorizationSchema = z.object({
174
178
  scope: ProductExecutionScopeSchema,
175
179
  allowedTools: McpAllowedToolsSchema,
176
180
  }).strict();
181
+ export const HostedHeartbeatExecutionPreparationDecisionSchema = z.discriminatedUnion('kind', [
182
+ z.object({
183
+ kind: z.literal('execute'),
184
+ authorization: HostedHeartbeatExecutionAuthorizationSchema,
185
+ }).strict(),
186
+ z.object({
187
+ kind: z.literal('skip'),
188
+ summary: z.string().trim().min(1).max(500),
189
+ }).strict(),
190
+ ]);
191
+ export const HostedHeartbeatExecutionPreparationSchema = z.discriminatedUnion('kind', [
192
+ z.object({
193
+ schemaVersion: z.literal(1),
194
+ kind: z.literal('execute'),
195
+ delegation: HostedHeartbeatDelegationSchema,
196
+ }).strict(),
197
+ z.object({
198
+ schemaVersion: z.literal(1),
199
+ kind: z.literal('skip'),
200
+ taskId: OpaqueIdSchema,
201
+ executionId: OpaqueIdSchema,
202
+ summary: z.string().trim().min(1).max(500),
203
+ }).strict(),
204
+ ]);
205
+ export const HostedHeartbeatExecutionResultSchema = z.object({
206
+ decision: z.enum(['continue', 'pause', 'complete', 'escalate']),
207
+ summary: z.string(),
208
+ runId: OpaqueIdSchema,
209
+ outcome: z.enum(['done', 'max_steps', 'error', 'interrupted']),
210
+ }).strict();
211
+ const HostedHeartbeatExecutionSettlementEnvelopeSchema = z.object({
212
+ schemaVersion: z.literal(1),
213
+ taskId: OpaqueIdSchema,
214
+ executionId: OpaqueIdSchema,
215
+ });
216
+ export const HostedHeartbeatExecutionSettlementRequestSchema = z.discriminatedUnion('kind', [
217
+ HostedHeartbeatExecutionSettlementEnvelopeSchema.extend({
218
+ kind: z.literal('completed'),
219
+ result: HostedHeartbeatExecutionResultSchema,
220
+ }).strict(),
221
+ HostedHeartbeatExecutionSettlementEnvelopeSchema.extend({
222
+ kind: z.literal('failed'),
223
+ errorType: z.string().trim().min(1).max(128),
224
+ }).strict(),
225
+ HostedHeartbeatExecutionSettlementEnvelopeSchema.extend({
226
+ kind: z.literal('interrupted'),
227
+ }).strict(),
228
+ ]);
229
+ export const HostedHeartbeatExecutionDispositionSchema = z.discriminatedUnion('kind', [
230
+ z.object({ kind: z.literal('accepted') }).strict(),
231
+ z.object({
232
+ kind: z.literal('retry'),
233
+ summary: z.string().trim().min(1).max(500),
234
+ delayMs: z.number().int().min(1_000).max(Number.MAX_SAFE_INTEGER)
235
+ .optional(),
236
+ }).strict(),
237
+ z.object({
238
+ kind: z.literal('blocked'),
239
+ summary: z.string().trim().min(1).max(500),
240
+ }).strict(),
241
+ ]);
242
+ export const HostedHeartbeatExecutionSettlementSchema = z.object({
243
+ schemaVersion: z.literal(1),
244
+ taskId: OpaqueIdSchema,
245
+ executionId: OpaqueIdSchema,
246
+ disposition: HostedHeartbeatExecutionDispositionSchema,
247
+ }).strict();
177
248
  function sameProductScope(left, right) {
178
249
  return left.tenantId === right.tenantId
179
250
  && left.subjectId === right.subjectId
@@ -1 +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 state: '/v1/coordinator',\n tasks: '/v1/heartbeat/tasks',\n pause: '/v1/control/pause',\n resume: '/v1/control/resume',\n drain: '/v1/control/drain',\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 HostedHeartbeatCoordinatorStateSchema = z.enum([\n 'running',\n 'paused',\n 'drained',\n 'stopped',\n]);\n\nexport const HostedHeartbeatCoordinatorStateResponseSchema = z.object({\n state: HostedHeartbeatCoordinatorStateSchema,\n}).strict();\n\nexport const HostedHeartbeatCoordinatorTaskStatusSchema = z.enum([\n 'idle',\n 'running',\n 'waiting',\n 'blocked',\n 'complete',\n 'failed',\n]);\n\nexport const HostedHeartbeatCoordinatorTaskResultSchema = z.object({\n kind: z.enum([\n 'agent',\n 'skipped',\n 'cancelled',\n 'retry',\n 'blocked',\n 'failed',\n ]),\n decision: z.enum(['continue', 'pause', 'complete', 'escalate']).optional(),\n summary: z.string(),\n outcome: z.string(),\n agentRunId: OpaqueIdSchema.optional(),\n usage: z.unknown().optional(),\n}).passthrough();\n\n/** Stable product/operator projection returned by the Coordinator API. */\nexport const HostedHeartbeatCoordinatorTaskViewSchema = z.object({\n id: OpaqueIdSchema,\n taskId: OpaqueIdSchema,\n workspaceId: OpaqueIdSchema.optional(),\n name: z.string().optional(),\n task: z.string(),\n enabled: z.boolean(),\n continuationMode: z.enum(['operator', 'agent']).optional(),\n schedule: z.object({\n intervalMs: z.number().int().positive(),\n nextRunAt: TimestampSchema.optional(),\n }).passthrough(),\n state: z.object({\n status: HostedHeartbeatCoordinatorTaskStatusSchema,\n progress: z.string().optional(),\n runId: OpaqueIdSchema.optional(),\n runAt: TimestampSchema.optional(),\n loadedCheckpoint: z.boolean().optional(),\n resumable: z.boolean().optional(),\n result: HostedHeartbeatCoordinatorTaskResultSchema.optional(),\n error: z.string().optional(),\n updatedAt: TimestampSchema.optional(),\n }).passthrough(),\n}).passthrough();\n\nexport const HostedHeartbeatCoordinatorTaskListSchema = z.object({\n tasks: z.array(HostedHeartbeatCoordinatorTaskViewSchema),\n}).strict();\n\nexport const HostedHeartbeatCoordinatorRunViewSchema = z.object({\n id: OpaqueIdSchema,\n taskId: OpaqueIdSchema,\n workspaceId: OpaqueIdSchema.optional(),\n executionId: OpaqueIdSchema,\n runId: OpaqueIdSchema.optional(),\n createdAt: TimestampSchema,\n task: HostedHeartbeatCoordinatorTaskViewSchema,\n result: HostedHeartbeatCoordinatorTaskResultSchema,\n loadedCheckpoint: z.boolean().optional(),\n}).passthrough();\n\nexport const HostedHeartbeatCoordinatorTaskDetailSchema = z.object({\n task: HostedHeartbeatCoordinatorTaskViewSchema,\n runs: z.array(HostedHeartbeatCoordinatorRunViewSchema),\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 HostedHeartbeatCoordinatorState = z.infer<\n typeof HostedHeartbeatCoordinatorStateSchema\n>;\nexport type HostedHeartbeatCoordinatorTaskView = z.infer<\n typeof HostedHeartbeatCoordinatorTaskViewSchema\n>;\nexport type HostedHeartbeatCoordinatorRunView = z.infer<\n typeof HostedHeartbeatCoordinatorRunViewSchema\n>;\nexport type HostedHeartbeatCoordinatorTaskDetail = z.infer<\n typeof HostedHeartbeatCoordinatorTaskDetailSchema\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"]}
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 state: '/v1/coordinator',\n tasks: '/v1/heartbeat/tasks',\n pause: '/v1/control/pause',\n resume: '/v1/control/resume',\n drain: '/v1/control/drain',\n});\n\nexport const HOSTED_HEARTBEAT_EXECUTION_PATHS = Object.freeze({\n prepare: '/hosted-execution/internal/heartbeat-executions/prepare',\n settle: '/hosted-execution/internal/heartbeat-executions/settle',\n});\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 HostedHeartbeatCoordinatorStateSchema = z.enum([\n 'running',\n 'paused',\n 'drained',\n 'stopped',\n]);\n\nexport const HostedHeartbeatCoordinatorStateResponseSchema = z.object({\n state: HostedHeartbeatCoordinatorStateSchema,\n}).strict();\n\nexport const HostedHeartbeatCoordinatorTaskStatusSchema = z.enum([\n 'idle',\n 'running',\n 'waiting',\n 'blocked',\n 'complete',\n 'failed',\n]);\n\nexport const HostedHeartbeatCoordinatorTaskResultSchema = z.object({\n kind: z.enum([\n 'agent',\n 'skipped',\n 'cancelled',\n 'retry',\n 'blocked',\n 'failed',\n ]),\n decision: z.enum(['continue', 'pause', 'complete', 'escalate']).optional(),\n summary: z.string(),\n outcome: z.string(),\n agentRunId: OpaqueIdSchema.optional(),\n usage: z.unknown().optional(),\n}).passthrough();\n\n/** Stable product/operator projection returned by the Coordinator API. */\nexport const HostedHeartbeatCoordinatorTaskViewSchema = z.object({\n id: OpaqueIdSchema,\n taskId: OpaqueIdSchema,\n workspaceId: OpaqueIdSchema.optional(),\n name: z.string().optional(),\n task: z.string(),\n enabled: z.boolean(),\n continuationMode: z.enum(['operator', 'agent']).optional(),\n schedule: z.object({\n intervalMs: z.number().int().positive(),\n nextRunAt: TimestampSchema.optional(),\n }).passthrough(),\n state: z.object({\n status: HostedHeartbeatCoordinatorTaskStatusSchema,\n progress: z.string().optional(),\n runId: OpaqueIdSchema.optional(),\n runAt: TimestampSchema.optional(),\n loadedCheckpoint: z.boolean().optional(),\n resumable: z.boolean().optional(),\n result: HostedHeartbeatCoordinatorTaskResultSchema.optional(),\n error: z.string().optional(),\n updatedAt: TimestampSchema.optional(),\n }).passthrough(),\n}).passthrough();\n\nexport const HostedHeartbeatCoordinatorTaskListSchema = z.object({\n tasks: z.array(HostedHeartbeatCoordinatorTaskViewSchema),\n}).strict();\n\nexport const HostedHeartbeatCoordinatorRunViewSchema = z.object({\n id: OpaqueIdSchema,\n taskId: OpaqueIdSchema,\n workspaceId: OpaqueIdSchema.optional(),\n executionId: OpaqueIdSchema,\n runId: OpaqueIdSchema.optional(),\n createdAt: TimestampSchema,\n task: HostedHeartbeatCoordinatorTaskViewSchema,\n result: HostedHeartbeatCoordinatorTaskResultSchema,\n loadedCheckpoint: z.boolean().optional(),\n}).passthrough();\n\nexport const HostedHeartbeatCoordinatorTaskDetailSchema = z.object({\n task: HostedHeartbeatCoordinatorTaskViewSchema,\n runs: z.array(HostedHeartbeatCoordinatorRunViewSchema),\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 HostedHeartbeatExecutionPreparationRequestSchema = z.object({\n schemaVersion: z.literal(1),\n taskId: OpaqueIdSchema,\n executionId: OpaqueIdSchema,\n interruptedExecutionId: OpaqueIdSchema.optional(),\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 HostedHeartbeatExecutionAuthorizationSchema = z.object({\n scope: ProductExecutionScopeSchema,\n allowedTools: McpAllowedToolsSchema,\n}).strict();\n\nexport const HostedHeartbeatExecutionPreparationDecisionSchema =\n z.discriminatedUnion('kind', [\n z.object({\n kind: z.literal('execute'),\n authorization: HostedHeartbeatExecutionAuthorizationSchema,\n }).strict(),\n z.object({\n kind: z.literal('skip'),\n summary: z.string().trim().min(1).max(500),\n }).strict(),\n ]);\n\nexport const HostedHeartbeatExecutionPreparationSchema = z.discriminatedUnion(\n 'kind',\n [\n z.object({\n schemaVersion: z.literal(1),\n kind: z.literal('execute'),\n delegation: HostedHeartbeatDelegationSchema,\n }).strict(),\n z.object({\n schemaVersion: z.literal(1),\n kind: z.literal('skip'),\n taskId: OpaqueIdSchema,\n executionId: OpaqueIdSchema,\n summary: z.string().trim().min(1).max(500),\n }).strict(),\n ],\n);\n\nexport const HostedHeartbeatExecutionResultSchema = z.object({\n decision: z.enum(['continue', 'pause', 'complete', 'escalate']),\n summary: z.string(),\n runId: OpaqueIdSchema,\n outcome: z.enum(['done', 'max_steps', 'error', 'interrupted']),\n}).strict();\n\nconst HostedHeartbeatExecutionSettlementEnvelopeSchema = z.object({\n schemaVersion: z.literal(1),\n taskId: OpaqueIdSchema,\n executionId: OpaqueIdSchema,\n});\n\nexport const HostedHeartbeatExecutionSettlementRequestSchema =\n z.discriminatedUnion('kind', [\n HostedHeartbeatExecutionSettlementEnvelopeSchema.extend({\n kind: z.literal('completed'),\n result: HostedHeartbeatExecutionResultSchema,\n }).strict(),\n HostedHeartbeatExecutionSettlementEnvelopeSchema.extend({\n kind: z.literal('failed'),\n errorType: z.string().trim().min(1).max(128),\n }).strict(),\n HostedHeartbeatExecutionSettlementEnvelopeSchema.extend({\n kind: z.literal('interrupted'),\n }).strict(),\n ]);\n\nexport const HostedHeartbeatExecutionDispositionSchema = z.discriminatedUnion(\n 'kind',\n [\n z.object({ kind: z.literal('accepted') }).strict(),\n z.object({\n kind: z.literal('retry'),\n summary: z.string().trim().min(1).max(500),\n delayMs: z.number().int().min(1_000).max(Number.MAX_SAFE_INTEGER)\n .optional(),\n }).strict(),\n z.object({\n kind: z.literal('blocked'),\n summary: z.string().trim().min(1).max(500),\n }).strict(),\n ],\n);\n\nexport const HostedHeartbeatExecutionSettlementSchema = z.object({\n schemaVersion: z.literal(1),\n taskId: OpaqueIdSchema,\n executionId: OpaqueIdSchema,\n disposition: HostedHeartbeatExecutionDispositionSchema,\n}).strict();\n\nexport type HostedHeartbeatCoordinatorTaskInput = z.infer<\n typeof HostedHeartbeatCoordinatorTaskInputSchema\n>;\nexport type HostedHeartbeatCoordinatorState = z.infer<\n typeof HostedHeartbeatCoordinatorStateSchema\n>;\nexport type HostedHeartbeatCoordinatorTaskView = z.infer<\n typeof HostedHeartbeatCoordinatorTaskViewSchema\n>;\nexport type HostedHeartbeatCoordinatorRunView = z.infer<\n typeof HostedHeartbeatCoordinatorRunViewSchema\n>;\nexport type HostedHeartbeatCoordinatorTaskDetail = z.infer<\n typeof HostedHeartbeatCoordinatorTaskDetailSchema\n>;\nexport type HostedHeartbeatDesiredTask = z.infer<\n typeof HostedHeartbeatDesiredTaskSchema\n>;\nexport type HostedHeartbeatDesiredTaskCatalog = z.infer<\n typeof HostedHeartbeatDesiredTaskCatalogSchema\n>;\nexport type HostedHeartbeatExecutionPreparationRequest = z.infer<\n typeof HostedHeartbeatExecutionPreparationRequestSchema\n>;\nexport type HostedHeartbeatDelegation = z.infer<\n typeof HostedHeartbeatDelegationSchema\n>;\nexport type HostedHeartbeatExecutionAuthorization = z.infer<\n typeof HostedHeartbeatExecutionAuthorizationSchema\n>;\nexport type HostedHeartbeatExecutionPreparationDecision = z.infer<\n typeof HostedHeartbeatExecutionPreparationDecisionSchema\n>;\nexport type HostedHeartbeatExecutionPreparation = z.infer<\n typeof HostedHeartbeatExecutionPreparationSchema\n>;\nexport type HostedHeartbeatExecutionResult = z.infer<\n typeof HostedHeartbeatExecutionResultSchema\n>;\nexport type HostedHeartbeatExecutionSettlementRequest = z.infer<\n typeof HostedHeartbeatExecutionSettlementRequestSchema\n>;\nexport type HostedHeartbeatExecutionDisposition = z.infer<\n typeof HostedHeartbeatExecutionDispositionSchema\n>;\nexport type HostedHeartbeatExecutionSettlement = z.infer<\n typeof HostedHeartbeatExecutionSettlementSchema\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,30 @@
1
+ import { type HostedHeartbeatAgentExecutionTransportInput } from '../heartbeat/index.js';
2
+ import { type HostedHeartbeatExecutionPreparation, type HostedHeartbeatExecutionPreparationRequest, type HostedHeartbeatExecutionSettlement, type HostedHeartbeatExecutionSettlementRequest } from './contracts.js';
3
+ import type { HostedHeartbeatCoordinatorExecutionContext, HostedHeartbeatDelegatedExecutionConfig, HostedHeartbeatExecutionTransportPort, HostedHeartbeatExecutionApi, HostedHeartbeatExecutionClientConfig } from './types.js';
4
+ type ExecutionOperation = 'prepare' | 'settle';
5
+ export declare class HostedHeartbeatExecutionRequestError extends Error {
6
+ readonly operation: ExecutionOperation;
7
+ readonly status: number;
8
+ readonly name = "HostedHeartbeatExecutionRequestError";
9
+ constructor(operation: ExecutionOperation, status: number);
10
+ }
11
+ /** Authenticated Coordinator client for the product-owned work lifecycle. */
12
+ export declare class HostedHeartbeatExecutionClient implements HostedHeartbeatExecutionApi {
13
+ #private;
14
+ constructor(config: HostedHeartbeatExecutionClientConfig);
15
+ prepare(rawInput: HostedHeartbeatExecutionPreparationRequest, signal?: AbortSignal): Promise<HostedHeartbeatExecutionPreparation>;
16
+ settle(rawInput: HostedHeartbeatExecutionSettlementRequest, signal?: AbortSignal): Promise<HostedHeartbeatExecutionSettlement>;
17
+ }
18
+ /**
19
+ * Coordinates product work around Heddle's authoritative task attempt.
20
+ * The paired transport consumes exactly the delegation prepared for that
21
+ * execution, so running the agent can never create a second product claim.
22
+ */
23
+ export declare class HostedHeartbeatDelegatedExecution implements HostedHeartbeatExecutionTransportPort {
24
+ #private;
25
+ constructor(config: HostedHeartbeatDelegatedExecutionConfig);
26
+ handle<TResult, TOutcome>(context: HostedHeartbeatCoordinatorExecutionContext<TResult, TOutcome>): Promise<TResult | TOutcome>;
27
+ execute(input: HostedHeartbeatAgentExecutionTransportInput): Promise<unknown>;
28
+ }
29
+ export {};
30
+ //# sourceMappingURL=hosted-heartbeat-execution-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosted-heartbeat-execution-client.d.ts","sourceRoot":"","sources":["../../src/coordinator/hosted-heartbeat-execution-client.ts"],"names":[],"mappings":"AAaA,OAAO,EAGL,KAAK,2CAA2C,EACjD,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAOL,KAAK,mCAAmC,EACxC,KAAK,0CAA0C,EAC/C,KAAK,kCAAkC,EACvC,KAAK,yCAAyC,EAC/C,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EACV,0CAA0C,EAC1C,uCAAuC,EACvC,qCAAqC,EACrC,2BAA2B,EAC3B,oCAAoC,EACrC,MAAM,YAAY,CAAC;AAgBpB,KAAK,kBAAkB,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/C,qBAAa,oCAAqC,SAAQ,KAAK;IAI3D,QAAQ,CAAC,SAAS,EAAE,kBAAkB;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM;IAJzB,QAAQ,CAAC,IAAI,0CAA0C;gBAG5C,SAAS,EAAE,kBAAkB,EAC7B,MAAM,EAAE,MAAM;CAI1B;AAED,6EAA6E;AAC7E,qBAAa,8BACb,YAAW,2BAA2B;;gBAMxB,MAAM,EAAE,oCAAoC;IAyBlD,OAAO,CACX,QAAQ,EAAE,0CAA0C,EACpD,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,mCAAmC,CAAC;IAczC,MAAM,CACV,QAAQ,EAAE,yCAAyC,EACnD,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,kCAAkC,CAAC;CAqC/C;AAED;;;;GAIG;AACH,qBAAa,iCACb,YAAW,qCAAqC;;gBAIlC,MAAM,EAAE,uCAAuC;IAIrD,MAAM,CAAC,OAAO,EAAE,QAAQ,EAC5B,OAAO,EAAE,0CAA0C,CAAC,OAAO,EAAE,QAAQ,CAAC,GACrE,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC;IA2DxB,OAAO,CACX,KAAK,EAAE,2CAA2C,GACjD,OAAO,CAAC,OAAO,CAAC;CA+DpB"}
@@ -0,0 +1,240 @@
1
+ import { z } from 'zod';
2
+ import { HEARTBEAT_TASK_WORKFLOW, OpaqueIdSchema, isDockerLocalWebUrl, isSafeWebUrl, } from '../contracts/index.js';
3
+ import { HostedHeartbeatAgentExecutionTransport, HostedHeartbeatTaskService, } from '../heartbeat/index.js';
4
+ import { HOSTED_HEARTBEAT_EXECUTION_PATHS, HostedHeartbeatExecutionPreparationRequestSchema, HostedHeartbeatExecutionPreparationSchema, HostedHeartbeatExecutionSettlementRequestSchema, HostedHeartbeatExecutionSettlementSchema, } from './contracts.js';
5
+ import { HostedHeartbeatServiceTokenSchema } from './service-token.js';
6
+ const AbsolutePathSchema = z.string().min(1).max(256).regex(/^\/(?:[^?#\s]*)$/, 'must be an absolute path without query, fragment, or whitespace');
7
+ const RequestTimeoutSchema = z.number().int().min(1_000).max(60_000);
8
+ const AgentResultSchema = z.object({
9
+ decision: z.enum(['continue', 'pause', 'complete', 'escalate']),
10
+ summary: z.string(),
11
+ state: z.object({
12
+ runId: OpaqueIdSchema,
13
+ outcome: z.enum(['done', 'max_steps', 'error', 'interrupted']),
14
+ }).passthrough(),
15
+ }).passthrough();
16
+ export class HostedHeartbeatExecutionRequestError extends Error {
17
+ operation;
18
+ status;
19
+ name = 'HostedHeartbeatExecutionRequestError';
20
+ constructor(operation, status) {
21
+ super(`Heartbeat execution ${operation} failed with status ${status}.`);
22
+ this.operation = operation;
23
+ this.status = status;
24
+ }
25
+ }
26
+ /** Authenticated Coordinator client for the product-owned work lifecycle. */
27
+ export class HostedHeartbeatExecutionClient {
28
+ #endpoints;
29
+ #authorization;
30
+ #fetch;
31
+ #requestTimeoutMs;
32
+ constructor(config) {
33
+ const baseUrl = parseSafeBaseUrl(config);
34
+ this.#endpoints = {
35
+ prepare: new URL(AbsolutePathSchema.parse(config.preparePath ?? HOSTED_HEARTBEAT_EXECUTION_PATHS.prepare), baseUrl),
36
+ settle: new URL(AbsolutePathSchema.parse(config.settlePath ?? HOSTED_HEARTBEAT_EXECUTION_PATHS.settle), baseUrl),
37
+ };
38
+ this.#authorization = `Bearer ${HostedHeartbeatServiceTokenSchema.parse(config.apiToken)}`;
39
+ this.#fetch = config.fetch ?? globalThis.fetch;
40
+ this.#requestTimeoutMs = RequestTimeoutSchema.parse(config.requestTimeoutMs ?? 10_000);
41
+ }
42
+ async prepare(rawInput, signal) {
43
+ const input = HostedHeartbeatExecutionPreparationRequestSchema.parse(rawInput);
44
+ const preparation = HostedHeartbeatExecutionPreparationSchema.parse(await this.#post('prepare', input, signal));
45
+ const identity = preparation.kind === 'execute'
46
+ ? preparation.delegation
47
+ : preparation;
48
+ assertMatchingExecution(identity, input, 'preparation');
49
+ return preparation;
50
+ }
51
+ async settle(rawInput, signal) {
52
+ const input = HostedHeartbeatExecutionSettlementRequestSchema.parse(rawInput);
53
+ const settlement = HostedHeartbeatExecutionSettlementSchema.parse(await this.#post('settle', input, signal));
54
+ assertMatchingExecution(settlement, input, 'settlement');
55
+ return settlement;
56
+ }
57
+ async #post(operation, body, signal) {
58
+ const requestSignal = signal
59
+ ? AbortSignal.any([signal, AbortSignal.timeout(this.#requestTimeoutMs)])
60
+ : AbortSignal.timeout(this.#requestTimeoutMs);
61
+ const response = await this.#fetch(this.#endpoints[operation], {
62
+ method: 'POST',
63
+ headers: {
64
+ authorization: this.#authorization,
65
+ 'content-type': 'application/json',
66
+ },
67
+ body: JSON.stringify(body),
68
+ redirect: 'error',
69
+ signal: requestSignal,
70
+ });
71
+ if (!response.ok) {
72
+ throw new HostedHeartbeatExecutionRequestError(operation, response.status);
73
+ }
74
+ return await response.json();
75
+ }
76
+ }
77
+ /**
78
+ * Coordinates product work around Heddle's authoritative task attempt.
79
+ * The paired transport consumes exactly the delegation prepared for that
80
+ * execution, so running the agent can never create a second product claim.
81
+ */
82
+ export class HostedHeartbeatDelegatedExecution {
83
+ #config;
84
+ #prepared = new Map();
85
+ constructor(config) {
86
+ this.#config = config;
87
+ }
88
+ async handle(context) {
89
+ const request = HostedHeartbeatExecutionPreparationRequestSchema.parse({
90
+ schemaVersion: 1,
91
+ taskId: context.task.id,
92
+ executionId: context.executionId,
93
+ ...(context.task.state?.recovery?.interruptedExecutionId
94
+ ? {
95
+ interruptedExecutionId: context.task.state.recovery.interruptedExecutionId,
96
+ }
97
+ : {}),
98
+ });
99
+ const preparation = await this.#config.executions.prepare(request, context.signal);
100
+ if (preparation.kind === 'skip') {
101
+ return context.skip({ summary: preparation.summary });
102
+ }
103
+ this.#remember(preparation.delegation);
104
+ let result;
105
+ try {
106
+ result = await context.runAgent();
107
+ AgentResultSchema.parse(result);
108
+ }
109
+ catch (error) {
110
+ this.#prepared.delete(context.executionId);
111
+ await this.#settleFailure(request, error, context.signal.aborted);
112
+ throw error;
113
+ }
114
+ this.#prepared.delete(context.executionId);
115
+ const parsed = AgentResultSchema.parse(result);
116
+ const settlement = await this.#config.executions.settle({
117
+ schemaVersion: 1,
118
+ kind: 'completed',
119
+ taskId: request.taskId,
120
+ executionId: request.executionId,
121
+ result: {
122
+ decision: parsed.decision,
123
+ summary: parsed.summary,
124
+ runId: parsed.state.runId,
125
+ outcome: parsed.state.outcome,
126
+ },
127
+ });
128
+ if (settlement.disposition.kind === 'retry') {
129
+ return context.retry({
130
+ summary: settlement.disposition.summary,
131
+ ...(settlement.disposition.delayMs !== undefined
132
+ ? { delayMs: settlement.disposition.delayMs }
133
+ : {}),
134
+ });
135
+ }
136
+ if (settlement.disposition.kind === 'blocked') {
137
+ return context.block({ summary: settlement.disposition.summary });
138
+ }
139
+ return result;
140
+ }
141
+ async execute(input) {
142
+ const delegation = this.#prepared.get(input.request.executionId);
143
+ this.#prepared.delete(input.request.executionId);
144
+ if (!delegation
145
+ || delegation.taskId !== input.request.taskId
146
+ || delegation.executionId !== input.request.executionId) {
147
+ throw new Error('Heartbeat execution has no matching prepared product authority.');
148
+ }
149
+ const service = new HostedHeartbeatTaskService({
150
+ authority: new DelegatedExecutionAuthorityIssuer(delegation),
151
+ executionHost: this.#config.executionHost,
152
+ modelCredentials: this.#config.modelCredentials,
153
+ mcp: {
154
+ allowedTools: delegation.authority.metadata.mcp.allowedTools,
155
+ },
156
+ });
157
+ const transport = new HostedHeartbeatAgentExecutionTransport({
158
+ runner: service,
159
+ resolveInvocationContext: () => ({
160
+ scope: delegation.scope,
161
+ runtimeSessionId: delegation.runtimeSessionId,
162
+ deadlineAt: delegation.deadlineAt,
163
+ }),
164
+ });
165
+ return await transport.execute(input);
166
+ }
167
+ #remember(delegation) {
168
+ if (this.#prepared.has(delegation.executionId)) {
169
+ throw new Error('Heartbeat execution was prepared more than once.');
170
+ }
171
+ this.#prepared.set(delegation.executionId, delegation);
172
+ }
173
+ async #settleFailure(request, error, interrupted) {
174
+ const settlement = await this.#config.executions.settle(interrupted
175
+ ? {
176
+ schemaVersion: 1,
177
+ kind: 'interrupted',
178
+ taskId: request.taskId,
179
+ executionId: request.executionId,
180
+ }
181
+ : {
182
+ schemaVersion: 1,
183
+ kind: 'failed',
184
+ taskId: request.taskId,
185
+ executionId: request.executionId,
186
+ errorType: error instanceof Error ? error.name : 'unknown',
187
+ });
188
+ if (settlement.disposition.kind !== 'accepted') {
189
+ throw new Error('Product must accept failed or interrupted heartbeat settlement.');
190
+ }
191
+ }
192
+ }
193
+ function parseSafeBaseUrl(config) {
194
+ return z.custom((value) => value instanceof URL && (isSafeWebUrl(value)
195
+ || (config.allowDockerLocalHost === true
196
+ && isDockerLocalWebUrl(value))), 'baseUrl must use HTTPS or loopback HTTP; Docker local-host HTTP requires an explicit opt-in').parse(config.baseUrl);
197
+ }
198
+ function assertMatchingExecution(response, request, responseName) {
199
+ if (response.taskId !== request.taskId
200
+ || response.executionId !== request.executionId) {
201
+ throw new Error(`Product backend returned a mismatched heartbeat ${responseName}.`);
202
+ }
203
+ }
204
+ /** Ensures downstream execution cannot widen a delegated authority bundle. */
205
+ class DelegatedExecutionAuthorityIssuer {
206
+ delegation;
207
+ constructor(delegation) {
208
+ this.delegation = delegation;
209
+ }
210
+ async issue(input) {
211
+ const metadata = this.delegation.authority.metadata;
212
+ if (input.workflow !== HEARTBEAT_TASK_WORKFLOW
213
+ || input.workflow !== metadata.workflow
214
+ || input.invocationId !== metadata.invocationId
215
+ || input.runtimeSessionId !== metadata.runtimeSessionId
216
+ || !sameScope(input.scope, this.delegation.scope)
217
+ || !sameScope(input.scope, metadata.scope)
218
+ || !sameTools(input.mcp?.allowedTools, metadata.mcp.allowedTools)) {
219
+ throw new Error('Heartbeat delegation does not match Heddle execution.');
220
+ }
221
+ const authority = this.delegation.authority;
222
+ return Object.freeze({
223
+ metadata: metadata,
224
+ executionAssertion: () => authority.executionAssertion,
225
+ mcpCapability: () => authority.mcpCapability,
226
+ toJSON: () => metadata,
227
+ });
228
+ }
229
+ }
230
+ function sameScope(left, right) {
231
+ return left.tenantId === right.tenantId
232
+ && left.subjectId === right.subjectId
233
+ && left.productSessionId === right.productSessionId;
234
+ }
235
+ function sameTools(left, right) {
236
+ return Boolean(left
237
+ && left.length === right.length
238
+ && left.every((tool, index) => tool === right[index]));
239
+ }
240
+ //# sourceMappingURL=hosted-heartbeat-execution-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosted-heartbeat-execution-client.js","sourceRoot":"","sources":["../../src/coordinator/hosted-heartbeat-execution-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport type {\n ExecutionAuthorityIssueInput,\n ExecutionAuthorityIssuer,\n IssuedExecutionAuthority,\n IssuedExecutionAuthorityMetadata,\n} from '../authority/index.js';\nimport {\n HEARTBEAT_TASK_WORKFLOW,\n OpaqueIdSchema,\n isDockerLocalWebUrl,\n isSafeWebUrl,\n} from '../contracts/index.js';\nimport {\n HostedHeartbeatAgentExecutionTransport,\n HostedHeartbeatTaskService,\n type HostedHeartbeatAgentExecutionTransportInput,\n} from '../heartbeat/index.js';\nimport {\n HOSTED_HEARTBEAT_EXECUTION_PATHS,\n HostedHeartbeatExecutionPreparationRequestSchema,\n HostedHeartbeatExecutionPreparationSchema,\n HostedHeartbeatExecutionSettlementRequestSchema,\n HostedHeartbeatExecutionSettlementSchema,\n type HostedHeartbeatDelegation,\n type HostedHeartbeatExecutionPreparation,\n type HostedHeartbeatExecutionPreparationRequest,\n type HostedHeartbeatExecutionSettlement,\n type HostedHeartbeatExecutionSettlementRequest,\n} from './contracts.js';\nimport { HostedHeartbeatServiceTokenSchema } from './service-token.js';\nimport type {\n HostedHeartbeatCoordinatorExecutionContext,\n HostedHeartbeatDelegatedExecutionConfig,\n HostedHeartbeatExecutionTransportPort,\n HostedHeartbeatExecutionApi,\n HostedHeartbeatExecutionClientConfig,\n} from './types.js';\n\nconst AbsolutePathSchema = z.string().min(1).max(256).regex(\n /^\\/(?:[^?#\\s]*)$/,\n 'must be an absolute path without query, fragment, or whitespace',\n);\nconst RequestTimeoutSchema = z.number().int().min(1_000).max(60_000);\nconst AgentResultSchema = z.object({\n decision: z.enum(['continue', 'pause', 'complete', 'escalate']),\n summary: z.string(),\n state: z.object({\n runId: OpaqueIdSchema,\n outcome: z.enum(['done', 'max_steps', 'error', 'interrupted']),\n }).passthrough(),\n}).passthrough();\n\ntype ExecutionOperation = 'prepare' | 'settle';\n\nexport class HostedHeartbeatExecutionRequestError extends Error {\n readonly name = 'HostedHeartbeatExecutionRequestError';\n\n constructor(\n readonly operation: ExecutionOperation,\n readonly status: number,\n ) {\n super(`Heartbeat execution ${operation} failed with status ${status}.`);\n }\n}\n\n/** Authenticated Coordinator client for the product-owned work lifecycle. */\nexport class HostedHeartbeatExecutionClient\nimplements HostedHeartbeatExecutionApi {\n readonly #endpoints: Record<ExecutionOperation, URL>;\n readonly #authorization: string;\n readonly #fetch: typeof globalThis.fetch;\n readonly #requestTimeoutMs: number;\n\n constructor(config: HostedHeartbeatExecutionClientConfig) {\n const baseUrl = parseSafeBaseUrl(config);\n this.#endpoints = {\n prepare: new URL(\n AbsolutePathSchema.parse(\n config.preparePath ?? HOSTED_HEARTBEAT_EXECUTION_PATHS.prepare,\n ),\n baseUrl,\n ),\n settle: new URL(\n AbsolutePathSchema.parse(\n config.settlePath ?? HOSTED_HEARTBEAT_EXECUTION_PATHS.settle,\n ),\n baseUrl,\n ),\n };\n this.#authorization = `Bearer ${\n HostedHeartbeatServiceTokenSchema.parse(config.apiToken)\n }`;\n this.#fetch = config.fetch ?? globalThis.fetch;\n this.#requestTimeoutMs = RequestTimeoutSchema.parse(\n config.requestTimeoutMs ?? 10_000,\n );\n }\n\n async prepare(\n rawInput: HostedHeartbeatExecutionPreparationRequest,\n signal?: AbortSignal,\n ): Promise<HostedHeartbeatExecutionPreparation> {\n const input = HostedHeartbeatExecutionPreparationRequestSchema.parse(\n rawInput,\n );\n const preparation = HostedHeartbeatExecutionPreparationSchema.parse(\n await this.#post('prepare', input, signal),\n );\n const identity = preparation.kind === 'execute'\n ? preparation.delegation\n : preparation;\n assertMatchingExecution(identity, input, 'preparation');\n return preparation;\n }\n\n async settle(\n rawInput: HostedHeartbeatExecutionSettlementRequest,\n signal?: AbortSignal,\n ): Promise<HostedHeartbeatExecutionSettlement> {\n const input = HostedHeartbeatExecutionSettlementRequestSchema.parse(\n rawInput,\n );\n const settlement = HostedHeartbeatExecutionSettlementSchema.parse(\n await this.#post('settle', input, signal),\n );\n assertMatchingExecution(settlement, input, 'settlement');\n return settlement;\n }\n\n async #post(\n operation: ExecutionOperation,\n body: unknown,\n signal?: AbortSignal,\n ): Promise<unknown> {\n const requestSignal = signal\n ? AbortSignal.any([signal, AbortSignal.timeout(this.#requestTimeoutMs)])\n : AbortSignal.timeout(this.#requestTimeoutMs);\n const response = await this.#fetch(this.#endpoints[operation], {\n method: 'POST',\n headers: {\n authorization: this.#authorization,\n 'content-type': 'application/json',\n },\n body: JSON.stringify(body),\n redirect: 'error',\n signal: requestSignal,\n });\n if (!response.ok) {\n throw new HostedHeartbeatExecutionRequestError(\n operation,\n response.status,\n );\n }\n return await response.json();\n }\n}\n\n/**\n * Coordinates product work around Heddle's authoritative task attempt.\n * The paired transport consumes exactly the delegation prepared for that\n * execution, so running the agent can never create a second product claim.\n */\nexport class HostedHeartbeatDelegatedExecution\nimplements HostedHeartbeatExecutionTransportPort {\n readonly #config: HostedHeartbeatDelegatedExecutionConfig;\n readonly #prepared = new Map<string, HostedHeartbeatDelegation>();\n\n constructor(config: HostedHeartbeatDelegatedExecutionConfig) {\n this.#config = config;\n }\n\n async handle<TResult, TOutcome>(\n context: HostedHeartbeatCoordinatorExecutionContext<TResult, TOutcome>,\n ): Promise<TResult | TOutcome> {\n const request = HostedHeartbeatExecutionPreparationRequestSchema.parse({\n schemaVersion: 1,\n taskId: context.task.id,\n executionId: context.executionId,\n ...(context.task.state?.recovery?.interruptedExecutionId\n ? {\n interruptedExecutionId:\n context.task.state.recovery.interruptedExecutionId,\n }\n : {}),\n });\n const preparation = await this.#config.executions.prepare(\n request,\n context.signal,\n );\n if (preparation.kind === 'skip') {\n return context.skip({ summary: preparation.summary });\n }\n\n this.#remember(preparation.delegation);\n let result: TResult;\n try {\n result = await context.runAgent();\n AgentResultSchema.parse(result);\n } catch (error) {\n this.#prepared.delete(context.executionId);\n await this.#settleFailure(request, error, context.signal.aborted);\n throw error;\n }\n this.#prepared.delete(context.executionId);\n\n const parsed = AgentResultSchema.parse(result);\n const settlement = await this.#config.executions.settle({\n schemaVersion: 1,\n kind: 'completed',\n taskId: request.taskId,\n executionId: request.executionId,\n result: {\n decision: parsed.decision,\n summary: parsed.summary,\n runId: parsed.state.runId,\n outcome: parsed.state.outcome,\n },\n });\n if (settlement.disposition.kind === 'retry') {\n return context.retry({\n summary: settlement.disposition.summary,\n ...(settlement.disposition.delayMs !== undefined\n ? { delayMs: settlement.disposition.delayMs }\n : {}),\n });\n }\n if (settlement.disposition.kind === 'blocked') {\n return context.block({ summary: settlement.disposition.summary });\n }\n return result;\n }\n\n async execute(\n input: HostedHeartbeatAgentExecutionTransportInput,\n ): Promise<unknown> {\n const delegation = this.#prepared.get(input.request.executionId);\n this.#prepared.delete(input.request.executionId);\n if (\n !delegation\n || delegation.taskId !== input.request.taskId\n || delegation.executionId !== input.request.executionId\n ) {\n throw new Error(\n 'Heartbeat execution has no matching prepared product authority.',\n );\n }\n const service = new HostedHeartbeatTaskService({\n authority: new DelegatedExecutionAuthorityIssuer(delegation),\n executionHost: this.#config.executionHost,\n modelCredentials: this.#config.modelCredentials,\n mcp: {\n allowedTools: delegation.authority.metadata.mcp.allowedTools,\n },\n });\n const transport = new HostedHeartbeatAgentExecutionTransport({\n runner: service,\n resolveInvocationContext: () => ({\n scope: delegation.scope,\n runtimeSessionId: delegation.runtimeSessionId,\n deadlineAt: delegation.deadlineAt,\n }),\n });\n return await transport.execute(input);\n }\n\n #remember(delegation: HostedHeartbeatDelegation): void {\n if (this.#prepared.has(delegation.executionId)) {\n throw new Error('Heartbeat execution was prepared more than once.');\n }\n this.#prepared.set(delegation.executionId, delegation);\n }\n\n async #settleFailure(\n request: HostedHeartbeatExecutionPreparationRequest,\n error: unknown,\n interrupted: boolean,\n ): Promise<void> {\n const settlement = await this.#config.executions.settle(interrupted\n ? {\n schemaVersion: 1,\n kind: 'interrupted',\n taskId: request.taskId,\n executionId: request.executionId,\n }\n : {\n schemaVersion: 1,\n kind: 'failed',\n taskId: request.taskId,\n executionId: request.executionId,\n errorType: error instanceof Error ? error.name : 'unknown',\n });\n if (settlement.disposition.kind !== 'accepted') {\n throw new Error(\n 'Product must accept failed or interrupted heartbeat settlement.',\n );\n }\n }\n}\n\nfunction parseSafeBaseUrl(\n config: HostedHeartbeatExecutionClientConfig,\n): URL {\n return z.custom<URL>(\n (value) => value instanceof URL && (\n isSafeWebUrl(value)\n || (\n config.allowDockerLocalHost === true\n && isDockerLocalWebUrl(value)\n )\n ),\n 'baseUrl must use HTTPS or loopback HTTP; Docker local-host HTTP requires an explicit opt-in',\n ).parse(config.baseUrl);\n}\n\nfunction assertMatchingExecution(\n response: { taskId: string; executionId: string },\n request: { taskId: string; executionId: string },\n responseName: string,\n): void {\n if (\n response.taskId !== request.taskId\n || response.executionId !== request.executionId\n ) {\n throw new Error(\n `Product backend returned a mismatched heartbeat ${responseName}.`,\n );\n }\n}\n\n/** Ensures downstream execution cannot widen a delegated authority bundle. */\nclass DelegatedExecutionAuthorityIssuer implements ExecutionAuthorityIssuer {\n constructor(private readonly delegation: HostedHeartbeatDelegation) {}\n\n async issue(\n input: ExecutionAuthorityIssueInput,\n ): Promise<IssuedExecutionAuthority> {\n const metadata = this.delegation.authority.metadata;\n if (\n input.workflow !== HEARTBEAT_TASK_WORKFLOW\n || input.workflow !== metadata.workflow\n || input.invocationId !== metadata.invocationId\n || input.runtimeSessionId !== metadata.runtimeSessionId\n || !sameScope(input.scope, this.delegation.scope)\n || !sameScope(input.scope, metadata.scope)\n || !sameTools(input.mcp?.allowedTools, metadata.mcp.allowedTools)\n ) {\n throw new Error('Heartbeat delegation does not match Heddle execution.');\n }\n const authority = this.delegation.authority;\n return Object.freeze({\n metadata: metadata as IssuedExecutionAuthorityMetadata,\n executionAssertion: () => authority.executionAssertion,\n mcpCapability: () => authority.mcpCapability,\n toJSON: () => metadata as IssuedExecutionAuthorityMetadata,\n });\n }\n}\n\nfunction sameScope(\n left: ExecutionAuthorityIssueInput['scope'],\n right: HostedHeartbeatDelegation['scope']\n | HostedHeartbeatDelegation['authority']['metadata']['scope'],\n): boolean {\n return left.tenantId === right.tenantId\n && left.subjectId === right.subjectId\n && left.productSessionId === right.productSessionId;\n}\n\nfunction sameTools(\n left: readonly string[] | undefined,\n right: readonly string[],\n): boolean {\n return Boolean(\n left\n && left.length === right.length\n && left.every((tool, index) => tool === right[index]),\n );\n}\n"]}
@@ -0,0 +1,14 @@
1
+ import { type HostedHeartbeatExecutionPreparation, type HostedHeartbeatExecutionPreparationRequest, type HostedHeartbeatExecutionSettlement, type HostedHeartbeatExecutionSettlementRequest } from './contracts.js';
2
+ import type { HostedHeartbeatExecutionApi, HostedHeartbeatExecutionServiceConfig } from './types.js';
3
+ /**
4
+ * Owns the generic product lifecycle edge for one Coordinator execution.
5
+ * Product code decides whether work exists and how it settles; this service
6
+ * alone constructs the Heddle authority bundle used by the Execution Host.
7
+ */
8
+ export declare class HostedHeartbeatExecutionService implements HostedHeartbeatExecutionApi {
9
+ #private;
10
+ constructor(config: HostedHeartbeatExecutionServiceConfig);
11
+ prepare(rawInput: HostedHeartbeatExecutionPreparationRequest, rawSignal?: AbortSignal): Promise<HostedHeartbeatExecutionPreparation>;
12
+ settle(rawInput: HostedHeartbeatExecutionSettlementRequest, rawSignal?: AbortSignal): Promise<HostedHeartbeatExecutionSettlement>;
13
+ }
14
+ //# sourceMappingURL=hosted-heartbeat-execution-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosted-heartbeat-execution-service.d.ts","sourceRoot":"","sources":["../../src/coordinator/hosted-heartbeat-execution-service.ts"],"names":[],"mappings":"AAGA,OAAO,EASL,KAAK,mCAAmC,EACxC,KAAK,0CAA0C,EAC/C,KAAK,kCAAkC,EACvC,KAAK,yCAAyC,EAC/C,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EACV,2BAA2B,EAC3B,qCAAqC,EACtC,MAAM,YAAY,CAAC;AAOpB;;;;GAIG;AACH,qBAAa,+BACb,YAAW,2BAA2B;;gBAOxB,MAAM,EAAE,qCAAqC;IAYnD,OAAO,CACX,QAAQ,EAAE,0CAA0C,EACpD,SAAS,CAAC,EAAE,WAAW,GACtB,OAAO,CAAC,mCAAmC,CAAC;IA2BzC,MAAM,CACV,QAAQ,EAAE,yCAAyC,EACnD,SAAS,CAAC,EAAE,WAAW,GACtB,OAAO,CAAC,kCAAkC,CAAC;CA4D/C"}
@@ -0,0 +1,100 @@
1
+ import dayjs from 'dayjs';
2
+ import { z } from 'zod';
3
+ import { HEARTBEAT_TASK_WORKFLOW, OpaqueIdSchema } from '../contracts/index.js';
4
+ import { HostedHeartbeatDelegationSchema, HostedHeartbeatExecutionDispositionSchema, HostedHeartbeatExecutionPreparationDecisionSchema, HostedHeartbeatExecutionPreparationRequestSchema, HostedHeartbeatExecutionPreparationSchema, HostedHeartbeatExecutionSettlementRequestSchema, HostedHeartbeatExecutionSettlementSchema, } from './contracts.js';
5
+ import { createHostedRuntimeSessionId } from './runtime-session.js';
6
+ const ExecutionServiceConfigSchema = z.object({
7
+ runtimeSessionNamespace: OpaqueIdSchema,
8
+ maxExecutionMs: z.number().int().min(1_000).max(Number.MAX_SAFE_INTEGER),
9
+ }).strict();
10
+ /**
11
+ * Owns the generic product lifecycle edge for one Coordinator execution.
12
+ * Product code decides whether work exists and how it settles; this service
13
+ * alone constructs the Heddle authority bundle used by the Execution Host.
14
+ */
15
+ export class HostedHeartbeatExecutionService {
16
+ #authority;
17
+ #lifecycle;
18
+ #runtimeSessionNamespace;
19
+ #maxExecutionMs;
20
+ #now;
21
+ constructor(config) {
22
+ const parsed = ExecutionServiceConfigSchema.parse({
23
+ runtimeSessionNamespace: config.runtimeSessionNamespace,
24
+ maxExecutionMs: config.maxExecutionMs,
25
+ });
26
+ this.#authority = config.authority;
27
+ this.#lifecycle = config.lifecycle;
28
+ this.#runtimeSessionNamespace = parsed.runtimeSessionNamespace;
29
+ this.#maxExecutionMs = parsed.maxExecutionMs;
30
+ this.#now = config.now ?? (() => new Date());
31
+ }
32
+ async prepare(rawInput, rawSignal) {
33
+ const input = HostedHeartbeatExecutionPreparationRequestSchema.parse(rawInput);
34
+ const signal = rawSignal ?? new AbortController().signal;
35
+ signal.throwIfAborted();
36
+ const decision = HostedHeartbeatExecutionPreparationDecisionSchema.parse(await this.#lifecycle.prepare({ ...input, signal }));
37
+ signal.throwIfAborted();
38
+ if (decision.kind === 'skip') {
39
+ return HostedHeartbeatExecutionPreparationSchema.parse({
40
+ schemaVersion: 1,
41
+ kind: 'skip',
42
+ taskId: input.taskId,
43
+ executionId: input.executionId,
44
+ summary: decision.summary,
45
+ });
46
+ }
47
+ return HostedHeartbeatExecutionPreparationSchema.parse({
48
+ schemaVersion: 1,
49
+ kind: 'execute',
50
+ delegation: await this.#createDelegation(input, decision.authorization),
51
+ });
52
+ }
53
+ async settle(rawInput, rawSignal) {
54
+ const input = HostedHeartbeatExecutionSettlementRequestSchema.parse(rawInput);
55
+ const signal = rawSignal ?? new AbortController().signal;
56
+ signal.throwIfAborted();
57
+ const disposition = HostedHeartbeatExecutionDispositionSchema.parse(await this.#lifecycle.settle({ ...input, signal }));
58
+ signal.throwIfAborted();
59
+ return HostedHeartbeatExecutionSettlementSchema.parse({
60
+ schemaVersion: 1,
61
+ taskId: input.taskId,
62
+ executionId: input.executionId,
63
+ disposition,
64
+ });
65
+ }
66
+ async #createDelegation(input, authorization) {
67
+ const runtimeSessionId = createHostedRuntimeSessionId({
68
+ namespace: this.#runtimeSessionNamespace,
69
+ scope: authorization.scope,
70
+ });
71
+ const deadlineAt = dayjs(this.#now())
72
+ .add(this.#maxExecutionMs, 'millisecond')
73
+ .toISOString();
74
+ const issued = await this.#authority.issue({
75
+ scope: authorization.scope,
76
+ runtimeSessionId,
77
+ invocationId: input.executionId,
78
+ workflow: HEARTBEAT_TASK_WORKFLOW,
79
+ mcp: { allowedTools: authorization.allowedTools },
80
+ });
81
+ const mcpCapability = issued.mcpCapability();
82
+ if (!mcpCapability || !issued.metadata.mcp) {
83
+ throw new Error('Hosted heartbeat execution requires an MCP-capable authority.');
84
+ }
85
+ return HostedHeartbeatDelegationSchema.parse({
86
+ schemaVersion: 1,
87
+ taskId: input.taskId,
88
+ executionId: input.executionId,
89
+ scope: authorization.scope,
90
+ runtimeSessionId,
91
+ deadlineAt,
92
+ authority: {
93
+ metadata: issued.metadata,
94
+ executionAssertion: issued.executionAssertion(),
95
+ mcpCapability,
96
+ },
97
+ });
98
+ }
99
+ }
100
+ //# sourceMappingURL=hosted-heartbeat-execution-service.js.map