@heddleagent/execution-host-client 6.5.0 → 6.6.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.
Files changed (98) hide show
  1. package/README.md +7 -6
  2. package/dist/adopter/contracts.d.ts +13 -0
  3. package/dist/adopter/contracts.d.ts.map +1 -0
  4. package/dist/adopter/contracts.js +13 -0
  5. package/dist/adopter/contracts.js.map +1 -0
  6. package/dist/adopter/hosted-conversation-client.d.ts +20 -0
  7. package/dist/adopter/hosted-conversation-client.d.ts.map +1 -0
  8. package/dist/adopter/hosted-conversation-client.js +103 -0
  9. package/dist/adopter/hosted-conversation-client.js.map +1 -0
  10. package/dist/adopter/index.d.ts +5 -0
  11. package/dist/adopter/index.d.ts.map +1 -0
  12. package/dist/adopter/index.js +3 -0
  13. package/dist/adopter/index.js.map +1 -0
  14. package/dist/adopter/types.d.ts +14 -0
  15. package/dist/adopter/types.d.ts.map +1 -0
  16. package/dist/adopter/types.js +2 -0
  17. package/dist/adopter/types.js.map +1 -0
  18. package/dist/agentcore/agentcore-execution-host.d.ts.map +1 -1
  19. package/dist/agentcore/agentcore-execution-host.js +7 -4
  20. package/dist/agentcore/agentcore-execution-host.js.map +1 -1
  21. package/dist/agentcore/index.d.ts +2 -0
  22. package/dist/agentcore/index.d.ts.map +1 -1
  23. package/dist/agentcore/index.js +1 -0
  24. package/dist/agentcore/index.js.map +1 -1
  25. package/dist/agentcore/schemas.d.ts +11 -0
  26. package/dist/agentcore/schemas.d.ts.map +1 -0
  27. package/dist/agentcore/schemas.js +12 -0
  28. package/dist/agentcore/schemas.js.map +1 -0
  29. package/dist/agentcore/types.d.ts +2 -4
  30. package/dist/agentcore/types.d.ts.map +1 -1
  31. package/dist/agentcore/types.js.map +1 -1
  32. package/dist/coordinator/contracts.d.ts +367 -2
  33. package/dist/coordinator/contracts.d.ts.map +1 -1
  34. package/dist/coordinator/contracts.js +72 -2
  35. package/dist/coordinator/contracts.js.map +1 -1
  36. package/dist/coordinator/hosted-heartbeat-coordinator-client.d.ts +6 -2
  37. package/dist/coordinator/hosted-heartbeat-coordinator-client.d.ts.map +1 -1
  38. package/dist/coordinator/hosted-heartbeat-coordinator-client.js +21 -1
  39. package/dist/coordinator/hosted-heartbeat-coordinator-client.js.map +1 -1
  40. package/dist/coordinator/index.d.ts +2 -2
  41. package/dist/coordinator/index.d.ts.map +1 -1
  42. package/dist/coordinator/index.js +1 -1
  43. package/dist/coordinator/index.js.map +1 -1
  44. package/dist/coordinator/types.d.ts +7 -3
  45. package/dist/coordinator/types.d.ts.map +1 -1
  46. package/dist/coordinator/types.js.map +1 -1
  47. package/dist/host/index.d.ts +1 -0
  48. package/dist/host/index.d.ts.map +1 -1
  49. package/dist/host/index.js +1 -0
  50. package/dist/host/index.js.map +1 -1
  51. package/dist/host/runtime-session/errors.d.ts +21 -0
  52. package/dist/host/runtime-session/errors.d.ts.map +1 -0
  53. package/dist/host/runtime-session/errors.js +21 -0
  54. package/dist/host/runtime-session/errors.js.map +1 -0
  55. package/dist/host/runtime-session/index.d.ts +9 -0
  56. package/dist/host/runtime-session/index.d.ts.map +1 -0
  57. package/dist/host/runtime-session/index.js +5 -0
  58. package/dist/host/runtime-session/index.js.map +1 -0
  59. package/dist/host/runtime-session/scope-binding.d.ts +17 -0
  60. package/dist/host/runtime-session/scope-binding.d.ts.map +1 -0
  61. package/dist/host/runtime-session/scope-binding.js +37 -0
  62. package/dist/host/runtime-session/scope-binding.js.map +1 -0
  63. package/dist/host/runtime-session/service.d.ts +38 -0
  64. package/dist/host/runtime-session/service.d.ts.map +1 -0
  65. package/dist/host/runtime-session/service.js +177 -0
  66. package/dist/host/runtime-session/service.js.map +1 -0
  67. package/dist/host/runtime-session/status.d.ts +17 -0
  68. package/dist/host/runtime-session/status.d.ts.map +1 -0
  69. package/dist/host/runtime-session/status.js +33 -0
  70. package/dist/host/runtime-session/status.js.map +1 -0
  71. package/dist/host/runtime-session/types.d.ts +61 -0
  72. package/dist/host/runtime-session/types.d.ts.map +1 -0
  73. package/dist/host/runtime-session/types.js +2 -0
  74. package/dist/host/runtime-session/types.js.map +1 -0
  75. package/dist/http-sse/direct-http-execution-host.d.ts.map +1 -1
  76. package/dist/http-sse/direct-http-execution-host.js +10 -177
  77. package/dist/http-sse/direct-http-execution-host.js.map +1 -1
  78. package/dist/index.d.ts +1 -0
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +1 -0
  81. package/dist/index.js.map +1 -1
  82. package/dist/internal/execution-host-event-stream.d.ts +18 -0
  83. package/dist/internal/execution-host-event-stream.d.ts.map +1 -0
  84. package/dist/internal/execution-host-event-stream.js +141 -0
  85. package/dist/internal/execution-host-event-stream.js.map +1 -0
  86. package/dist/internal/http-response.d.ts +4 -0
  87. package/dist/internal/http-response.d.ts.map +1 -0
  88. package/dist/internal/http-response.js +57 -0
  89. package/dist/internal/http-response.js.map +1 -0
  90. package/dist/node/http-service.d.ts +0 -2
  91. package/dist/node/http-service.d.ts.map +1 -1
  92. package/dist/node/http-service.js +1 -2
  93. package/dist/node/http-service.js.map +1 -1
  94. package/dist/node/index.d.ts +2 -1
  95. package/dist/node/index.d.ts.map +1 -1
  96. package/dist/node/index.js +2 -1
  97. package/dist/node/index.js.map +1 -1
  98. package/package.json +6 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/host/runtime-session/status.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,4BAA4B,GAAG;IACzC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,kFAAkF;AAClF,qBAAa,2BAA2B;IAI1B,OAAO,CAAC,QAAQ,CAAC,GAAG;IAHhC,OAAO,CAAC,KAAK,CAAiD;IAC9D,OAAO,CAAC,oBAAoB,CAAS;gBAER,GAAG,GAAE,MAAM,IAAuB;IAI/D,aAAa,IAAI,IAAI;IAIrB,QAAQ,IAAI,IAAI;IAIhB,IAAI,IAAI,4BAA4B;IAOpC,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,kBAAkB;CAG3B"}
@@ -0,0 +1,33 @@
1
+ /** Tracks process-local execution status without provider-specific vocabulary. */
2
+ export class RuntimeSessionStatusService {
3
+ now;
4
+ state = 'idle';
5
+ changedAtUnixSeconds;
6
+ constructor(now = () => new Date()) {
7
+ this.now = now;
8
+ this.changedAtUnixSeconds = this.currentUnixSeconds();
9
+ }
10
+ markExecuting() {
11
+ this.transition('executing');
12
+ }
13
+ markIdle() {
14
+ this.transition('idle');
15
+ }
16
+ read() {
17
+ return {
18
+ state: this.state,
19
+ changedAtUnixSeconds: this.changedAtUnixSeconds,
20
+ };
21
+ }
22
+ transition(next) {
23
+ if (this.state === next) {
24
+ return;
25
+ }
26
+ this.state = next;
27
+ this.changedAtUnixSeconds = this.currentUnixSeconds();
28
+ }
29
+ currentUnixSeconds() {
30
+ return Math.floor(this.now().getTime() / 1_000);
31
+ }
32
+ }
33
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/host/runtime-session/status.ts"],"names":[],"mappings":"AAKA,kFAAkF;AAClF,MAAM,OAAO,2BAA2B;IAIT;IAHrB,KAAK,GAA0C,MAAM,CAAC;IACtD,oBAAoB,CAAS;IAErC,YAA6B,MAAkB,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE;QAAlC,QAAG,GAAH,GAAG,CAA+B;QAC7D,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;IACxD,CAAC;IAED,aAAa;QACX,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI;QACF,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;SAChD,CAAC;IACJ,CAAC;IAEO,UAAU,CAAC,IAA2C;QAC5D,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;IACxD,CAAC;IAEO,kBAAkB;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC;IAClD,CAAC;CACF","sourcesContent":["export type RuntimeSessionStatusSnapshot = {\n state: 'idle' | 'executing';\n changedAtUnixSeconds: number;\n};\n\n/** Tracks process-local execution status without provider-specific vocabulary. */\nexport class RuntimeSessionStatusService {\n private state: RuntimeSessionStatusSnapshot['state'] = 'idle';\n private changedAtUnixSeconds: number;\n\n constructor(private readonly now: () => Date = () => new Date()) {\n this.changedAtUnixSeconds = this.currentUnixSeconds();\n }\n\n markExecuting(): void {\n this.transition('executing');\n }\n\n markIdle(): void {\n this.transition('idle');\n }\n\n read(): RuntimeSessionStatusSnapshot {\n return {\n state: this.state,\n changedAtUnixSeconds: this.changedAtUnixSeconds,\n };\n }\n\n private transition(next: RuntimeSessionStatusSnapshot['state']): void {\n if (this.state === next) {\n return;\n }\n this.state = next;\n this.changedAtUnixSeconds = this.currentUnixSeconds();\n }\n\n private currentUnixSeconds(): number {\n return Math.floor(this.now().getTime() / 1_000);\n }\n}\n"]}
@@ -0,0 +1,61 @@
1
+ import type { ExecutionHostConversationTurnRequest, ExecutionHostHeartbeatTaskRequest, RuntimePublicResult } from '../../contracts/index.js';
2
+ import type { VerifiedExecutionHostMcpCapability } from '../types.js';
3
+ type RuntimeExecutionStreamEnvelope = {
4
+ runId: string;
5
+ sequence: number;
6
+ timestamp: string;
7
+ };
8
+ /** Ordered execution events exposed by any workflow executor. */
9
+ export type RuntimeExecutionStreamItem<Result = unknown> = (RuntimeExecutionStreamEnvelope & {
10
+ kind: 'activity';
11
+ activity: unknown;
12
+ }) | (RuntimeExecutionStreamEnvelope & {
13
+ kind: 'result';
14
+ result: Result;
15
+ }) | (RuntimeExecutionStreamEnvelope & {
16
+ kind: 'cancelled';
17
+ reason: string;
18
+ }) | (RuntimeExecutionStreamEnvelope & {
19
+ kind: 'error';
20
+ error: {
21
+ code: string;
22
+ message: string;
23
+ };
24
+ });
25
+ export type RuntimeInvocationRequest = ExecutionHostConversationTurnRequest | ExecutionHostHeartbeatTaskRequest;
26
+ export type RuntimeExecutionInput<Request extends RuntimeInvocationRequest = RuntimeInvocationRequest> = {
27
+ scopeKey: string;
28
+ executionSessionId: string;
29
+ request: Request;
30
+ modelApiKey: string;
31
+ mcpCapability?: VerifiedExecutionHostMcpCapability;
32
+ abortSignal: AbortSignal;
33
+ };
34
+ export type RuntimeExecutionHandle<Result = unknown> = {
35
+ runId: string;
36
+ result: Promise<Result>;
37
+ events(options?: {
38
+ signal?: AbortSignal;
39
+ }): AsyncIterable<RuntimeExecutionStreamItem<Result>>;
40
+ cancel(): boolean;
41
+ };
42
+ /** Outbound execution port for one provider-neutral workflow. */
43
+ export type RuntimeWorkflowExecutor<Request extends RuntimeInvocationRequest, Result> = {
44
+ start(input: RuntimeExecutionInput<Request>): Promise<RuntimeExecutionHandle<Result>>;
45
+ };
46
+ export type RuntimeWorkflowExecutors<HeartbeatResult = unknown> = {
47
+ conversationTurn: RuntimeWorkflowExecutor<ExecutionHostConversationTurnRequest, RuntimePublicResult>;
48
+ heartbeatTask: RuntimeWorkflowExecutor<ExecutionHostHeartbeatTaskRequest, HeartbeatResult>;
49
+ };
50
+ export type RuntimeInvocationHandle<Result = unknown> = {
51
+ runId: string;
52
+ acceptedAt: string;
53
+ events(): AsyncIterable<RuntimeExecutionStreamItem<Result>>;
54
+ cancel(): boolean;
55
+ result: Promise<Result>;
56
+ };
57
+ export type RuntimeSessionConfig = {
58
+ maxInvocationMs: number;
59
+ };
60
+ export {};
61
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/host/runtime-session/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oCAAoC,EACpC,iCAAiC,EACjC,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,aAAa,CAAC;AAEtE,KAAK,8BAA8B,GAAG;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,iEAAiE;AACjE,MAAM,MAAM,0BAA0B,CAAC,MAAM,GAAG,OAAO,IACnD,CAAC,8BAA8B,GAAG;IAClC,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC,GACA,CAAC,8BAA8B,GAAG;IAClC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,GACA,CAAC,8BAA8B,GAAG;IAClC,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,GACA,CAAC,8BAA8B,GAAG;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1C,CAAC,CAAC;AAEL,MAAM,MAAM,wBAAwB,GAChC,oCAAoC,GACpC,iCAAiC,CAAC;AAEtC,MAAM,MAAM,qBAAqB,CAC/B,OAAO,SAAS,wBAAwB,GAAG,wBAAwB,IACjE;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,kCAAkC,CAAC;IACnD,WAAW,EAAE,WAAW,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,sBAAsB,CAAC,MAAM,GAAG,OAAO,IAAI;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACxB,MAAM,CAAC,OAAO,CAAC,EAAE;QACf,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,aAAa,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,MAAM,IAAI,OAAO,CAAC;CACnB,CAAC;AAEF,iEAAiE;AACjE,MAAM,MAAM,uBAAuB,CACjC,OAAO,SAAS,wBAAwB,EACxC,MAAM,IACJ;IACF,KAAK,CACH,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,GACpC,OAAO,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,wBAAwB,CAAC,eAAe,GAAG,OAAO,IAAI;IAChE,gBAAgB,EAAE,uBAAuB,CACvC,oCAAoC,EACpC,mBAAmB,CACpB,CAAC;IACF,aAAa,EAAE,uBAAuB,CACpC,iCAAiC,EACjC,eAAe,CAChB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,uBAAuB,CAAC,MAAM,GAAG,OAAO,IAAI;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,IAAI,aAAa,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5D,MAAM,IAAI,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/host/runtime-session/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ExecutionHostConversationTurnRequest,\n ExecutionHostHeartbeatTaskRequest,\n RuntimePublicResult,\n} from '../../contracts/index.js';\nimport type { VerifiedExecutionHostMcpCapability } from '../types.js';\n\ntype RuntimeExecutionStreamEnvelope = {\n runId: string;\n sequence: number;\n timestamp: string;\n};\n\n/** Ordered execution events exposed by any workflow executor. */\nexport type RuntimeExecutionStreamItem<Result = unknown> =\n | (RuntimeExecutionStreamEnvelope & {\n kind: 'activity';\n activity: unknown;\n })\n | (RuntimeExecutionStreamEnvelope & {\n kind: 'result';\n result: Result;\n })\n | (RuntimeExecutionStreamEnvelope & {\n kind: 'cancelled';\n reason: string;\n })\n | (RuntimeExecutionStreamEnvelope & {\n kind: 'error';\n error: { code: string; message: string };\n });\n\nexport type RuntimeInvocationRequest =\n | ExecutionHostConversationTurnRequest\n | ExecutionHostHeartbeatTaskRequest;\n\nexport type RuntimeExecutionInput<\n Request extends RuntimeInvocationRequest = RuntimeInvocationRequest,\n> = {\n scopeKey: string;\n executionSessionId: string;\n request: Request;\n modelApiKey: string;\n mcpCapability?: VerifiedExecutionHostMcpCapability;\n abortSignal: AbortSignal;\n};\n\nexport type RuntimeExecutionHandle<Result = unknown> = {\n runId: string;\n result: Promise<Result>;\n events(options?: {\n signal?: AbortSignal;\n }): AsyncIterable<RuntimeExecutionStreamItem<Result>>;\n cancel(): boolean;\n};\n\n/** Outbound execution port for one provider-neutral workflow. */\nexport type RuntimeWorkflowExecutor<\n Request extends RuntimeInvocationRequest,\n Result,\n> = {\n start(\n input: RuntimeExecutionInput<Request>,\n ): Promise<RuntimeExecutionHandle<Result>>;\n};\n\nexport type RuntimeWorkflowExecutors<HeartbeatResult = unknown> = {\n conversationTurn: RuntimeWorkflowExecutor<\n ExecutionHostConversationTurnRequest,\n RuntimePublicResult\n >;\n heartbeatTask: RuntimeWorkflowExecutor<\n ExecutionHostHeartbeatTaskRequest,\n HeartbeatResult\n >;\n};\n\nexport type RuntimeInvocationHandle<Result = unknown> = {\n runId: string;\n acceptedAt: string;\n events(): AsyncIterable<RuntimeExecutionStreamItem<Result>>;\n cancel(): boolean;\n result: Promise<Result>;\n};\n\nexport type RuntimeSessionConfig = {\n maxInvocationMs: number;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"direct-http-execution-host.d.ts","sourceRoot":"","sources":["../../src/http-sse/direct-http-execution-host.ts"],"names":[],"mappings":"AAEA,OAAO,EAmBL,KAAK,iCAAiC,EACtC,KAAK,wBAAwB,EAC9B,MAAM,uBAAuB,CAAC;AAO/B,OAAO,KAAK,EACV,6BAA6B,EAC7B,aAAa,EACb,6BAA6B,EAC7B,0BAA0B,EAC1B,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAkCpB;;;GAGG;AACH,qBAAa,uBACb,YAAW,aAAa,EAAE,sBAAsB;;gBAKlC,MAAM,EAAE,6BAA6B;IAO1C,sBAAsB,CAC3B,QAAQ,EAAE,6BAA6B,GACtC,aAAa,CAAC,wBAAwB,CAAC;IAoBnC,mBAAmB,CACxB,QAAQ,EAAE,0BAA0B,GACnC,aAAa,CAAC,iCAAiC,CAAC;CAwJpD"}
1
+ {"version":3,"file":"direct-http-execution-host.d.ts","sourceRoot":"","sources":["../../src/http-sse/direct-http-execution-host.ts"],"names":[],"mappings":"AACA,OAAO,EAmBL,KAAK,iCAAiC,EACtC,KAAK,wBAAwB,EAC9B,MAAM,uBAAuB,CAAC;AAK/B,OAAO,KAAK,EACV,6BAA6B,EAC7B,aAAa,EACb,6BAA6B,EAC7B,0BAA0B,EAC1B,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAqCpB;;;GAGG;AACH,qBAAa,uBACb,YAAW,aAAa,EAAE,sBAAsB;;gBAKlC,MAAM,EAAE,6BAA6B;IAO1C,sBAAsB,CAC3B,QAAQ,EAAE,6BAA6B,GACtC,aAAa,CAAC,wBAAwB,CAAC;IAoBnC,mBAAmB,CACxB,QAAQ,EAAE,0BAA0B,GACnC,aAAa,CAAC,iCAAiC,CAAC;CAmEpD"}
@@ -1,9 +1,8 @@
1
- import { createParser } from 'eventsource-parser';
2
1
  import { z } from 'zod';
3
2
  import { AGENTCORE_RUNTIME_SESSION_HEADER, CONVERSATION_TURN_WORKFLOW, EXECUTION_ASSERTION_HEADER, EXECUTION_CONTRACT_VERSION, EXECUTION_HOST_LOCAL_TOKEN_HEADER, ExecutionHostConversationTurnRequestSchema, ExecutionHostHeartbeatStreamEventSchema, ExecutionHostHeartbeatTaskRequestSchema, ExecutionHostStreamEventSchema, HEARTBEAT_TASK_WORKFLOW, MCP_CAPABILITY_HEADER, MODEL_API_KEY_HEADER, OpaqueIdSchema, RuntimeSessionIdSchema, TimestampSchema, isExecutionHostHeartbeatTerminalEvent, isExecutionHostTerminalEvent, isSafeWebUrl, } from '../contracts/index.js';
4
- import { ExecutionHostInvocationCancelledError, ExecutionHostProtocolError, ExecutionHostRejectedError, ExecutionHostStreamInterruptedError, } from './errors.js';
5
- const MAX_SSE_BUFFER_CHARACTERS = 1_048_576;
6
- const MAX_PENDING_SSE_FRAMES = 1_024;
3
+ import { ExecutionHostInvocationCancelledError, ExecutionHostRejectedError, } from './errors.js';
4
+ import { readExecutionHostEventStream, toExecutionHostTransportError, } from '../internal/execution-host-event-stream.js';
5
+ import { readBoundedJsonResponse } from '../internal/http-response.js';
7
6
  const MAX_ERROR_BODY_BYTES = 16_384;
8
7
  const SecretSchema = z.string().min(8).max(4_096);
9
8
  const InvocationAuthoritySchema = z.object({
@@ -87,82 +86,13 @@ export class DirectHttpExecutionHost {
87
86
  if (!response.ok) {
88
87
  throw new ExecutionHostRejectedError(response.status, await readSafeErrorCode(response));
89
88
  }
90
- if (!isEventStream(response.headers.get('content-type'))) {
91
- await cancelBody(response);
92
- throw new ExecutionHostProtocolError('Execution Host did not return an SSE stream.');
93
- }
94
- if (!response.body) {
95
- throw new ExecutionHostProtocolError('Execution Host returned an empty SSE response body.');
96
- }
97
- const state = {
89
+ yield* readExecutionHostEventStream({
90
+ response,
91
+ schema,
92
+ isTerminal,
98
93
  invocationId: input.invocationId,
99
- nextSequence: 0,
100
- terminal: false,
101
- };
102
- const decoder = new TextDecoder();
103
- const pending = [];
104
- let terminalEvent;
105
- let parserError = false;
106
- const parser = createParser({
107
- maxBufferSize: MAX_SSE_BUFFER_CHARACTERS,
108
- onEvent: (event) => {
109
- if (pending.length >= MAX_PENDING_SSE_FRAMES) {
110
- parserError = true;
111
- return;
112
- }
113
- pending.push(event);
114
- },
115
- onError: () => {
116
- parserError = true;
117
- },
94
+ signal: input.signal,
118
95
  });
119
- try {
120
- for await (const chunk of response.body) {
121
- input.signal?.throwIfAborted();
122
- parser.feed(decoder.decode(chunk, { stream: true }));
123
- if (parserError) {
124
- throw new ExecutionHostProtocolError();
125
- }
126
- while (pending.length > 0) {
127
- const event = validateEvent(pending.shift(), state, schema, isTerminal);
128
- if (isTerminal(event)) {
129
- terminalEvent = event;
130
- }
131
- else {
132
- yield event;
133
- }
134
- }
135
- }
136
- parser.feed(decoder.decode());
137
- parser.reset({ consume: true });
138
- if (parserError) {
139
- throw new ExecutionHostProtocolError();
140
- }
141
- while (pending.length > 0) {
142
- const event = validateEvent(pending.shift(), state, schema, isTerminal);
143
- if (isTerminal(event)) {
144
- terminalEvent = event;
145
- }
146
- else {
147
- yield event;
148
- }
149
- }
150
- }
151
- catch (error) {
152
- if (error instanceof ExecutionHostProtocolError) {
153
- throw error;
154
- }
155
- throw toTransportError(error, input.signal);
156
- }
157
- if (!state.accepted) {
158
- throw new ExecutionHostProtocolError('Execution Host stream omitted the accepted event.');
159
- }
160
- if (!state.terminal || !terminalEvent) {
161
- throw new ExecutionHostStreamInterruptedError();
162
- }
163
- // Terminal is released only after clean EOF, so a trailing malformed or
164
- // post-terminal frame cannot be projected as success.
165
- yield terminalEvent;
166
96
  }
167
97
  async #invoke(input, body) {
168
98
  try {
@@ -175,43 +105,9 @@ export class DirectHttpExecutionHost {
175
105
  });
176
106
  }
177
107
  catch (error) {
178
- throw toTransportError(error, input.signal);
179
- }
180
- }
181
- }
182
- function validateEvent(frame, state, schema, isTerminal) {
183
- let decoded;
184
- try {
185
- decoded = JSON.parse(frame.data);
186
- }
187
- catch {
188
- throw new ExecutionHostProtocolError();
189
- }
190
- const parsed = schema.safeParse(decoded);
191
- if (!parsed.success) {
192
- throw new ExecutionHostProtocolError();
193
- }
194
- const event = parsed.data;
195
- const correctFrameMetadata = frame.event === event.kind
196
- && frame.id === String(event.sequence);
197
- const correctEnvelope = event.invocationId === state.invocationId
198
- && event.sequence === state.nextSequence;
199
- if (!correctFrameMetadata || !correctEnvelope || state.terminal) {
200
- throw new ExecutionHostProtocolError();
201
- }
202
- if (!state.accepted) {
203
- if (event.kind !== 'accepted') {
204
- throw new ExecutionHostProtocolError();
108
+ throw toExecutionHostTransportError(error, input.signal);
205
109
  }
206
- state.accepted = true;
207
- state.runId = event.runId;
208
- }
209
- else if (event.kind === 'accepted' || event.runId !== state.runId) {
210
- throw new ExecutionHostProtocolError();
211
110
  }
212
- state.nextSequence += 1;
213
- state.terminal = isTerminal(event);
214
- return event;
215
111
  }
216
112
  function createSensitiveHeaders(input, localToken) {
217
113
  const headers = new Headers({
@@ -227,78 +123,15 @@ function createSensitiveHeaders(input, localToken) {
227
123
  }
228
124
  return headers;
229
125
  }
230
- function isEventStream(contentType) {
231
- return contentType?.split(';', 1)[0]?.trim().toLowerCase()
232
- === 'text/event-stream';
233
- }
234
126
  async function readSafeErrorCode(response) {
235
127
  try {
236
- const declaredLength = Number(response.headers.get('content-length'));
237
- if (Number.isFinite(declaredLength)
238
- && declaredLength > MAX_ERROR_BODY_BYTES) {
239
- await cancelBody(response);
240
- return 'unknown';
241
- }
242
- const bytes = await readBoundedBody(response, MAX_ERROR_BODY_BYTES);
243
- if (!bytes) {
244
- return 'unknown';
245
- }
246
- const parsed = ApiErrorSchema.safeParse(JSON.parse(new TextDecoder().decode(bytes)));
128
+ const parsed = ApiErrorSchema.safeParse(await readBoundedJsonResponse(response, MAX_ERROR_BODY_BYTES));
247
129
  return parsed.success ? parsed.data.error.code : 'unknown';
248
130
  }
249
131
  catch {
250
132
  return 'unknown';
251
133
  }
252
134
  }
253
- async function readBoundedBody(response, maxBytes) {
254
- if (!response.body) {
255
- return new Uint8Array();
256
- }
257
- const reader = response.body.getReader();
258
- const chunks = [];
259
- let totalBytes = 0;
260
- try {
261
- while (true) {
262
- const { done, value } = await reader.read();
263
- if (done) {
264
- break;
265
- }
266
- totalBytes += value.byteLength;
267
- if (totalBytes > maxBytes) {
268
- await reader.cancel();
269
- return undefined;
270
- }
271
- chunks.push(value);
272
- }
273
- }
274
- finally {
275
- reader.releaseLock();
276
- }
277
- const bytes = new Uint8Array(totalBytes);
278
- let offset = 0;
279
- for (const chunk of chunks) {
280
- bytes.set(chunk, offset);
281
- offset += chunk.byteLength;
282
- }
283
- return bytes;
284
- }
285
- async function cancelBody(response) {
286
- try {
287
- await response.body?.cancel();
288
- }
289
- catch {
290
- // Response cleanup is best effort and must not replace the protocol error.
291
- }
292
- }
293
- function toTransportError(error, signal) {
294
- if (signal?.aborted || isAbortError(error)) {
295
- return new ExecutionHostInvocationCancelledError();
296
- }
297
- return new ExecutionHostStreamInterruptedError();
298
- }
299
- function isAbortError(error) {
300
- return error instanceof Error && error.name === 'AbortError';
301
- }
302
135
  function assertSafeBaseUrl(url) {
303
136
  if (!isSafeWebUrl(url)) {
304
137
  throw new Error('Direct Execution Host URL must use HTTPS or loopback HTTP and contain no credentials, query, or fragment.');
@@ -1 +1 @@
1
- {"version":3,"file":"direct-http-execution-host.js","sourceRoot":"","sources":["../../src/http-sse/direct-http-execution-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { createParser, type EventSourceMessage } from 'eventsource-parser';\nimport { z } from 'zod';\nimport {\n AGENTCORE_RUNTIME_SESSION_HEADER,\n CONVERSATION_TURN_WORKFLOW,\n EXECUTION_ASSERTION_HEADER,\n EXECUTION_CONTRACT_VERSION,\n EXECUTION_HOST_LOCAL_TOKEN_HEADER,\n ExecutionHostConversationTurnRequestSchema,\n ExecutionHostHeartbeatStreamEventSchema,\n ExecutionHostHeartbeatTaskRequestSchema,\n ExecutionHostStreamEventSchema,\n HEARTBEAT_TASK_WORKFLOW,\n MCP_CAPABILITY_HEADER,\n MODEL_API_KEY_HEADER,\n OpaqueIdSchema,\n RuntimeSessionIdSchema,\n TimestampSchema,\n isExecutionHostHeartbeatTerminalEvent,\n isExecutionHostTerminalEvent,\n isSafeWebUrl,\n type ExecutionHostHeartbeatStreamEvent,\n type ExecutionHostStreamEvent,\n} from '../contracts/index.js';\nimport {\n ExecutionHostInvocationCancelledError,\n ExecutionHostProtocolError,\n ExecutionHostRejectedError,\n ExecutionHostStreamInterruptedError,\n} from './errors.js';\nimport type {\n DirectHttpExecutionHostConfig,\n ExecutionHost,\n ExecutionHostConversationTurn,\n ExecutionHostHeartbeatTask,\n HeartbeatExecutionHost,\n} from './types.js';\n\nconst MAX_SSE_BUFFER_CHARACTERS = 1_048_576;\nconst MAX_PENDING_SSE_FRAMES = 1_024;\nconst MAX_ERROR_BODY_BYTES = 16_384;\nconst SecretSchema = z.string().min(8).max(4_096);\nconst InvocationAuthoritySchema = z.object({\n runtimeSessionId: RuntimeSessionIdSchema,\n executionAssertion: z.string().min(32).max(4_096),\n mcpCapability: z.string().min(32).max(4_096).optional(),\n modelApiKey: SecretSchema,\n signal: z.custom<AbortSignal>(\n (value) => value instanceof AbortSignal,\n 'signal must be an AbortSignal',\n ).optional(),\n}).strict();\nconst ConversationTurnSchema = InvocationAuthoritySchema.extend({\n invocationId: OpaqueIdSchema,\n prompt: z.string().trim().min(1).max(200_000),\n deadlineAt: TimestampSchema.optional(),\n}).strict();\nconst HeartbeatTaskSchema = InvocationAuthoritySchema.extend(\n ExecutionHostHeartbeatTaskRequestSchema.omit({\n schemaVersion: true,\n kind: true,\n }).shape,\n).strict();\nconst ApiErrorSchema = z.object({\n error: z.object({\n code: z.string().min(1).max(128).regex(/^[a-z0-9_]+$/),\n message: z.string(),\n }).strict(),\n}).strict();\n\n/**\n * Strict direct-development HTTP/SSE adapter for the Execution Host v1 wire.\n * It deliberately owns neither AWS SDK nor SigV4 behavior.\n */\nexport class DirectHttpExecutionHost\nimplements ExecutionHost, HeartbeatExecutionHost {\n readonly #endpoint: URL;\n readonly #fetch: typeof fetch;\n readonly #localToken: string;\n\n constructor(config: DirectHttpExecutionHostConfig) {\n assertSafeBaseUrl(config.baseUrl);\n this.#localToken = SecretSchema.parse(config.localToken);\n this.#endpoint = new URL('invocations', withTrailingSlash(config.baseUrl));\n this.#fetch = config.fetch ?? globalThis.fetch;\n }\n\n async *streamConversationTurn(\n rawInput: ExecutionHostConversationTurn,\n ): AsyncIterable<ExecutionHostStreamEvent> {\n const input = ConversationTurnSchema.parse(rawInput);\n if (input.signal?.aborted) {\n throw new ExecutionHostInvocationCancelledError();\n }\n const body = ExecutionHostConversationTurnRequestSchema.parse({\n schemaVersion: EXECUTION_CONTRACT_VERSION,\n kind: CONVERSATION_TURN_WORKFLOW,\n invocationId: input.invocationId,\n prompt: input.prompt,\n ...(input.deadlineAt ? { deadlineAt: input.deadlineAt } : {}),\n });\n yield* this.#streamInvocation(\n input,\n body,\n ExecutionHostStreamEventSchema,\n isExecutionHostTerminalEvent,\n );\n }\n\n async *streamHeartbeatTask(\n rawInput: ExecutionHostHeartbeatTask,\n ): AsyncIterable<ExecutionHostHeartbeatStreamEvent> {\n const input = HeartbeatTaskSchema.parse(rawInput);\n if (input.signal?.aborted) {\n throw new ExecutionHostInvocationCancelledError();\n }\n const body = ExecutionHostHeartbeatTaskRequestSchema.parse({\n schemaVersion: EXECUTION_CONTRACT_VERSION,\n kind: HEARTBEAT_TASK_WORKFLOW,\n invocationId: input.invocationId,\n taskId: input.taskId,\n task: input.task,\n ...(input.checkpoint ? { checkpoint: input.checkpoint } : {}),\n runContext: input.runContext,\n ...(input.model ? { model: input.model } : {}),\n ...(input.reasoningEffort\n ? { reasoningEffort: input.reasoningEffort }\n : {}),\n ...(input.maxSteps !== undefined ? { maxSteps: input.maxSteps } : {}),\n ...(input.searchIgnoreDirs\n ? { searchIgnoreDirs: input.searchIgnoreDirs }\n : {}),\n ...(input.systemContext ? { systemContext: input.systemContext } : {}),\n ...(input.deadlineAt ? { deadlineAt: input.deadlineAt } : {}),\n });\n yield* this.#streamInvocation(\n input,\n body,\n ExecutionHostHeartbeatStreamEventSchema,\n isExecutionHostHeartbeatTerminalEvent,\n );\n }\n\n async *#streamInvocation<TEvent extends ValidatedStreamEvent>(\n input: InvocationInput,\n body: unknown,\n schema: z.ZodType<TEvent>,\n isTerminal: (event: TEvent) => boolean,\n ): AsyncIterable<TEvent> {\n const response = await this.#invoke(input, body);\n if (!response.ok) {\n throw new ExecutionHostRejectedError(\n response.status,\n await readSafeErrorCode(response),\n );\n }\n if (!isEventStream(response.headers.get('content-type'))) {\n await cancelBody(response);\n throw new ExecutionHostProtocolError(\n 'Execution Host did not return an SSE stream.',\n );\n }\n if (!response.body) {\n throw new ExecutionHostProtocolError(\n 'Execution Host returned an empty SSE response body.',\n );\n }\n\n const state: StreamValidationState = {\n invocationId: input.invocationId,\n nextSequence: 0,\n terminal: false,\n };\n const decoder = new TextDecoder();\n const pending: EventSourceMessage[] = [];\n let terminalEvent: TEvent | undefined;\n let parserError = false;\n const parser = createParser({\n maxBufferSize: MAX_SSE_BUFFER_CHARACTERS,\n onEvent: (event) => {\n if (pending.length >= MAX_PENDING_SSE_FRAMES) {\n parserError = true;\n return;\n }\n pending.push(event);\n },\n onError: () => {\n parserError = true;\n },\n });\n\n try {\n for await (const chunk of response.body) {\n input.signal?.throwIfAborted();\n parser.feed(decoder.decode(chunk, { stream: true }));\n if (parserError) {\n throw new ExecutionHostProtocolError();\n }\n while (pending.length > 0) {\n const event = validateEvent(\n pending.shift()!,\n state,\n schema,\n isTerminal,\n );\n if (isTerminal(event)) {\n terminalEvent = event;\n } else {\n yield event;\n }\n }\n }\n parser.feed(decoder.decode());\n parser.reset({ consume: true });\n if (parserError) {\n throw new ExecutionHostProtocolError();\n }\n while (pending.length > 0) {\n const event = validateEvent(\n pending.shift()!,\n state,\n schema,\n isTerminal,\n );\n if (isTerminal(event)) {\n terminalEvent = event;\n } else {\n yield event;\n }\n }\n } catch (error) {\n if (error instanceof ExecutionHostProtocolError) {\n throw error;\n }\n throw toTransportError(error, input.signal);\n }\n\n if (!state.accepted) {\n throw new ExecutionHostProtocolError(\n 'Execution Host stream omitted the accepted event.',\n );\n }\n if (!state.terminal || !terminalEvent) {\n throw new ExecutionHostStreamInterruptedError();\n }\n // Terminal is released only after clean EOF, so a trailing malformed or\n // post-terminal frame cannot be projected as success.\n yield terminalEvent;\n }\n\n async #invoke(input: InvocationInput, body: unknown): Promise<Response> {\n try {\n return await this.#fetch(this.#endpoint, {\n method: 'POST',\n redirect: 'error',\n signal: input.signal,\n headers: createSensitiveHeaders(input, this.#localToken),\n body: JSON.stringify(body),\n });\n } catch (error) {\n throw toTransportError(error, input.signal);\n }\n }\n}\n\ntype StreamValidationState = {\n invocationId: string;\n runId?: string;\n nextSequence: number;\n accepted?: true;\n terminal: boolean;\n};\n\ntype InvocationInput = {\n invocationId: string;\n runtimeSessionId: string;\n executionAssertion: string;\n mcpCapability?: string;\n modelApiKey: string;\n signal?: AbortSignal;\n};\n\ntype ValidatedStreamEvent = {\n kind: string;\n invocationId: string;\n runId: string;\n sequence: number;\n timestamp: string;\n};\n\nfunction validateEvent<TEvent extends ValidatedStreamEvent>(\n frame: EventSourceMessage,\n state: StreamValidationState,\n schema: z.ZodType<TEvent>,\n isTerminal: (event: TEvent) => boolean,\n): TEvent {\n let decoded: unknown;\n try {\n decoded = JSON.parse(frame.data);\n } catch {\n throw new ExecutionHostProtocolError();\n }\n const parsed = schema.safeParse(decoded);\n if (!parsed.success) {\n throw new ExecutionHostProtocolError();\n }\n const event = parsed.data;\n const correctFrameMetadata = frame.event === event.kind\n && frame.id === String(event.sequence);\n const correctEnvelope = event.invocationId === state.invocationId\n && event.sequence === state.nextSequence;\n if (!correctFrameMetadata || !correctEnvelope || state.terminal) {\n throw new ExecutionHostProtocolError();\n }\n\n if (!state.accepted) {\n if (event.kind !== 'accepted') {\n throw new ExecutionHostProtocolError();\n }\n state.accepted = true;\n state.runId = event.runId;\n } else if (event.kind === 'accepted' || event.runId !== state.runId) {\n throw new ExecutionHostProtocolError();\n }\n\n state.nextSequence += 1;\n state.terminal = isTerminal(event);\n return event;\n}\n\nfunction createSensitiveHeaders(\n input: InvocationInput,\n localToken: string,\n): Headers {\n const headers = new Headers({\n Accept: 'text/event-stream',\n 'Content-Type': 'application/json',\n [AGENTCORE_RUNTIME_SESSION_HEADER]: input.runtimeSessionId,\n [EXECUTION_HOST_LOCAL_TOKEN_HEADER]: localToken,\n [MODEL_API_KEY_HEADER]: input.modelApiKey,\n [EXECUTION_ASSERTION_HEADER]: input.executionAssertion,\n });\n if (input.mcpCapability) {\n headers.set(MCP_CAPABILITY_HEADER, input.mcpCapability);\n }\n return headers;\n}\n\nfunction isEventStream(contentType: string | null): boolean {\n return contentType?.split(';', 1)[0]?.trim().toLowerCase()\n === 'text/event-stream';\n}\n\nasync function readSafeErrorCode(response: Response): Promise<string> {\n try {\n const declaredLength = Number(response.headers.get('content-length'));\n if (\n Number.isFinite(declaredLength)\n && declaredLength > MAX_ERROR_BODY_BYTES\n ) {\n await cancelBody(response);\n return 'unknown';\n }\n const bytes = await readBoundedBody(response, MAX_ERROR_BODY_BYTES);\n if (!bytes) {\n return 'unknown';\n }\n const parsed = ApiErrorSchema.safeParse(\n JSON.parse(new TextDecoder().decode(bytes)),\n );\n return parsed.success ? parsed.data.error.code : 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\nasync function readBoundedBody(\n response: Response,\n maxBytes: number,\n): Promise<Uint8Array | undefined> {\n if (!response.body) {\n return new Uint8Array();\n }\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let totalBytes = 0;\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n totalBytes += value.byteLength;\n if (totalBytes > maxBytes) {\n await reader.cancel();\n return undefined;\n }\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n const bytes = new Uint8Array(totalBytes);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return bytes;\n}\n\nasync function cancelBody(response: Response): Promise<void> {\n try {\n await response.body?.cancel();\n } catch {\n // Response cleanup is best effort and must not replace the protocol error.\n }\n}\n\nfunction toTransportError(error: unknown, signal?: AbortSignal): Error {\n if (signal?.aborted || isAbortError(error)) {\n return new ExecutionHostInvocationCancelledError();\n }\n return new ExecutionHostStreamInterruptedError();\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError';\n}\n\nfunction assertSafeBaseUrl(url: URL): void {\n if (!isSafeWebUrl(url)) {\n throw new Error(\n 'Direct Execution Host URL must use HTTPS or loopback HTTP and contain no credentials, query, or fragment.',\n );\n }\n}\n\nfunction withTrailingSlash(url: URL): URL {\n const normalized = new URL(url);\n normalized.pathname = normalized.pathname.endsWith('/')\n ? normalized.pathname\n : `${normalized.pathname}/`;\n return normalized;\n}\n"]}
1
+ {"version":3,"file":"direct-http-execution-host.js","sourceRoot":"","sources":["../../src/http-sse/direct-http-execution-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {\n AGENTCORE_RUNTIME_SESSION_HEADER,\n CONVERSATION_TURN_WORKFLOW,\n EXECUTION_ASSERTION_HEADER,\n EXECUTION_CONTRACT_VERSION,\n EXECUTION_HOST_LOCAL_TOKEN_HEADER,\n ExecutionHostConversationTurnRequestSchema,\n ExecutionHostHeartbeatStreamEventSchema,\n ExecutionHostHeartbeatTaskRequestSchema,\n ExecutionHostStreamEventSchema,\n HEARTBEAT_TASK_WORKFLOW,\n MCP_CAPABILITY_HEADER,\n MODEL_API_KEY_HEADER,\n OpaqueIdSchema,\n RuntimeSessionIdSchema,\n TimestampSchema,\n isExecutionHostHeartbeatTerminalEvent,\n isExecutionHostTerminalEvent,\n isSafeWebUrl,\n type ExecutionHostHeartbeatStreamEvent,\n type ExecutionHostStreamEvent,\n} from '../contracts/index.js';\nimport {\n ExecutionHostInvocationCancelledError,\n ExecutionHostRejectedError,\n} from './errors.js';\nimport type {\n DirectHttpExecutionHostConfig,\n ExecutionHost,\n ExecutionHostConversationTurn,\n ExecutionHostHeartbeatTask,\n HeartbeatExecutionHost,\n} from './types.js';\nimport {\n readExecutionHostEventStream,\n toExecutionHostTransportError,\n} from '../internal/execution-host-event-stream.js';\nimport { readBoundedJsonResponse } from '../internal/http-response.js';\n\nconst MAX_ERROR_BODY_BYTES = 16_384;\nconst SecretSchema = z.string().min(8).max(4_096);\nconst InvocationAuthoritySchema = z.object({\n runtimeSessionId: RuntimeSessionIdSchema,\n executionAssertion: z.string().min(32).max(4_096),\n mcpCapability: z.string().min(32).max(4_096).optional(),\n modelApiKey: SecretSchema,\n signal: z.custom<AbortSignal>(\n (value) => value instanceof AbortSignal,\n 'signal must be an AbortSignal',\n ).optional(),\n}).strict();\nconst ConversationTurnSchema = InvocationAuthoritySchema.extend({\n invocationId: OpaqueIdSchema,\n prompt: z.string().trim().min(1).max(200_000),\n deadlineAt: TimestampSchema.optional(),\n}).strict();\nconst HeartbeatTaskSchema = InvocationAuthoritySchema.extend(\n ExecutionHostHeartbeatTaskRequestSchema.omit({\n schemaVersion: true,\n kind: true,\n }).shape,\n).strict();\nconst ApiErrorSchema = z.object({\n error: z.object({\n code: z.string().min(1).max(128).regex(/^[a-z0-9_]+$/),\n message: z.string(),\n }).strict(),\n}).strict();\n\n/**\n * Strict direct-development HTTP/SSE adapter for the Execution Host v1 wire.\n * It deliberately owns neither AWS SDK nor SigV4 behavior.\n */\nexport class DirectHttpExecutionHost\nimplements ExecutionHost, HeartbeatExecutionHost {\n readonly #endpoint: URL;\n readonly #fetch: typeof fetch;\n readonly #localToken: string;\n\n constructor(config: DirectHttpExecutionHostConfig) {\n assertSafeBaseUrl(config.baseUrl);\n this.#localToken = SecretSchema.parse(config.localToken);\n this.#endpoint = new URL('invocations', withTrailingSlash(config.baseUrl));\n this.#fetch = config.fetch ?? globalThis.fetch;\n }\n\n async *streamConversationTurn(\n rawInput: ExecutionHostConversationTurn,\n ): AsyncIterable<ExecutionHostStreamEvent> {\n const input = ConversationTurnSchema.parse(rawInput);\n if (input.signal?.aborted) {\n throw new ExecutionHostInvocationCancelledError();\n }\n const body = ExecutionHostConversationTurnRequestSchema.parse({\n schemaVersion: EXECUTION_CONTRACT_VERSION,\n kind: CONVERSATION_TURN_WORKFLOW,\n invocationId: input.invocationId,\n prompt: input.prompt,\n ...(input.deadlineAt ? { deadlineAt: input.deadlineAt } : {}),\n });\n yield* this.#streamInvocation(\n input,\n body,\n ExecutionHostStreamEventSchema,\n isExecutionHostTerminalEvent,\n );\n }\n\n async *streamHeartbeatTask(\n rawInput: ExecutionHostHeartbeatTask,\n ): AsyncIterable<ExecutionHostHeartbeatStreamEvent> {\n const input = HeartbeatTaskSchema.parse(rawInput);\n if (input.signal?.aborted) {\n throw new ExecutionHostInvocationCancelledError();\n }\n const body = ExecutionHostHeartbeatTaskRequestSchema.parse({\n schemaVersion: EXECUTION_CONTRACT_VERSION,\n kind: HEARTBEAT_TASK_WORKFLOW,\n invocationId: input.invocationId,\n taskId: input.taskId,\n task: input.task,\n ...(input.checkpoint ? { checkpoint: input.checkpoint } : {}),\n runContext: input.runContext,\n ...(input.model ? { model: input.model } : {}),\n ...(input.reasoningEffort\n ? { reasoningEffort: input.reasoningEffort }\n : {}),\n ...(input.maxSteps !== undefined ? { maxSteps: input.maxSteps } : {}),\n ...(input.searchIgnoreDirs\n ? { searchIgnoreDirs: input.searchIgnoreDirs }\n : {}),\n ...(input.systemContext ? { systemContext: input.systemContext } : {}),\n ...(input.deadlineAt ? { deadlineAt: input.deadlineAt } : {}),\n });\n yield* this.#streamInvocation(\n input,\n body,\n ExecutionHostHeartbeatStreamEventSchema,\n isExecutionHostHeartbeatTerminalEvent,\n );\n }\n\n async *#streamInvocation<TEvent extends ValidatedStreamEvent>(\n input: InvocationInput,\n body: unknown,\n schema: z.ZodType<TEvent>,\n isTerminal: (event: TEvent) => boolean,\n ): AsyncIterable<TEvent> {\n const response = await this.#invoke(input, body);\n if (!response.ok) {\n throw new ExecutionHostRejectedError(\n response.status,\n await readSafeErrorCode(response),\n );\n }\n yield* readExecutionHostEventStream({\n response,\n schema,\n isTerminal,\n invocationId: input.invocationId,\n signal: input.signal,\n });\n }\n\n async #invoke(input: InvocationInput, body: unknown): Promise<Response> {\n try {\n return await this.#fetch(this.#endpoint, {\n method: 'POST',\n redirect: 'error',\n signal: input.signal,\n headers: createSensitiveHeaders(input, this.#localToken),\n body: JSON.stringify(body),\n });\n } catch (error) {\n throw toExecutionHostTransportError(error, input.signal);\n }\n }\n}\n\ntype InvocationInput = {\n invocationId: string;\n runtimeSessionId: string;\n executionAssertion: string;\n mcpCapability?: string;\n modelApiKey: string;\n signal?: AbortSignal;\n};\n\ntype ValidatedStreamEvent = {\n kind: string;\n invocationId: string;\n runId: string;\n sequence: number;\n timestamp: string;\n};\n\nfunction createSensitiveHeaders(\n input: InvocationInput,\n localToken: string,\n): Headers {\n const headers = new Headers({\n Accept: 'text/event-stream',\n 'Content-Type': 'application/json',\n [AGENTCORE_RUNTIME_SESSION_HEADER]: input.runtimeSessionId,\n [EXECUTION_HOST_LOCAL_TOKEN_HEADER]: localToken,\n [MODEL_API_KEY_HEADER]: input.modelApiKey,\n [EXECUTION_ASSERTION_HEADER]: input.executionAssertion,\n });\n if (input.mcpCapability) {\n headers.set(MCP_CAPABILITY_HEADER, input.mcpCapability);\n }\n return headers;\n}\n\nasync function readSafeErrorCode(response: Response): Promise<string> {\n try {\n const parsed = ApiErrorSchema.safeParse(await readBoundedJsonResponse(\n response,\n MAX_ERROR_BODY_BYTES,\n ));\n return parsed.success ? parsed.data.error.code : 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\nfunction assertSafeBaseUrl(url: URL): void {\n if (!isSafeWebUrl(url)) {\n throw new Error(\n 'Direct Execution Host URL must use HTTPS or loopback HTTP and contain no credentials, query, or fragment.',\n );\n }\n}\n\nfunction withTrailingSlash(url: URL): URL {\n const normalized = new URL(url);\n normalized.pathname = normalized.pathname.endsWith('/')\n ? normalized.pathname\n : `${normalized.pathname}/`;\n return normalized;\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './contracts/index.js';
2
+ export * from './adopter/index.js';
2
3
  export * from './authority/index.js';
3
4
  export * from './conversation/index.js';
4
5
  export * from './heartbeat/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './contracts/index.js';
2
+ export * from './adopter/index.js';
2
3
  export * from './authority/index.js';
3
4
  export * from './conversation/index.js';
4
5
  export * from './heartbeat/index.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC","sourcesContent":["export * from './contracts/index.js';\nexport * from './authority/index.js';\nexport * from './conversation/index.js';\nexport * from './heartbeat/index.js';\nexport * from './coordinator/index.js';\nexport * from './mcp/index.js';\nexport * from './http-sse/index.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC","sourcesContent":["export * from './contracts/index.js';\nexport * from './adopter/index.js';\nexport * from './authority/index.js';\nexport * from './conversation/index.js';\nexport * from './heartbeat/index.js';\nexport * from './coordinator/index.js';\nexport * from './mcp/index.js';\nexport * from './http-sse/index.js';\n"]}
@@ -0,0 +1,18 @@
1
+ import type { z } from 'zod';
2
+ type ExecutionHostEvent = {
3
+ kind: string;
4
+ invocationId: string;
5
+ runId: string;
6
+ sequence: number;
7
+ timestamp: string;
8
+ };
9
+ export declare function readExecutionHostEventStream<Event extends ExecutionHostEvent>(input: {
10
+ response: Response;
11
+ schema: z.ZodType<Event>;
12
+ isTerminal: (event: Event) => boolean;
13
+ invocationId?: string;
14
+ signal?: AbortSignal;
15
+ }): AsyncIterable<Event>;
16
+ export declare function toExecutionHostTransportError(error: unknown, signal?: AbortSignal): Error;
17
+ export {};
18
+ //# sourceMappingURL=execution-host-event-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution-host-event-stream.d.ts","sourceRoot":"","sources":["../../src/internal/execution-host-event-stream.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAc7B,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAUF,wBAAuB,4BAA4B,CACjD,KAAK,SAAS,kBAAkB,EAChC,KAAK,EAAE;IACP,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACzB,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GAAG,aAAa,CAAC,KAAK,CAAC,CAsFvB;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,WAAW,GACnB,KAAK,CAKP"}
@@ -0,0 +1,141 @@
1
+ import { createParser } from 'eventsource-parser';
2
+ import { ExecutionHostInvocationCancelledError, ExecutionHostProtocolError, ExecutionHostStreamInterruptedError, } from '../http-sse/errors.js';
3
+ import { cancelResponseBody, isEventStreamResponse, } from './http-response.js';
4
+ const MAX_SSE_BUFFER_CHARACTERS = 1_048_576;
5
+ const MAX_PENDING_SSE_FRAMES = 1_024;
6
+ export async function* readExecutionHostEventStream(input) {
7
+ if (!isEventStreamResponse(input.response)) {
8
+ await cancelResponseBody(input.response);
9
+ throw new ExecutionHostProtocolError('Execution Host did not return an SSE stream.');
10
+ }
11
+ if (!input.response.body) {
12
+ throw new ExecutionHostProtocolError('Execution Host returned an empty SSE response body.');
13
+ }
14
+ const state = {
15
+ invocationId: input.invocationId,
16
+ nextSequence: 0,
17
+ terminal: false,
18
+ };
19
+ const decoder = new TextDecoder();
20
+ const pending = [];
21
+ let terminalEvent;
22
+ let parserFailed = false;
23
+ const parser = createParser({
24
+ maxBufferSize: MAX_SSE_BUFFER_CHARACTERS,
25
+ onEvent: (event) => {
26
+ if (pending.length >= MAX_PENDING_SSE_FRAMES) {
27
+ parserFailed = true;
28
+ return;
29
+ }
30
+ pending.push(event);
31
+ },
32
+ onError: () => {
33
+ parserFailed = true;
34
+ },
35
+ });
36
+ const reader = input.response.body.getReader();
37
+ try {
38
+ while (true) {
39
+ input.signal?.throwIfAborted();
40
+ const { done, value } = await reader.read();
41
+ if (done) {
42
+ break;
43
+ }
44
+ parser.feed(decoder.decode(value, { stream: true }));
45
+ assertParserHealthy(parserFailed);
46
+ for (const event of drainEvents(pending, state, input.schema, input.isTerminal)) {
47
+ if (input.isTerminal(event)) {
48
+ terminalEvent = event;
49
+ }
50
+ else {
51
+ yield event;
52
+ }
53
+ }
54
+ }
55
+ parser.feed(decoder.decode());
56
+ parser.reset({ consume: true });
57
+ assertParserHealthy(parserFailed);
58
+ for (const event of drainEvents(pending, state, input.schema, input.isTerminal)) {
59
+ if (input.isTerminal(event)) {
60
+ terminalEvent = event;
61
+ }
62
+ else {
63
+ yield event;
64
+ }
65
+ }
66
+ }
67
+ catch (error) {
68
+ await reader.cancel().catch(() => undefined);
69
+ if (error instanceof ExecutionHostProtocolError) {
70
+ throw error;
71
+ }
72
+ throw toExecutionHostTransportError(error, input.signal);
73
+ }
74
+ finally {
75
+ reader.releaseLock();
76
+ }
77
+ if (!state.accepted) {
78
+ throw new ExecutionHostProtocolError('Execution Host stream omitted the accepted event.');
79
+ }
80
+ if (!state.terminal || !terminalEvent) {
81
+ throw new ExecutionHostStreamInterruptedError();
82
+ }
83
+ // A terminal event is observable only after clean EOF. This keeps success
84
+ // truthful if the transport appends malformed or post-terminal data.
85
+ yield terminalEvent;
86
+ }
87
+ export function toExecutionHostTransportError(error, signal) {
88
+ if (signal?.aborted || isAbortError(error)) {
89
+ return new ExecutionHostInvocationCancelledError();
90
+ }
91
+ return new ExecutionHostStreamInterruptedError();
92
+ }
93
+ function* drainEvents(pending, state, schema, isTerminal) {
94
+ while (pending.length > 0) {
95
+ yield validateEvent(pending.shift(), state, schema, isTerminal);
96
+ }
97
+ }
98
+ function validateEvent(frame, state, schema, isTerminal) {
99
+ let decoded;
100
+ try {
101
+ decoded = JSON.parse(frame.data);
102
+ }
103
+ catch {
104
+ throw new ExecutionHostProtocolError();
105
+ }
106
+ const parsed = schema.safeParse(decoded);
107
+ if (!parsed.success) {
108
+ throw new ExecutionHostProtocolError();
109
+ }
110
+ const event = parsed.data;
111
+ const correctFrameMetadata = frame.event === event.kind
112
+ && frame.id === String(event.sequence);
113
+ const correctEnvelope = event.sequence === state.nextSequence
114
+ && (!state.invocationId || event.invocationId === state.invocationId);
115
+ if (!correctFrameMetadata || !correctEnvelope || state.terminal) {
116
+ throw new ExecutionHostProtocolError();
117
+ }
118
+ if (!state.accepted) {
119
+ if (event.kind !== 'accepted') {
120
+ throw new ExecutionHostProtocolError();
121
+ }
122
+ state.accepted = true;
123
+ state.invocationId = event.invocationId;
124
+ state.runId = event.runId;
125
+ }
126
+ else if (event.kind === 'accepted' || event.runId !== state.runId) {
127
+ throw new ExecutionHostProtocolError();
128
+ }
129
+ state.nextSequence += 1;
130
+ state.terminal = isTerminal(event);
131
+ return event;
132
+ }
133
+ function assertParserHealthy(failed) {
134
+ if (failed) {
135
+ throw new ExecutionHostProtocolError();
136
+ }
137
+ }
138
+ function isAbortError(error) {
139
+ return error instanceof Error && error.name === 'AbortError';
140
+ }
141
+ //# sourceMappingURL=execution-host-event-stream.js.map