@heddleagent/execution-host-client 6.7.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/dist/agentcore/agentcore-execution-host.d.ts +1 -1
- package/dist/agentcore/agentcore-execution-host.d.ts.map +1 -1
- package/dist/agentcore/agentcore-execution-host.js +6 -3
- package/dist/agentcore/agentcore-execution-host.js.map +1 -1
- package/dist/contracts/index.d.ts +16 -1
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +19 -1
- package/dist/contracts/index.js.map +1 -1
- package/dist/conversation/hosted-conversation-turn-service.js +2 -2
- package/dist/conversation/hosted-conversation-turn-service.js.map +1 -1
- package/dist/conversation/types.d.ts +2 -2
- package/dist/conversation/types.d.ts.map +1 -1
- package/dist/conversation/types.js.map +1 -1
- package/dist/heartbeat/hosted-heartbeat-task-service.js +2 -2
- package/dist/heartbeat/hosted-heartbeat-task-service.js.map +1 -1
- package/dist/host/jwt-execution-host-mcp-capability-verifier.d.ts.map +1 -1
- package/dist/host/jwt-execution-host-mcp-capability-verifier.js +4 -2
- package/dist/host/jwt-execution-host-mcp-capability-verifier.js.map +1 -1
- package/dist/host/jwt-execution-identity-verifier.d.ts.map +1 -1
- package/dist/host/jwt-execution-identity-verifier.js +4 -2
- package/dist/host/jwt-execution-identity-verifier.js.map +1 -1
- package/dist/host/runtime-session/service.d.ts +2 -2
- package/dist/host/runtime-session/service.d.ts.map +1 -1
- package/dist/host/runtime-session/service.js +1 -1
- package/dist/host/runtime-session/service.js.map +1 -1
- package/dist/host/runtime-session/types.d.ts +2 -2
- package/dist/host/runtime-session/types.d.ts.map +1 -1
- package/dist/host/runtime-session/types.js.map +1 -1
- package/dist/host/schemas.d.ts +6 -0
- package/dist/host/schemas.d.ts.map +1 -1
- package/dist/host/schemas.js +22 -0
- package/dist/host/schemas.js.map +1 -1
- package/dist/host/types.d.ts +2 -0
- package/dist/host/types.d.ts.map +1 -1
- package/dist/host/types.js.map +1 -1
- package/dist/http-sse/direct-http-execution-host.d.ts.map +1 -1
- package/dist/http-sse/direct-http-execution-host.js +3 -3
- package/dist/http-sse/direct-http-execution-host.js.map +1 -1
- package/dist/http-sse/types.d.ts +3 -3
- package/dist/http-sse/types.d.ts.map +1 -1
- package/dist/http-sse/types.js.map +1 -1
- package/dist/node/direct-credentials.d.ts +3 -7
- package/dist/node/direct-credentials.d.ts.map +1 -1
- package/dist/node/direct-credentials.js +3 -15
- package/dist/node/direct-credentials.js.map +1 -1
- package/dist/testing/request.d.ts.map +1 -1
- package/dist/testing/request.js +14 -4
- package/dist/testing/request.js.map +1 -1
- package/package.json +1 -1
- package/spec/v1/openapi.json +62 -4
- package/spec/v1/schema-bundle.json +58 -0
package/dist/testing/request.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { createHash, timingSafeEqual, } from 'node:crypto';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { AGENTCORE_RUNTIME_SESSION_HEADER, EXECUTION_ASSERTION_HEADER, EXECUTION_HOST_LOCAL_TOKEN_HEADER, ExecutionHostConversationTurnRequestSchema, MCP_CAPABILITY_HEADER,
|
|
3
|
+
import { AGENTCORE_RUNTIME_SESSION_HEADER, EXECUTION_ASSERTION_HEADER, EXECUTION_HOST_LOCAL_TOKEN_HEADER, ExecutionHostConversationTurnRequestSchema, ExecutionHostModelCredentialSchema, MCP_CAPABILITY_HEADER, MODEL_CREDENTIAL_HEADER, RuntimeSessionIdSchema, } from '../contracts/index.js';
|
|
4
4
|
const MAX_REQUEST_BODY_BYTES = 262_144;
|
|
5
5
|
const REDACTED_HEADER_VALUE = '[REDACTED]';
|
|
6
|
-
const SecretSchema = z.string().min(8).max(4_096);
|
|
7
6
|
const AssertionSchema = z.string().min(32).max(4_096);
|
|
8
7
|
const ErrorCodeSchema = z.string().min(1).max(128).regex(/^[a-z0-9_]+$/);
|
|
9
8
|
export async function parseLocalExecutionHostRequest(request, expectedLocalToken, signal) {
|
|
@@ -12,7 +11,7 @@ export async function parseLocalExecutionHostRequest(request, expectedLocalToken
|
|
|
12
11
|
assertLocalToken(headers.localToken, expectedLocalToken);
|
|
13
12
|
const runtimeSessionId = parseRequestValue(RuntimeSessionIdSchema, headers.runtimeSessionId, 400, 'invalid_runtime_session');
|
|
14
13
|
parseRequestValue(AssertionSchema, headers.executionAssertion, 401, 'invalid_execution_identity');
|
|
15
|
-
parseRequestValue(
|
|
14
|
+
parseRequestValue(ExecutionHostModelCredentialSchema, parseSensitiveJson(headers.modelCredential), 401, 'invalid_model_credential');
|
|
16
15
|
const mcpCapability = headers.mcpCapability === undefined
|
|
17
16
|
? undefined
|
|
18
17
|
: parseRequestValue(AssertionSchema, headers.mcpCapability, 401, 'invalid_mcp_capability');
|
|
@@ -57,13 +56,24 @@ function takeInvocationHeaders(request) {
|
|
|
57
56
|
runtimeSessionId: extractSensitiveHeader(request, AGENTCORE_RUNTIME_SESSION_HEADER),
|
|
58
57
|
executionAssertion: extractSensitiveHeader(request, EXECUTION_ASSERTION_HEADER),
|
|
59
58
|
mcpCapability: extractSensitiveHeader(request, MCP_CAPABILITY_HEADER),
|
|
60
|
-
|
|
59
|
+
modelCredential: extractSensitiveHeader(request, MODEL_CREDENTIAL_HEADER),
|
|
61
60
|
};
|
|
62
61
|
if (Object.values(extracted).some((header) => header.duplicate)) {
|
|
63
62
|
throw new LocalExecutionHostRequestError(400, 'duplicate_sensitive_header');
|
|
64
63
|
}
|
|
65
64
|
return Object.fromEntries(Object.entries(extracted).map(([name, header]) => [name, header.value]));
|
|
66
65
|
}
|
|
66
|
+
function parseSensitiveJson(value) {
|
|
67
|
+
if (!value) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
return JSON.parse(value);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
67
77
|
function extractSensitiveHeader(request, name) {
|
|
68
78
|
const occurrences = request.rawHeaders.reduce((count, headerName, index) => count
|
|
69
79
|
+ (index % 2 === 0 && headerName.toLowerCase() === name ? 1 : 0), 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/testing/request.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createHash,\n timingSafeEqual,\n} from 'node:crypto';\nimport type {\n IncomingMessage,\n ServerResponse,\n} from 'node:http';\nimport { z } from 'zod';\nimport {\n AGENTCORE_RUNTIME_SESSION_HEADER,\n EXECUTION_ASSERTION_HEADER,\n EXECUTION_HOST_LOCAL_TOKEN_HEADER,\n ExecutionHostConversationTurnRequestSchema,\n MCP_CAPABILITY_HEADER,\n MODEL_API_KEY_HEADER,\n RuntimeSessionIdSchema,\n type ExecutionHostConversationTurnRequest,\n} from '../contracts/index.js';\n\nconst MAX_REQUEST_BODY_BYTES = 262_144;\nconst REDACTED_HEADER_VALUE = '[REDACTED]';\nconst SecretSchema = z.string().min(8).max(4_096);\nconst AssertionSchema = z.string().min(32).max(4_096);\nconst ErrorCodeSchema = z.string().min(1).max(128).regex(/^[a-z0-9_]+$/);\n\nexport type ParsedLocalExecutionHostRequest = {\n request: ExecutionHostConversationTurnRequest;\n runtimeSessionId: string;\n mcpCapability?: string;\n};\n\nexport async function parseLocalExecutionHostRequest(\n request: IncomingMessage,\n expectedLocalToken: string,\n signal: AbortSignal,\n): Promise<ParsedLocalExecutionHostRequest> {\n const headers = takeInvocationHeaders(request);\n assertInvocationRoute(request);\n assertLocalToken(headers.localToken, expectedLocalToken);\n const runtimeSessionId = parseRequestValue(\n RuntimeSessionIdSchema,\n headers.runtimeSessionId,\n 400,\n 'invalid_runtime_session',\n );\n parseRequestValue(\n AssertionSchema,\n headers.executionAssertion,\n 401,\n 'invalid_execution_identity',\n );\n parseRequestValue(\n SecretSchema,\n headers.modelApiKey,\n 401,\n 'invalid_model_credential',\n );\n const mcpCapability = headers.mcpCapability === undefined\n ? undefined\n : parseRequestValue(\n AssertionSchema,\n headers.mcpCapability,\n 401,\n 'invalid_mcp_capability',\n );\n const parsedRequest = parseRequestValue(\n ExecutionHostConversationTurnRequestSchema,\n await readJsonBody(request, signal),\n 400,\n 'invalid_request',\n );\n return {\n request: parsedRequest,\n runtimeSessionId,\n mcpCapability,\n };\n}\n\nexport function writeLocalExecutionHostRejection(\n response: ServerResponse,\n error: unknown,\n): void {\n const rejection = error instanceof LocalExecutionHostRequestError\n ? { status: error.status, code: error.code }\n : { status: 500, code: 'fixture_internal_error' };\n const safeCode = ErrorCodeSchema.parse(rejection.code);\n const body = JSON.stringify({\n error: {\n code: safeCode,\n message: 'Local Execution Host fixture rejected the request.',\n },\n });\n response.writeHead(rejection.status, {\n 'Cache-Control': 'no-store',\n 'Content-Length': Buffer.byteLength(body),\n 'Content-Type': 'application/json; charset=utf-8',\n 'X-Content-Type-Options': 'nosniff',\n });\n response.end(body);\n}\n\ntype InvocationHeaders = {\n localToken: string | undefined;\n runtimeSessionId: string | undefined;\n executionAssertion: string | undefined;\n mcpCapability: string | undefined;\n modelApiKey: string | undefined;\n};\n\nclass LocalExecutionHostRequestError extends Error {\n constructor(\n readonly status: number,\n readonly code: string,\n ) {\n super(code);\n }\n}\n\nfunction takeInvocationHeaders(request: IncomingMessage): InvocationHeaders {\n const extracted = {\n localToken: extractSensitiveHeader(\n request,\n EXECUTION_HOST_LOCAL_TOKEN_HEADER,\n ),\n runtimeSessionId: extractSensitiveHeader(\n request,\n AGENTCORE_RUNTIME_SESSION_HEADER,\n ),\n executionAssertion: extractSensitiveHeader(\n request,\n EXECUTION_ASSERTION_HEADER,\n ),\n mcpCapability: extractSensitiveHeader(request, MCP_CAPABILITY_HEADER),\n modelApiKey: extractSensitiveHeader(request, MODEL_API_KEY_HEADER),\n };\n if (Object.values(extracted).some((header) => header.duplicate)) {\n throw new LocalExecutionHostRequestError(\n 400,\n 'duplicate_sensitive_header',\n );\n }\n return Object.fromEntries(\n Object.entries(extracted).map(([name, header]) => [name, header.value]),\n ) as InvocationHeaders;\n}\n\nfunction extractSensitiveHeader(\n request: IncomingMessage,\n name: string,\n): { value: string | undefined; duplicate: boolean } {\n const occurrences = request.rawHeaders.reduce(\n (count, headerName, index) => count\n + (index % 2 === 0 && headerName.toLowerCase() === name ? 1 : 0),\n 0,\n );\n const value = request.headers[name];\n request.headers[name] = value === undefined\n ? undefined\n : REDACTED_HEADER_VALUE;\n for (let index = 0; index < request.rawHeaders.length; index += 2) {\n if (request.rawHeaders[index]?.toLowerCase() === name) {\n request.rawHeaders[index + 1] = REDACTED_HEADER_VALUE;\n }\n }\n return {\n value: Array.isArray(value) ? undefined : value,\n duplicate: occurrences > 1 || Array.isArray(value),\n };\n}\n\nfunction assertInvocationRoute(request: IncomingMessage): void {\n if (request.method !== 'POST') {\n throw new LocalExecutionHostRequestError(405, 'method_not_allowed');\n }\n if (request.url !== '/invocations') {\n throw new LocalExecutionHostRequestError(404, 'not_found');\n }\n const contentType = request.headers['content-type']\n ?.split(';', 1)[0]\n ?.trim()\n .toLowerCase();\n if (contentType !== 'application/json') {\n throw new LocalExecutionHostRequestError(\n 415,\n 'unsupported_media_type',\n );\n }\n}\n\nfunction assertLocalToken(actual: string | undefined, expected: string): void {\n if (!actual || !constantTimeEqual(actual, expected)) {\n throw new LocalExecutionHostRequestError(401, 'invalid_local_token');\n }\n}\n\nfunction constantTimeEqual(left: string, right: string): boolean {\n const leftHash = createHash('sha256').update(left).digest();\n const rightHash = createHash('sha256').update(right).digest();\n return timingSafeEqual(leftHash, rightHash);\n}\n\nasync function readJsonBody(\n request: IncomingMessage,\n signal: AbortSignal,\n): Promise<unknown> {\n const chunks: Buffer[] = [];\n let totalBytes = 0;\n for await (const rawChunk of request) {\n signal.throwIfAborted();\n const chunk = Buffer.isBuffer(rawChunk)\n ? rawChunk\n : Buffer.from(rawChunk as Uint8Array);\n totalBytes += chunk.byteLength;\n if (totalBytes > MAX_REQUEST_BODY_BYTES) {\n throw new LocalExecutionHostRequestError(413, 'request_too_large');\n }\n chunks.push(chunk);\n }\n if (totalBytes === 0) {\n throw new LocalExecutionHostRequestError(400, 'invalid_request');\n }\n try {\n return JSON.parse(Buffer.concat(chunks, totalBytes).toString('utf8'));\n } catch {\n throw new LocalExecutionHostRequestError(400, 'invalid_request');\n }\n}\n\nfunction parseRequestValue<T>(\n schema: z.ZodType<T>,\n value: unknown,\n status: number,\n code: string,\n): T {\n const parsed = schema.safeParse(value);\n if (!parsed.success) {\n throw new LocalExecutionHostRequestError(status, code);\n }\n return parsed.data;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/testing/request.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,eAAe,GAChB,MAAM,aAAa,CAAC;AAKrB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,gCAAgC,EAChC,0BAA0B,EAC1B,iCAAiC,EACjC,0CAA0C,EAC1C,kCAAkC,EAClC,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,GAEvB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,sBAAsB,GAAG,OAAO,CAAC;AACvC,MAAM,qBAAqB,GAAG,YAAY,CAAC;AAC3C,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACtD,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;AAQzE,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,OAAwB,EACxB,kBAA0B,EAC1B,MAAmB;IAEnB,MAAM,OAAO,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/C,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,gBAAgB,CAAC,OAAO,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;IACzD,MAAM,gBAAgB,GAAG,iBAAiB,CACxC,sBAAsB,EACtB,OAAO,CAAC,gBAAgB,EACxB,GAAG,EACH,yBAAyB,CAC1B,CAAC;IACF,iBAAiB,CACf,eAAe,EACf,OAAO,CAAC,kBAAkB,EAC1B,GAAG,EACH,4BAA4B,CAC7B,CAAC;IACF,iBAAiB,CACf,kCAAkC,EAClC,kBAAkB,CAAC,OAAO,CAAC,eAAe,CAAC,EAC3C,GAAG,EACH,0BAA0B,CAC3B,CAAC;IACF,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,KAAK,SAAS;QACvD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,iBAAiB,CACjB,eAAe,EACf,OAAO,CAAC,aAAa,EACrB,GAAG,EACH,wBAAwB,CACzB,CAAC;IACJ,MAAM,aAAa,GAAG,iBAAiB,CACrC,0CAA0C,EAC1C,MAAM,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,EACnC,GAAG,EACH,iBAAiB,CAClB,CAAC;IACF,OAAO;QACL,OAAO,EAAE,aAAa;QACtB,gBAAgB;QAChB,aAAa;KACd,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gCAAgC,CAC9C,QAAwB,EACxB,KAAc;IAEd,MAAM,SAAS,GAAG,KAAK,YAAY,8BAA8B;QAC/D,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE;QAC5C,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,wBAAwB,EAAE,CAAC;IACpD,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QAC1B,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,oDAAoD;SAC9D;KACF,CAAC,CAAC;IACH,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE;QACnC,eAAe,EAAE,UAAU;QAC3B,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;QACzC,cAAc,EAAE,iCAAiC;QACjD,wBAAwB,EAAE,SAAS;KACpC,CAAC,CAAC;IACH,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAUD,MAAM,8BAA+B,SAAQ,KAAK;IAErC;IACA;IAFX,YACW,MAAc,EACd,IAAY;QAErB,KAAK,CAAC,IAAI,CAAC,CAAC;QAHH,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAQ;IAGvB,CAAC;CACF;AAED,SAAS,qBAAqB,CAAC,OAAwB;IACrD,MAAM,SAAS,GAAG;QAChB,UAAU,EAAE,sBAAsB,CAChC,OAAO,EACP,iCAAiC,CAClC;QACD,gBAAgB,EAAE,sBAAsB,CACtC,OAAO,EACP,gCAAgC,CACjC;QACD,kBAAkB,EAAE,sBAAsB,CACxC,OAAO,EACP,0BAA0B,CAC3B;QACD,aAAa,EAAE,sBAAsB,CAAC,OAAO,EAAE,qBAAqB,CAAC;QACrE,eAAe,EAAE,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,CAAC;KAC1E,CAAC;IACF,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,8BAA8B,CACtC,GAAG,EACH,4BAA4B,CAC7B,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CACnD,CAAC;AACzB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAyB;IACnD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAY,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAC7B,OAAwB,EACxB,IAAY;IAEZ,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAC3C,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK;UAC/B,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAClE,CAAC,CACF,CAAC;IACF,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK,SAAS;QACzC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,qBAAqB,CAAC;IAC1B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAClE,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC;YACtD,OAAO,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,qBAAqB,CAAC;QACxD,CAAC;IACH,CAAC;IACD,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK;QAC/C,SAAS,EAAE,WAAW,GAAG,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;KACnD,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAwB;IACrD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC9B,MAAM,IAAI,8BAA8B,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,KAAK,cAAc,EAAE,CAAC;QACnC,MAAM,IAAI,8BAA8B,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC;QACjD,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,EAAE,IAAI,EAAE;SACP,WAAW,EAAE,CAAC;IACjB,IAAI,WAAW,KAAK,kBAAkB,EAAE,CAAC;QACvC,MAAM,IAAI,8BAA8B,CACtC,GAAG,EACH,wBAAwB,CACzB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,MAA0B,EAAE,QAAgB;IACpE,IAAI,CAAC,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,8BAA8B,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY,EAAE,KAAa;IACpD,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;IAC5D,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;IAC9D,OAAO,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,OAAwB,EACxB,MAAmB;IAEnB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,KAAK,EAAE,MAAM,QAAQ,IAAI,OAAO,EAAE,CAAC;QACrC,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACrC,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAsB,CAAC,CAAC;QACxC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC;QAC/B,IAAI,UAAU,GAAG,sBAAsB,EAAE,CAAC;YACxC,MAAM,IAAI,8BAA8B,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,8BAA8B,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,8BAA8B,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IACnE,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CACxB,MAAoB,EACpB,KAAc,EACd,MAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,8BAA8B,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC","sourcesContent":["import {\n createHash,\n timingSafeEqual,\n} from 'node:crypto';\nimport type {\n IncomingMessage,\n ServerResponse,\n} from 'node:http';\nimport { z } from 'zod';\nimport {\n AGENTCORE_RUNTIME_SESSION_HEADER,\n EXECUTION_ASSERTION_HEADER,\n EXECUTION_HOST_LOCAL_TOKEN_HEADER,\n ExecutionHostConversationTurnRequestSchema,\n ExecutionHostModelCredentialSchema,\n MCP_CAPABILITY_HEADER,\n MODEL_CREDENTIAL_HEADER,\n RuntimeSessionIdSchema,\n type ExecutionHostConversationTurnRequest,\n} from '../contracts/index.js';\n\nconst MAX_REQUEST_BODY_BYTES = 262_144;\nconst REDACTED_HEADER_VALUE = '[REDACTED]';\nconst AssertionSchema = z.string().min(32).max(4_096);\nconst ErrorCodeSchema = z.string().min(1).max(128).regex(/^[a-z0-9_]+$/);\n\nexport type ParsedLocalExecutionHostRequest = {\n request: ExecutionHostConversationTurnRequest;\n runtimeSessionId: string;\n mcpCapability?: string;\n};\n\nexport async function parseLocalExecutionHostRequest(\n request: IncomingMessage,\n expectedLocalToken: string,\n signal: AbortSignal,\n): Promise<ParsedLocalExecutionHostRequest> {\n const headers = takeInvocationHeaders(request);\n assertInvocationRoute(request);\n assertLocalToken(headers.localToken, expectedLocalToken);\n const runtimeSessionId = parseRequestValue(\n RuntimeSessionIdSchema,\n headers.runtimeSessionId,\n 400,\n 'invalid_runtime_session',\n );\n parseRequestValue(\n AssertionSchema,\n headers.executionAssertion,\n 401,\n 'invalid_execution_identity',\n );\n parseRequestValue(\n ExecutionHostModelCredentialSchema,\n parseSensitiveJson(headers.modelCredential),\n 401,\n 'invalid_model_credential',\n );\n const mcpCapability = headers.mcpCapability === undefined\n ? undefined\n : parseRequestValue(\n AssertionSchema,\n headers.mcpCapability,\n 401,\n 'invalid_mcp_capability',\n );\n const parsedRequest = parseRequestValue(\n ExecutionHostConversationTurnRequestSchema,\n await readJsonBody(request, signal),\n 400,\n 'invalid_request',\n );\n return {\n request: parsedRequest,\n runtimeSessionId,\n mcpCapability,\n };\n}\n\nexport function writeLocalExecutionHostRejection(\n response: ServerResponse,\n error: unknown,\n): void {\n const rejection = error instanceof LocalExecutionHostRequestError\n ? { status: error.status, code: error.code }\n : { status: 500, code: 'fixture_internal_error' };\n const safeCode = ErrorCodeSchema.parse(rejection.code);\n const body = JSON.stringify({\n error: {\n code: safeCode,\n message: 'Local Execution Host fixture rejected the request.',\n },\n });\n response.writeHead(rejection.status, {\n 'Cache-Control': 'no-store',\n 'Content-Length': Buffer.byteLength(body),\n 'Content-Type': 'application/json; charset=utf-8',\n 'X-Content-Type-Options': 'nosniff',\n });\n response.end(body);\n}\n\ntype InvocationHeaders = {\n localToken: string | undefined;\n runtimeSessionId: string | undefined;\n executionAssertion: string | undefined;\n mcpCapability: string | undefined;\n modelCredential: string | undefined;\n};\n\nclass LocalExecutionHostRequestError extends Error {\n constructor(\n readonly status: number,\n readonly code: string,\n ) {\n super(code);\n }\n}\n\nfunction takeInvocationHeaders(request: IncomingMessage): InvocationHeaders {\n const extracted = {\n localToken: extractSensitiveHeader(\n request,\n EXECUTION_HOST_LOCAL_TOKEN_HEADER,\n ),\n runtimeSessionId: extractSensitiveHeader(\n request,\n AGENTCORE_RUNTIME_SESSION_HEADER,\n ),\n executionAssertion: extractSensitiveHeader(\n request,\n EXECUTION_ASSERTION_HEADER,\n ),\n mcpCapability: extractSensitiveHeader(request, MCP_CAPABILITY_HEADER),\n modelCredential: extractSensitiveHeader(request, MODEL_CREDENTIAL_HEADER),\n };\n if (Object.values(extracted).some((header) => header.duplicate)) {\n throw new LocalExecutionHostRequestError(\n 400,\n 'duplicate_sensitive_header',\n );\n }\n return Object.fromEntries(\n Object.entries(extracted).map(([name, header]) => [name, header.value]),\n ) as InvocationHeaders;\n}\n\nfunction parseSensitiveJson(value: string | undefined): unknown {\n if (!value) {\n return undefined;\n }\n try {\n return JSON.parse(value) as unknown;\n } catch {\n return undefined;\n }\n}\n\nfunction extractSensitiveHeader(\n request: IncomingMessage,\n name: string,\n): { value: string | undefined; duplicate: boolean } {\n const occurrences = request.rawHeaders.reduce(\n (count, headerName, index) => count\n + (index % 2 === 0 && headerName.toLowerCase() === name ? 1 : 0),\n 0,\n );\n const value = request.headers[name];\n request.headers[name] = value === undefined\n ? undefined\n : REDACTED_HEADER_VALUE;\n for (let index = 0; index < request.rawHeaders.length; index += 2) {\n if (request.rawHeaders[index]?.toLowerCase() === name) {\n request.rawHeaders[index + 1] = REDACTED_HEADER_VALUE;\n }\n }\n return {\n value: Array.isArray(value) ? undefined : value,\n duplicate: occurrences > 1 || Array.isArray(value),\n };\n}\n\nfunction assertInvocationRoute(request: IncomingMessage): void {\n if (request.method !== 'POST') {\n throw new LocalExecutionHostRequestError(405, 'method_not_allowed');\n }\n if (request.url !== '/invocations') {\n throw new LocalExecutionHostRequestError(404, 'not_found');\n }\n const contentType = request.headers['content-type']\n ?.split(';', 1)[0]\n ?.trim()\n .toLowerCase();\n if (contentType !== 'application/json') {\n throw new LocalExecutionHostRequestError(\n 415,\n 'unsupported_media_type',\n );\n }\n}\n\nfunction assertLocalToken(actual: string | undefined, expected: string): void {\n if (!actual || !constantTimeEqual(actual, expected)) {\n throw new LocalExecutionHostRequestError(401, 'invalid_local_token');\n }\n}\n\nfunction constantTimeEqual(left: string, right: string): boolean {\n const leftHash = createHash('sha256').update(left).digest();\n const rightHash = createHash('sha256').update(right).digest();\n return timingSafeEqual(leftHash, rightHash);\n}\n\nasync function readJsonBody(\n request: IncomingMessage,\n signal: AbortSignal,\n): Promise<unknown> {\n const chunks: Buffer[] = [];\n let totalBytes = 0;\n for await (const rawChunk of request) {\n signal.throwIfAborted();\n const chunk = Buffer.isBuffer(rawChunk)\n ? rawChunk\n : Buffer.from(rawChunk as Uint8Array);\n totalBytes += chunk.byteLength;\n if (totalBytes > MAX_REQUEST_BODY_BYTES) {\n throw new LocalExecutionHostRequestError(413, 'request_too_large');\n }\n chunks.push(chunk);\n }\n if (totalBytes === 0) {\n throw new LocalExecutionHostRequestError(400, 'invalid_request');\n }\n try {\n return JSON.parse(Buffer.concat(chunks, totalBytes).toString('utf8'));\n } catch {\n throw new LocalExecutionHostRequestError(400, 'invalid_request');\n }\n}\n\nfunction parseRequestValue<T>(\n schema: z.ZodType<T>,\n value: unknown,\n status: number,\n code: string,\n): T {\n const parsed = schema.safeParse(value);\n if (!parsed.success) {\n throw new LocalExecutionHostRequestError(status, code);\n }\n return parsed.data;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heddleagent/execution-host-client",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "Contracts, execution authority, lifecycle services, and adopter clients for compatible Heddle Execution Hosts",
|
|
5
5
|
"author": "Jay / Fienna Liang <roackb2@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
package/spec/v1/openapi.json
CHANGED
|
@@ -49,14 +49,14 @@
|
|
|
49
49
|
}
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
|
-
"name": "x-heddle-execution-host-model-
|
|
52
|
+
"name": "x-heddle-execution-host-model-credential",
|
|
53
53
|
"in": "header",
|
|
54
54
|
"required": true,
|
|
55
|
-
"description": "
|
|
55
|
+
"description": "JSON-encoded invocation-scoped model credential. OAuth refresh material is forbidden. The header must be scrubbed before parsing or logging.",
|
|
56
56
|
"schema": {
|
|
57
57
|
"type": "string",
|
|
58
|
-
"minLength":
|
|
59
|
-
"maxLength":
|
|
58
|
+
"minLength": 16,
|
|
59
|
+
"maxLength": 8192
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
62
|
{
|
|
@@ -441,6 +441,64 @@
|
|
|
441
441
|
}
|
|
442
442
|
}
|
|
443
443
|
},
|
|
444
|
+
"ModelCredential": {
|
|
445
|
+
"oneOf": [
|
|
446
|
+
{
|
|
447
|
+
"type": "object",
|
|
448
|
+
"properties": {
|
|
449
|
+
"type": {
|
|
450
|
+
"type": "string",
|
|
451
|
+
"const": "api-key"
|
|
452
|
+
},
|
|
453
|
+
"apiKey": {
|
|
454
|
+
"type": "string",
|
|
455
|
+
"minLength": 8,
|
|
456
|
+
"maxLength": 4096
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
"required": [
|
|
460
|
+
"type",
|
|
461
|
+
"apiKey"
|
|
462
|
+
],
|
|
463
|
+
"additionalProperties": false
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
"type": "object",
|
|
467
|
+
"properties": {
|
|
468
|
+
"type": {
|
|
469
|
+
"type": "string",
|
|
470
|
+
"const": "oauth-access-token"
|
|
471
|
+
},
|
|
472
|
+
"provider": {
|
|
473
|
+
"type": "string",
|
|
474
|
+
"const": "openai"
|
|
475
|
+
},
|
|
476
|
+
"accessToken": {
|
|
477
|
+
"type": "string",
|
|
478
|
+
"minLength": 8,
|
|
479
|
+
"maxLength": 4096
|
|
480
|
+
},
|
|
481
|
+
"expiresAt": {
|
|
482
|
+
"type": "integer",
|
|
483
|
+
"exclusiveMinimum": 0,
|
|
484
|
+
"maximum": 9007199254740991
|
|
485
|
+
},
|
|
486
|
+
"accountId": {
|
|
487
|
+
"type": "string",
|
|
488
|
+
"minLength": 1,
|
|
489
|
+
"maxLength": 512
|
|
490
|
+
}
|
|
491
|
+
},
|
|
492
|
+
"required": [
|
|
493
|
+
"type",
|
|
494
|
+
"provider",
|
|
495
|
+
"accessToken",
|
|
496
|
+
"expiresAt"
|
|
497
|
+
],
|
|
498
|
+
"additionalProperties": false
|
|
499
|
+
}
|
|
500
|
+
]
|
|
501
|
+
},
|
|
444
502
|
"RuntimePublicResult": {
|
|
445
503
|
"type": "object",
|
|
446
504
|
"properties": {
|
|
@@ -242,6 +242,64 @@
|
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
},
|
|
245
|
+
"ModelCredential": {
|
|
246
|
+
"oneOf": [
|
|
247
|
+
{
|
|
248
|
+
"type": "object",
|
|
249
|
+
"properties": {
|
|
250
|
+
"type": {
|
|
251
|
+
"type": "string",
|
|
252
|
+
"const": "api-key"
|
|
253
|
+
},
|
|
254
|
+
"apiKey": {
|
|
255
|
+
"type": "string",
|
|
256
|
+
"minLength": 8,
|
|
257
|
+
"maxLength": 4096
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
"required": [
|
|
261
|
+
"type",
|
|
262
|
+
"apiKey"
|
|
263
|
+
],
|
|
264
|
+
"additionalProperties": false
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"type": "object",
|
|
268
|
+
"properties": {
|
|
269
|
+
"type": {
|
|
270
|
+
"type": "string",
|
|
271
|
+
"const": "oauth-access-token"
|
|
272
|
+
},
|
|
273
|
+
"provider": {
|
|
274
|
+
"type": "string",
|
|
275
|
+
"const": "openai"
|
|
276
|
+
},
|
|
277
|
+
"accessToken": {
|
|
278
|
+
"type": "string",
|
|
279
|
+
"minLength": 8,
|
|
280
|
+
"maxLength": 4096
|
|
281
|
+
},
|
|
282
|
+
"expiresAt": {
|
|
283
|
+
"type": "integer",
|
|
284
|
+
"exclusiveMinimum": 0,
|
|
285
|
+
"maximum": 9007199254740991
|
|
286
|
+
},
|
|
287
|
+
"accountId": {
|
|
288
|
+
"type": "string",
|
|
289
|
+
"minLength": 1,
|
|
290
|
+
"maxLength": 512
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
"required": [
|
|
294
|
+
"type",
|
|
295
|
+
"provider",
|
|
296
|
+
"accessToken",
|
|
297
|
+
"expiresAt"
|
|
298
|
+
],
|
|
299
|
+
"additionalProperties": false
|
|
300
|
+
}
|
|
301
|
+
]
|
|
302
|
+
},
|
|
245
303
|
"RuntimePublicResult": {
|
|
246
304
|
"type": "object",
|
|
247
305
|
"properties": {
|