agentfootprint 9.64.0 → 9.66.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/dist/adapters/hosting/foundryResponses.js +110 -0
- package/dist/adapters/hosting/foundryResponses.js.map +1 -0
- package/dist/adapters/hosting/responsesWire.js +322 -0
- package/dist/adapters/hosting/responsesWire.js.map +1 -0
- package/dist/adapters/identity/agentcore.js +118 -2
- package/dist/adapters/identity/agentcore.js.map +1 -1
- package/dist/adapters/observability/agentcore.js +61 -1
- package/dist/adapters/observability/agentcore.js.map +1 -1
- package/dist/adapters/observability/otel.js +12 -3
- package/dist/adapters/observability/otel.js.map +1 -1
- package/dist/esm/adapters/hosting/foundryResponses.d.ts +89 -0
- package/dist/esm/adapters/hosting/foundryResponses.js +106 -0
- package/dist/esm/adapters/hosting/foundryResponses.js.map +1 -0
- package/dist/esm/adapters/hosting/responsesWire.d.ts +75 -0
- package/dist/esm/adapters/hosting/responsesWire.js +316 -0
- package/dist/esm/adapters/hosting/responsesWire.js.map +1 -0
- package/dist/esm/adapters/identity/agentcore.d.ts +115 -1
- package/dist/esm/adapters/identity/agentcore.js +117 -2
- package/dist/esm/adapters/identity/agentcore.js.map +1 -1
- package/dist/esm/adapters/observability/agentcore.d.ts +50 -0
- package/dist/esm/adapters/observability/agentcore.js +59 -0
- package/dist/esm/adapters/observability/agentcore.js.map +1 -1
- package/dist/esm/adapters/observability/otel.d.ts +73 -3
- package/dist/esm/adapters/observability/otel.js +12 -3
- package/dist/esm/adapters/observability/otel.js.map +1 -1
- package/dist/esm/hosting/errors.d.ts +43 -0
- package/dist/esm/hosting/errors.js +52 -0
- package/dist/esm/hosting/errors.js.map +1 -1
- package/dist/esm/hosting/httpHost.d.ts +133 -4
- package/dist/esm/hosting/httpHost.js +120 -22
- package/dist/esm/hosting/httpHost.js.map +1 -1
- package/dist/esm/hosting/index.d.ts +2 -2
- package/dist/esm/hosting/index.js +1 -1
- package/dist/esm/hosting/index.js.map +1 -1
- package/dist/esm/hosting-providers.d.ts +17 -0
- package/dist/esm/hosting-providers.js +19 -0
- package/dist/esm/hosting-providers.js.map +1 -1
- package/dist/esm/identity.d.ts +1 -1
- package/dist/esm/identity.js +5 -1
- package/dist/esm/identity.js.map +1 -1
- package/dist/esm/observability-providers.d.ts +1 -1
- package/dist/esm/observability-providers.js +5 -1
- package/dist/esm/observability-providers.js.map +1 -1
- package/dist/hosting/errors.js +55 -1
- package/dist/hosting/errors.js.map +1 -1
- package/dist/hosting/httpHost.js +119 -21
- package/dist/hosting/httpHost.js.map +1 -1
- package/dist/hosting/index.js +4 -2
- package/dist/hosting/index.js.map +1 -1
- package/dist/hosting-providers.js +30 -1
- package/dist/hosting-providers.js.map +1 -1
- package/dist/identity.js +5 -1
- package/dist/identity.js.map +1 -1
- package/dist/observability-providers.js +6 -1
- package/dist/observability-providers.js.map +1 -1
- package/dist/types/adapters/hosting/foundryResponses.d.ts +90 -0
- package/dist/types/adapters/hosting/foundryResponses.d.ts.map +1 -0
- package/dist/types/adapters/hosting/responsesWire.d.ts +76 -0
- package/dist/types/adapters/hosting/responsesWire.d.ts.map +1 -0
- package/dist/types/adapters/identity/agentcore.d.ts +115 -1
- package/dist/types/adapters/identity/agentcore.d.ts.map +1 -1
- package/dist/types/adapters/observability/agentcore.d.ts +50 -0
- package/dist/types/adapters/observability/agentcore.d.ts.map +1 -1
- package/dist/types/adapters/observability/otel.d.ts +73 -3
- package/dist/types/adapters/observability/otel.d.ts.map +1 -1
- package/dist/types/hosting/errors.d.ts +43 -0
- package/dist/types/hosting/errors.d.ts.map +1 -1
- package/dist/types/hosting/httpHost.d.ts +133 -4
- package/dist/types/hosting/httpHost.d.ts.map +1 -1
- package/dist/types/hosting/index.d.ts +2 -2
- package/dist/types/hosting/index.d.ts.map +1 -1
- package/dist/types/hosting-providers.d.ts +17 -0
- package/dist/types/hosting-providers.d.ts.map +1 -1
- package/dist/types/identity.d.ts +1 -1
- package/dist/types/identity.d.ts.map +1 -1
- package/dist/types/observability-providers.d.ts +1 -1
- package/dist/types/observability-providers.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* adapters/hosting/foundryResponses — an agent behind Microsoft Foundry's
|
|
4
|
+
* hosted-agent contract.
|
|
5
|
+
*
|
|
6
|
+
* ── The split, and why it is here ────────────────────────────────────────────
|
|
7
|
+
* Two different things are needed to serve a Foundry hosted agent, and only one
|
|
8
|
+
* of them is Microsoft's:
|
|
9
|
+
*
|
|
10
|
+
* • The **Responses protocol** — `input` items, a `response` object, the
|
|
11
|
+
* named streaming lifecycle. That is a protocol several runtimes speak, so
|
|
12
|
+
* it lives in `responsesWire.ts` with no vendor in it.
|
|
13
|
+
* • The **hosting contract** — port 8088, `POST /responses`, a `HEAD` probe
|
|
14
|
+
* on the same path, `GET /readiness` answering `{"status":"healthy"}`, and
|
|
15
|
+
* `agent_session_id` as a session alias. That IS this runtime's contract,
|
|
16
|
+
* the same way `/invocations` and `X-Amzn-…` are another's, and it is what
|
|
17
|
+
* this file supplies.
|
|
18
|
+
*
|
|
19
|
+
* So this file is a configuration, not an implementation. Everything hard —
|
|
20
|
+
* draining on close, aborting when the caller hangs up, failing a handler that
|
|
21
|
+
* throws or answers nothing — is `httpHost`'s, shared with every other adapter
|
|
22
|
+
* rather than reimplemented here where the two would drift.
|
|
23
|
+
*
|
|
24
|
+
* ── What it does NOT do ──────────────────────────────────────────────────────
|
|
25
|
+
* **Workflow Visualizer topology is not provided.** The Inspector can invoke
|
|
26
|
+
* this host and render its answer; it does not learn that the answer came from
|
|
27
|
+
* four composed agents, because nothing in the Responses protocol carries that
|
|
28
|
+
* and inventing a channel for it would be claiming a compatibility this has
|
|
29
|
+
* never demonstrated. An agent's internal structure is readable from
|
|
30
|
+
* agentfootprint's own recorders.
|
|
31
|
+
*
|
|
32
|
+
* Everything the protocol does not carry — tool calls, image and file input,
|
|
33
|
+
* function-call output, structured output — is refused by name. See
|
|
34
|
+
* `responsesWire.ts`.
|
|
35
|
+
*
|
|
36
|
+
* This is an **inbound hosting adapter**: it is the door callers arrive at. It
|
|
37
|
+
* is not a model provider, and it has nothing to do with which model the agent
|
|
38
|
+
* calls — for Foundry models, that is `openai()` with the endpoint's base URL.
|
|
39
|
+
*
|
|
40
|
+
* @example An agent behind the Inspector
|
|
41
|
+
* import { foundryResponsesHost, memorySessions, standingAgent } from 'agentfootprint/hosting';
|
|
42
|
+
*
|
|
43
|
+
* const handle = await standingAgent({
|
|
44
|
+
* agent,
|
|
45
|
+
* sessions: memorySessions(),
|
|
46
|
+
* host: foundryResponsesHost(),
|
|
47
|
+
* });
|
|
48
|
+
* process.on('SIGTERM', () => void handle.close());
|
|
49
|
+
*/
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
exports.foundryResponsesHost = exports.FOUNDRY_SESSION_FIELDS = exports.FOUNDRY_READINESS_PATH = exports.FOUNDRY_INVOKE_PATH = exports.DEFAULT_FOUNDRY_PORT = void 0;
|
|
52
|
+
const httpHost_js_1 = require("../../hosting/httpHost.js");
|
|
53
|
+
const responsesWire_js_1 = require("./responsesWire.js");
|
|
54
|
+
/** The port a Foundry hosted agent is expected on. */
|
|
55
|
+
exports.DEFAULT_FOUNDRY_PORT = 8088;
|
|
56
|
+
/** The path that takes a turn. */
|
|
57
|
+
exports.FOUNDRY_INVOKE_PATH = '/responses';
|
|
58
|
+
/** The path a Foundry hosted agent answers a readiness probe on. */
|
|
59
|
+
exports.FOUNDRY_READINESS_PATH = '/readiness';
|
|
60
|
+
/**
|
|
61
|
+
* Session aliases this contract accepts, in precedence order.
|
|
62
|
+
*
|
|
63
|
+
* `conversation` is the protocol's own; `agent_session_id` is this runtime's;
|
|
64
|
+
* `session_id` is the spelling several clients send anyway. First one present
|
|
65
|
+
* wins, so a caller using any of the three reaches the same session.
|
|
66
|
+
*/
|
|
67
|
+
exports.FOUNDRY_SESSION_FIELDS = [
|
|
68
|
+
'conversation',
|
|
69
|
+
'agent_session_id',
|
|
70
|
+
'session_id',
|
|
71
|
+
];
|
|
72
|
+
/**
|
|
73
|
+
* One mebibyte: large enough for any resume or job description this door was
|
|
74
|
+
* built to carry, small enough that a hostile caller cannot spend the heap.
|
|
75
|
+
*/
|
|
76
|
+
const DEFAULT_MAX_BODY_BYTES = 1_048_576;
|
|
77
|
+
/**
|
|
78
|
+
* An {@link HttpHost} speaking Foundry's hosted-agent contract.
|
|
79
|
+
*
|
|
80
|
+
* @param options - Port, interface, model label and body ceiling.
|
|
81
|
+
*/
|
|
82
|
+
function foundryResponsesHost(options = {}) {
|
|
83
|
+
const { server, onUnhandled, model, hostname } = options;
|
|
84
|
+
// `port` and `hostname` name a socket a caller-owned server already bound, so
|
|
85
|
+
// they are passed only when this host is the one binding. Defaulting the port
|
|
86
|
+
// unconditionally would turn "attach to my server" into a refusal.
|
|
87
|
+
const socket = server
|
|
88
|
+
? { server }
|
|
89
|
+
: {
|
|
90
|
+
port: options.port ?? exports.DEFAULT_FOUNDRY_PORT,
|
|
91
|
+
...(hostname === undefined ? {} : { hostname }),
|
|
92
|
+
...(onUnhandled === undefined ? {} : { onUnhandled }),
|
|
93
|
+
};
|
|
94
|
+
return (0, httpHost_js_1.httpHost)({
|
|
95
|
+
name: 'foundryResponsesHost',
|
|
96
|
+
wire: (0, responsesWire_js_1.responsesWire)({
|
|
97
|
+
...(model === undefined ? {} : { defaultModel: model }),
|
|
98
|
+
sessionFields: exports.FOUNDRY_SESSION_FIELDS,
|
|
99
|
+
health: { status: 'healthy' },
|
|
100
|
+
}),
|
|
101
|
+
invokePath: exports.FOUNDRY_INVOKE_PATH,
|
|
102
|
+
healthPath: exports.FOUNDRY_READINESS_PATH,
|
|
103
|
+
// The Inspector asks whether the door is there before it uses it.
|
|
104
|
+
invokeHeadProbe: true,
|
|
105
|
+
maxBodyBytes: options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES,
|
|
106
|
+
...socket,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
exports.foundryResponsesHost = foundryResponsesHost;
|
|
110
|
+
//# sourceMappingURL=foundryResponses.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundryResponses.js","sourceRoot":"","sources":["../../../src/adapters/hosting/foundryResponses.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;;;AAIH,2DAAoE;AACpE,yDAAmD;AAEnD,sDAAsD;AACzC,QAAA,oBAAoB,GAAG,IAAI,CAAC;AAEzC,kCAAkC;AACrB,QAAA,mBAAmB,GAAG,YAAY,CAAC;AAEhD,oEAAoE;AACvD,QAAA,sBAAsB,GAAG,YAAY,CAAC;AAEnD;;;;;;GAMG;AACU,QAAA,sBAAsB,GAAsB;IACvD,cAAc;IACd,kBAAkB;IAClB,YAAY;CACb,CAAC;AAEF;;;GAGG;AACH,MAAM,sBAAsB,GAAG,SAAS,CAAC;AAqBzC;;;;GAIG;AACH,SAAgB,oBAAoB,CAAC,UAAuC,EAAE;IAC5E,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IACzD,8EAA8E;IAC9E,8EAA8E;IAC9E,mEAAmE;IACnE,MAAM,MAAM,GAAG,MAAM;QACnB,CAAC,CAAC,EAAE,MAAM,EAAE;QACZ,CAAC,CAAC;YACE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,4BAAoB;YAC1C,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;YAC/C,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;SACtD,CAAC;IAEN,OAAO,IAAA,sBAAQ,EAAC;QACd,IAAI,EAAE,sBAAsB;QAC5B,IAAI,EAAE,IAAA,gCAAa,EAAC;YAClB,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;YACvD,aAAa,EAAE,8BAAsB;YACrC,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE;SAC9B,CAAC;QACF,UAAU,EAAE,2BAAmB;QAC/B,UAAU,EAAE,8BAAsB;QAClC,kEAAkE;QAClE,eAAe,EAAE,IAAI;QACrB,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,sBAAsB;QAC5D,GAAG,MAAM;KACV,CAAC,CAAC;AACL,CAAC;AA3BD,oDA2BC"}
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* adapters/hosting/responsesWire — the Responses protocol, as an `HttpWire`.
|
|
4
|
+
*
|
|
5
|
+
* ── What this is, and what it deliberately is not ────────────────────────────
|
|
6
|
+
* This file speaks the **Responses** wire protocol: a request carries `input`
|
|
7
|
+
* as text or as message items, a reply is a `response` object with an id and a
|
|
8
|
+
* status, and a stream is a LIFECYCLE of named events that open the response,
|
|
9
|
+
* announce output, carry deltas, and close each part before closing the
|
|
10
|
+
* response itself.
|
|
11
|
+
*
|
|
12
|
+
* That protocol is nobody's product. It is the shape a Responses-speaking
|
|
13
|
+
* client sends and expects, and several hosted runtimes speak it. So it lives
|
|
14
|
+
* here as a dialect on its own, and the runtimes that CONFIGURE it — their
|
|
15
|
+
* paths, their ports, their probe bodies, their session aliases — live in their
|
|
16
|
+
* own files beside this one. Keeping the split means the next runtime that
|
|
17
|
+
* speaks Responses is a configuration rather than a copy, and it means no
|
|
18
|
+
* vendor's spelling ends up in the protocol.
|
|
19
|
+
*
|
|
20
|
+
* ── The subset ───────────────────────────────────────────────────────────────
|
|
21
|
+
* A text turn, streamed or not, with a session. Deliberately not the whole
|
|
22
|
+
* Responses API: tool calls, reasoning items, image/file input, structured
|
|
23
|
+
* output and function-call output are NOT carried, and each is REFUSED by name
|
|
24
|
+
* rather than dropped — a request whose content this dialect cannot represent
|
|
25
|
+
* is answered 400 before a turn is paid for, never answered 200 with the parts
|
|
26
|
+
* it happened to understand.
|
|
27
|
+
*
|
|
28
|
+
* @example A host that speaks Responses on paths of its own choosing
|
|
29
|
+
* httpHost({
|
|
30
|
+
* name: 'myResponsesHost',
|
|
31
|
+
* wire: responsesWire({ defaultModel: 'my-agent' }),
|
|
32
|
+
* invokePath: '/responses',
|
|
33
|
+
* healthPath: '/health',
|
|
34
|
+
* });
|
|
35
|
+
*/
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.responsesWire = exports.readResponsesSession = exports.readResponsesInput = exports.PUBLIC_FAILURE_MESSAGE = exports.DEFAULT_SESSION_FIELDS = void 0;
|
|
38
|
+
const node_crypto_1 = require("node:crypto");
|
|
39
|
+
const errors_js_1 = require("../../hosting/errors.js");
|
|
40
|
+
/** Body fields that may carry a session id, in the order they are consulted. */
|
|
41
|
+
exports.DEFAULT_SESSION_FIELDS = ['conversation', 'session_id'];
|
|
42
|
+
/**
|
|
43
|
+
* What a caller is told when a handler THREW.
|
|
44
|
+
*
|
|
45
|
+
* A thrown error's message is the author's note to their own logs — a query, a
|
|
46
|
+
* path, a token in a connection string — and none of it is the caller's. A
|
|
47
|
+
* handler that CHOSE to fail chose its words for the caller, so those travel
|
|
48
|
+
* unchanged. The host tells this dialect which happened; it never guesses from
|
|
49
|
+
* the message.
|
|
50
|
+
*/
|
|
51
|
+
exports.PUBLIC_FAILURE_MESSAGE = 'The agent could not complete this request.';
|
|
52
|
+
const DEFAULT_MODEL = 'agentfootprint';
|
|
53
|
+
function isRecord(value) {
|
|
54
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
55
|
+
}
|
|
56
|
+
function nonEmptyString(value) {
|
|
57
|
+
return typeof value === 'string' && value.trim() !== '' ? value : undefined;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The text of one message's content, or a refusal naming what was in it.
|
|
61
|
+
*
|
|
62
|
+
* Every non-text part is refused rather than skipped: a resume with an attached
|
|
63
|
+
* image, silently reduced to the text around it, is a wrong answer delivered
|
|
64
|
+
* confidently.
|
|
65
|
+
*/
|
|
66
|
+
function inputTextFromContent(content) {
|
|
67
|
+
if (typeof content === 'string')
|
|
68
|
+
return content;
|
|
69
|
+
if (!Array.isArray(content)) {
|
|
70
|
+
throw new errors_js_1.WireRequestRefusal('unsupported_input', 'message content must be text or an array of input_text parts');
|
|
71
|
+
}
|
|
72
|
+
const text = [];
|
|
73
|
+
for (const part of content) {
|
|
74
|
+
if (!isRecord(part) || part.type !== 'input_text' || typeof part.text !== 'string') {
|
|
75
|
+
const kind = isRecord(part) && typeof part.type === 'string' ? part.type : 'unknown';
|
|
76
|
+
throw new errors_js_1.WireRequestRefusal('unsupported_input', `this dialect carries text input only; '${kind}' input is not supported`);
|
|
77
|
+
}
|
|
78
|
+
text.push(part.text);
|
|
79
|
+
}
|
|
80
|
+
return text.join('');
|
|
81
|
+
}
|
|
82
|
+
/** The turn's text: a bare string, or the user message items that carry it. */
|
|
83
|
+
function readResponsesInput(input) {
|
|
84
|
+
if (typeof input === 'string')
|
|
85
|
+
return input;
|
|
86
|
+
if (input === undefined || input === null) {
|
|
87
|
+
throw new errors_js_1.WireRequestRefusal('invalid_input', 'input is required');
|
|
88
|
+
}
|
|
89
|
+
if (!Array.isArray(input)) {
|
|
90
|
+
throw new errors_js_1.WireRequestRefusal('invalid_input', 'input must be text or an array of Responses message items');
|
|
91
|
+
}
|
|
92
|
+
const messages = [];
|
|
93
|
+
for (const item of input) {
|
|
94
|
+
if (!isRecord(item)) {
|
|
95
|
+
throw new errors_js_1.WireRequestRefusal('invalid_input', 'each input item must be an object');
|
|
96
|
+
}
|
|
97
|
+
// `type` is optional in the Responses grammar for a plain message.
|
|
98
|
+
if (item.type !== undefined && item.type !== 'message') {
|
|
99
|
+
throw new errors_js_1.WireRequestRefusal('unsupported_input', `this dialect carries message items only; '${String(item.type)}' items are not supported`);
|
|
100
|
+
}
|
|
101
|
+
if (item.role !== 'user') {
|
|
102
|
+
throw new errors_js_1.WireRequestRefusal('unsupported_input', `this dialect carries user messages only; role '${String(item.role)}' is not supported`);
|
|
103
|
+
}
|
|
104
|
+
messages.push(inputTextFromContent(item.content));
|
|
105
|
+
}
|
|
106
|
+
return messages.join('\n\n');
|
|
107
|
+
}
|
|
108
|
+
exports.readResponsesInput = readResponsesInput;
|
|
109
|
+
/** The session this request claims, by whichever of its aliases it used. */
|
|
110
|
+
function readResponsesSession(body, fields) {
|
|
111
|
+
for (const field of fields) {
|
|
112
|
+
const value = body[field];
|
|
113
|
+
// `conversation` is an object in the Responses grammar and a bare string in
|
|
114
|
+
// several dialects of it. Both are read, because refusing the spelling a
|
|
115
|
+
// client already sends teaches nothing.
|
|
116
|
+
const found = isRecord(value) ? nonEmptyString(value.id) : nonEmptyString(value);
|
|
117
|
+
if (found !== undefined)
|
|
118
|
+
return found;
|
|
119
|
+
}
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
exports.readResponsesSession = readResponsesSession;
|
|
123
|
+
function identityFor(facts, options) {
|
|
124
|
+
const body = facts?.body ?? {};
|
|
125
|
+
const nonce = (0, node_crypto_1.randomUUID)().replaceAll('-', '');
|
|
126
|
+
return {
|
|
127
|
+
responseId: `resp_${nonce}`,
|
|
128
|
+
messageId: `msg_${nonce}`,
|
|
129
|
+
createdAt: Math.floor(Date.now() / 1000),
|
|
130
|
+
model: nonEmptyString(body.model) ?? options.defaultModel,
|
|
131
|
+
sessionId: readResponsesSession(body, options.sessionFields),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function outputPart(text) {
|
|
135
|
+
return { type: 'output_text', text, annotations: [], logprobs: [] };
|
|
136
|
+
}
|
|
137
|
+
function outputItem(identity, text, status) {
|
|
138
|
+
return {
|
|
139
|
+
id: identity.messageId,
|
|
140
|
+
type: 'message',
|
|
141
|
+
status,
|
|
142
|
+
role: 'assistant',
|
|
143
|
+
content: status === 'completed' ? [outputPart(text)] : [],
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function responseObject(identity, status, text = '', error = null) {
|
|
147
|
+
return {
|
|
148
|
+
id: identity.responseId,
|
|
149
|
+
object: 'response',
|
|
150
|
+
created_at: identity.createdAt,
|
|
151
|
+
status,
|
|
152
|
+
error,
|
|
153
|
+
incomplete_details: null,
|
|
154
|
+
instructions: null,
|
|
155
|
+
parallel_tool_calls: true,
|
|
156
|
+
model: identity.model,
|
|
157
|
+
output: status === 'completed' ? [outputItem(identity, text, 'completed')] : [],
|
|
158
|
+
conversation: identity.sessionId === undefined ? null : { id: identity.sessionId },
|
|
159
|
+
usage: null,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* What a caller may be told about a failure.
|
|
164
|
+
*
|
|
165
|
+
* A refusal this library authored carries a `code` and says what it says. A
|
|
166
|
+
* handler that threw carries none, and its words do not travel.
|
|
167
|
+
*/
|
|
168
|
+
function errorBody(message, code, origin) {
|
|
169
|
+
if (origin === 'threw') {
|
|
170
|
+
return { code: 'server_error', message: exports.PUBLIC_FAILURE_MESSAGE, type: 'server_error' };
|
|
171
|
+
}
|
|
172
|
+
return code === undefined
|
|
173
|
+
? { code: 'server_error', message, type: 'server_error' }
|
|
174
|
+
: { code, message, type: 'invalid_request_error' };
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* The nine-event lifecycle one streamed response is made of.
|
|
178
|
+
*
|
|
179
|
+
* Holds this response's identity and its sequence counter, which is why it is
|
|
180
|
+
* built per request: two callers sharing a counter would each see a stream that
|
|
181
|
+
* skips numbers, and two sharing an id would see each other's response.
|
|
182
|
+
*/
|
|
183
|
+
function responsesFraming(identity) {
|
|
184
|
+
let sequence = 0;
|
|
185
|
+
let outputStarted = false;
|
|
186
|
+
let streamed = '';
|
|
187
|
+
let sawDelta = false;
|
|
188
|
+
const frame = (event, fields) => ({
|
|
189
|
+
event,
|
|
190
|
+
data: { type: event, sequence_number: sequence++, ...fields },
|
|
191
|
+
});
|
|
192
|
+
/**
|
|
193
|
+
* The two frames that must precede any text. Emitted on the first delta
|
|
194
|
+
* rather than at open, because a response that fails before producing a word
|
|
195
|
+
* never opened an output item and should not claim it did.
|
|
196
|
+
*/
|
|
197
|
+
const begin = () => {
|
|
198
|
+
if (outputStarted)
|
|
199
|
+
return [];
|
|
200
|
+
outputStarted = true;
|
|
201
|
+
return [
|
|
202
|
+
frame('response.output_item.added', {
|
|
203
|
+
output_index: 0,
|
|
204
|
+
item: outputItem(identity, '', 'in_progress'),
|
|
205
|
+
}),
|
|
206
|
+
frame('response.content_part.added', {
|
|
207
|
+
item_id: identity.messageId,
|
|
208
|
+
output_index: 0,
|
|
209
|
+
content_index: 0,
|
|
210
|
+
part: outputPart(''),
|
|
211
|
+
}),
|
|
212
|
+
];
|
|
213
|
+
};
|
|
214
|
+
const delta = (text) => {
|
|
215
|
+
if (text === '')
|
|
216
|
+
return [];
|
|
217
|
+
const frames = begin();
|
|
218
|
+
sawDelta = true;
|
|
219
|
+
streamed += text;
|
|
220
|
+
frames.push(frame('response.output_text.delta', {
|
|
221
|
+
item_id: identity.messageId,
|
|
222
|
+
output_index: 0,
|
|
223
|
+
content_index: 0,
|
|
224
|
+
delta: text,
|
|
225
|
+
logprobs: [],
|
|
226
|
+
}));
|
|
227
|
+
return frames;
|
|
228
|
+
};
|
|
229
|
+
return {
|
|
230
|
+
open: () => [
|
|
231
|
+
frame('response.created', { response: responseObject(identity, 'in_progress') }),
|
|
232
|
+
frame('response.in_progress', { response: responseObject(identity, 'in_progress') }),
|
|
233
|
+
],
|
|
234
|
+
chunk: (text) => delta(text),
|
|
235
|
+
complete: (output) => {
|
|
236
|
+
const frames = [];
|
|
237
|
+
// A handler that streamed nothing still owes the caller its text, and one
|
|
238
|
+
// that streamed a PREFIX of it owes the rest. Anything else — a final
|
|
239
|
+
// output that contradicts what was streamed — is left as it was streamed:
|
|
240
|
+
// frames already on the wire cannot be taken back, and re-sending the
|
|
241
|
+
// whole text would duplicate what the caller already rendered.
|
|
242
|
+
if (!sawDelta)
|
|
243
|
+
frames.push(...delta(output));
|
|
244
|
+
else if (output.startsWith(streamed) && output.length > streamed.length) {
|
|
245
|
+
frames.push(...delta(output.slice(streamed.length)));
|
|
246
|
+
}
|
|
247
|
+
frames.push(...begin());
|
|
248
|
+
// THE COMPLETION IS AUTHORITATIVE — this library's law, and it outranks
|
|
249
|
+
// the protocol's own tidiness. When a handler's chunks were a preview of
|
|
250
|
+
// different final text rather than a prefix of it, the deltas already on
|
|
251
|
+
// the wire cannot be recalled, and this reports the ANSWER rather than
|
|
252
|
+
// the preview. The two then disagree, which is a documented limit of
|
|
253
|
+
// streaming a preview; reporting the preview as the answer would be a
|
|
254
|
+
// wrong answer, which is not.
|
|
255
|
+
const text = output;
|
|
256
|
+
frames.push(frame('response.output_text.done', {
|
|
257
|
+
item_id: identity.messageId,
|
|
258
|
+
output_index: 0,
|
|
259
|
+
content_index: 0,
|
|
260
|
+
text,
|
|
261
|
+
logprobs: [],
|
|
262
|
+
}), frame('response.content_part.done', {
|
|
263
|
+
item_id: identity.messageId,
|
|
264
|
+
output_index: 0,
|
|
265
|
+
content_index: 0,
|
|
266
|
+
part: outputPart(text),
|
|
267
|
+
}), frame('response.output_item.done', {
|
|
268
|
+
output_index: 0,
|
|
269
|
+
item: outputItem(identity, text, 'completed'),
|
|
270
|
+
}), frame('response.completed', { response: responseObject(identity, 'completed', text) }));
|
|
271
|
+
return frames;
|
|
272
|
+
},
|
|
273
|
+
failure: (message, code, origin) => [
|
|
274
|
+
frame('response.failed', {
|
|
275
|
+
response: responseObject(identity, 'failed', '', errorBody(message, code, origin)),
|
|
276
|
+
}),
|
|
277
|
+
],
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* An `HttpWire` speaking the Responses protocol.
|
|
282
|
+
*
|
|
283
|
+
* Pair it with `httpHost` and the paths your deployment contract names. The
|
|
284
|
+
* host keeps its own promises — draining, aborting on disconnect, failing a
|
|
285
|
+
* handler that throws or answers nothing — and this supplies only the dialect.
|
|
286
|
+
*/
|
|
287
|
+
function responsesWire(options = {}) {
|
|
288
|
+
const resolved = {
|
|
289
|
+
defaultModel: options.defaultModel ?? DEFAULT_MODEL,
|
|
290
|
+
sessionFields: options.sessionFields ?? exports.DEFAULT_SESSION_FIELDS,
|
|
291
|
+
};
|
|
292
|
+
const health = options.health ?? { status: 'ok' };
|
|
293
|
+
return {
|
|
294
|
+
readRequest(facts) {
|
|
295
|
+
const input = readResponsesInput(facts.body.input);
|
|
296
|
+
if (input.trim() === '') {
|
|
297
|
+
throw new errors_js_1.WireRequestRefusal('invalid_input', 'input text must not be empty');
|
|
298
|
+
}
|
|
299
|
+
const sessionId = readResponsesSession(facts.body, resolved.sessionFields);
|
|
300
|
+
return { input, ...(sessionId === undefined ? {} : { sessionId }) };
|
|
301
|
+
},
|
|
302
|
+
// This dialect's callers choose in the body and never touch `Accept`.
|
|
303
|
+
wantsStream: (facts) => facts.body.stream === true,
|
|
304
|
+
stream: (facts) => responsesFraming(identityFor(facts, resolved)),
|
|
305
|
+
health: () => health,
|
|
306
|
+
output: (output, facts) => responseObject(identityFor(facts, resolved), 'completed', output),
|
|
307
|
+
chunk: (text) => ({ type: 'response.output_text.delta', delta: text }),
|
|
308
|
+
failure: (message, code, facts, origin) => {
|
|
309
|
+
// A terminal that ended an ACCEPTED response is reported as a failed
|
|
310
|
+
// response object — that is what the protocol says a response that got
|
|
311
|
+
// as far as running and then stopped looks like. A coded refusal ended
|
|
312
|
+
// the REQUEST before any of that, and gets the error envelope a client
|
|
313
|
+
// reads off a 4xx.
|
|
314
|
+
if (code === undefined) {
|
|
315
|
+
return responseObject(identityFor(facts, resolved), 'failed', '', errorBody(message, undefined, origin));
|
|
316
|
+
}
|
|
317
|
+
return { error: errorBody(message, code, origin) };
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
exports.responsesWire = responsesWire;
|
|
322
|
+
//# sourceMappingURL=responsesWire.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responsesWire.js","sourceRoot":"","sources":["../../../src/adapters/hosting/responsesWire.ts"],"names":[],"mappings":"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"}
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
* `getCredential` first runs (or never, if you inject `_client` / `_sdk`).
|
|
85
85
|
*/
|
|
86
86
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
87
|
-
exports.agentCoreIdentity = void 0;
|
|
87
|
+
exports.completeAgentCoreAuthorization = exports.agentCoreIdentity = void 0;
|
|
88
88
|
const lazyRequire_js_1 = require("../../lib/lazyRequire.js");
|
|
89
89
|
const kinds_js_1 = require("../../identity/kinds.js");
|
|
90
90
|
/**
|
|
@@ -223,6 +223,20 @@ function createIdentityClient(options) {
|
|
|
223
223
|
async getWorkloadAccessTokenForUserId(input) {
|
|
224
224
|
return ((await send(mod.GetWorkloadAccessTokenForUserIdCommand, 'GetWorkloadAccessTokenForUserIdCommand', input)) ?? {});
|
|
225
225
|
},
|
|
226
|
+
async getResourceApiKey(input) {
|
|
227
|
+
const r = (await send(mod.GetResourceApiKeyCommand, 'GetResourceApiKeyCommand', input));
|
|
228
|
+
return { ...(r?.apiKey !== undefined && { apiKey: r.apiKey }) };
|
|
229
|
+
},
|
|
230
|
+
async completeResourceTokenAuth(input) {
|
|
231
|
+
// `CompleteResourceTokenAuthRequest` is `{ sessionUri, userIdentifier }`,
|
|
232
|
+
// where userIdentifier is a UNION with exactly one member set — the
|
|
233
|
+
// person's own token, or the id the agent asserts for them. Success is an
|
|
234
|
+
// empty 200, so there is nothing to map back.
|
|
235
|
+
await send(mod.CompleteResourceTokenAuthCommand, 'CompleteResourceTokenAuthCommand', {
|
|
236
|
+
sessionUri: input.sessionId,
|
|
237
|
+
userIdentifier: input.userToken !== undefined ? { userToken: input.userToken } : { userId: input.userId },
|
|
238
|
+
});
|
|
239
|
+
},
|
|
226
240
|
async getWorkloadAccessTokenForJWT(input) {
|
|
227
241
|
// `GetWorkloadAccessTokenForJWTRequest` is `{ workloadName, userToken }`,
|
|
228
242
|
// both required, and the response is `{ workloadAccessToken }` — verified
|
|
@@ -310,14 +324,50 @@ function agentCoreIdentity(options = {}) {
|
|
|
310
324
|
}
|
|
311
325
|
return requireWorkloadAccessToken(await c.getWorkloadAccessTokenForUserId({ workloadName: options.workloadName, userId }), 'GetWorkloadAccessTokenForUserId');
|
|
312
326
|
};
|
|
327
|
+
const userFlow = options.userFlow ?? 'consent';
|
|
328
|
+
const apiKeyServices = new Set(options.apiKeyServices ?? []);
|
|
329
|
+
const apiKeyHeader = options.apiKeyHeader ?? 'x-api-key';
|
|
313
330
|
return {
|
|
314
331
|
id: options.id ?? 'agentcore-identity',
|
|
315
332
|
async getCredential(req) {
|
|
316
333
|
const workloadIdentityToken = await resolveWorkloadToken(req);
|
|
334
|
+
// An API-key service never touches the OAuth path: different operation,
|
|
335
|
+
// different credential kind, and no consent round-trip exists for it.
|
|
336
|
+
if (apiKeyServices.has(req.service)) {
|
|
337
|
+
const c = getClient();
|
|
338
|
+
if (!c.getResourceApiKey) {
|
|
339
|
+
throw new Error(`agentCoreIdentity: '${req.service}' is listed in \`apiKeyServices\` but the ` +
|
|
340
|
+
'injected `_client` has no getResourceApiKey. Implement it, or drop the service ' +
|
|
341
|
+
'from the list to vend it as OAuth.');
|
|
342
|
+
}
|
|
343
|
+
if (!workloadIdentityToken) {
|
|
344
|
+
// Required on `GetResourceApiKeyRequest`, exactly as on the OAuth
|
|
345
|
+
// call — verified against the real SDK's types, not assumed. Sending
|
|
346
|
+
// without one buys an opaque ValidationException; this names the two
|
|
347
|
+
// ways to supply it instead.
|
|
348
|
+
throw new Error(`agentCoreIdentity: GetResourceApiKey for '${req.service}' requires a workload ` +
|
|
349
|
+
'identity token, and none was available for this request.\n' +
|
|
350
|
+
' Inside AgentCore Runtime the container is given one — pass it as ' +
|
|
351
|
+
'`workloadIdentityToken`.\n' +
|
|
352
|
+
' Elsewhere, configure `workloadName` so a per-user token is resolved first.');
|
|
353
|
+
}
|
|
354
|
+
const keyRes = await c.getResourceApiKey({
|
|
355
|
+
resourceCredentialProviderName: req.service,
|
|
356
|
+
workloadIdentityToken,
|
|
357
|
+
});
|
|
358
|
+
if (!keyRes.apiKey) {
|
|
359
|
+
throw new Error(`agentCoreIdentity: GetResourceApiKey for '${req.service}' returned no key.`);
|
|
360
|
+
}
|
|
361
|
+
return { status: 'issued', credential: (0, kinds_js_1.apiKey)(keyRes.apiKey, apiKeyHeader) };
|
|
362
|
+
}
|
|
317
363
|
const res = await getClient().getResourceOauth2Token({
|
|
318
364
|
resourceCredentialProviderName: req.service,
|
|
319
365
|
scopes: req.scopes ?? [],
|
|
320
|
-
oauth2Flow: req.mode === 'user'
|
|
366
|
+
oauth2Flow: req.mode === 'user'
|
|
367
|
+
? userFlow === 'exchange'
|
|
368
|
+
? 'ON_BEHALF_OF_TOKEN_EXCHANGE'
|
|
369
|
+
: 'USER_FEDERATION'
|
|
370
|
+
: 'M2M',
|
|
321
371
|
forceAuthentication: req.forceReauth ?? false,
|
|
322
372
|
...(workloadIdentityToken && { workloadIdentityToken }),
|
|
323
373
|
});
|
|
@@ -342,4 +392,70 @@ function agentCoreIdentity(options = {}) {
|
|
|
342
392
|
};
|
|
343
393
|
}
|
|
344
394
|
exports.agentCoreIdentity = agentCoreIdentity;
|
|
395
|
+
/**
|
|
396
|
+
* Tell AgentCore the person finished consenting, so the token lands in the vault.
|
|
397
|
+
*
|
|
398
|
+
* ── Where this runs, and why it is not a provider method ─────────────────────
|
|
399
|
+
* A 3LO consent has three actors and two processes. The agent asks for a
|
|
400
|
+
* credential and gets back `authorization-required` with a URL and a session
|
|
401
|
+
* id; the PERSON opens that URL in their browser and approves; AgentCore then
|
|
402
|
+
* redirects their browser to a callback route **your web app** owns. That route
|
|
403
|
+
* is where this belongs — a different process from the agent run, often a
|
|
404
|
+
* different service — so it takes its own connection options rather than
|
|
405
|
+
* pretending to be a method on a provider that route has never seen.
|
|
406
|
+
*
|
|
407
|
+
* Your route's job before calling this is the part nobody else can do: confirm
|
|
408
|
+
* the browser session really belongs to the user you are about to name. This
|
|
409
|
+
* function is the handshake, not the authentication.
|
|
410
|
+
*
|
|
411
|
+
* ── After it returns ─────────────────────────────────────────────────────────
|
|
412
|
+
* Nothing is handed back — success is an empty acknowledgement. The token now
|
|
413
|
+
* exists in the vault for that (workload, user), and the way to obtain it is to
|
|
414
|
+
* run the agent's request again: the next `getCredential` for that service
|
|
415
|
+
* returns `issued` where the last one returned `authorization-required`. In
|
|
416
|
+
* agentfootprint terms the consent is a PAUSE, and this is what makes the
|
|
417
|
+
* resume succeed.
|
|
418
|
+
*
|
|
419
|
+
* The authorization URL and its session are short-lived (AWS documents ten
|
|
420
|
+
* minutes) — a person who wanders off has to start the consent again, and the
|
|
421
|
+
* refusal you get is AgentCore's, not this adapter's.
|
|
422
|
+
*
|
|
423
|
+
* @example An Express-style callback route
|
|
424
|
+
* app.get('/oauth/callback', async (req, res) => {
|
|
425
|
+
* const user = await requireSignedInUser(req); // yours, and load-bearing
|
|
426
|
+
* await completeAgentCoreAuthorization({
|
|
427
|
+
* sessionId: String(req.query.session),
|
|
428
|
+
* userId: user.id,
|
|
429
|
+
* region: 'us-east-1',
|
|
430
|
+
* });
|
|
431
|
+
* res.send('Approved — you can return to the assistant.');
|
|
432
|
+
* });
|
|
433
|
+
*/
|
|
434
|
+
async function completeAgentCoreAuthorization(options) {
|
|
435
|
+
if (!options.sessionId) {
|
|
436
|
+
throw new Error('completeAgentCoreAuthorization: `sessionId` is required — it is the `sessionId` from ' +
|
|
437
|
+
'the `authorization-required` result that started this consent.');
|
|
438
|
+
}
|
|
439
|
+
if ((options.userToken === undefined) === (options.userId === undefined)) {
|
|
440
|
+
// Both or neither. Naming a person twice is ambiguous; naming them zero
|
|
441
|
+
// times completes a consent for nobody.
|
|
442
|
+
throw new Error('completeAgentCoreAuthorization: pass exactly one of `userToken` (the person’s own JWT, ' +
|
|
443
|
+
'preferred) or `userId` (an id you assert for them).');
|
|
444
|
+
}
|
|
445
|
+
const client = options._client ??
|
|
446
|
+
createIdentityClient({
|
|
447
|
+
...(options.region !== undefined && { region: options.region }),
|
|
448
|
+
...(options._sdk !== undefined && { _sdk: options._sdk }),
|
|
449
|
+
});
|
|
450
|
+
if (!client.completeResourceTokenAuth) {
|
|
451
|
+
throw new Error('completeAgentCoreAuthorization: the injected `_client` has no ' +
|
|
452
|
+
'completeResourceTokenAuth. Implement it, or omit `_client` to use the SDK.');
|
|
453
|
+
}
|
|
454
|
+
await client.completeResourceTokenAuth({
|
|
455
|
+
sessionId: options.sessionId,
|
|
456
|
+
...(options.userToken !== undefined && { userToken: options.userToken }),
|
|
457
|
+
...(options.userId !== undefined && { userId: options.userId }),
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
exports.completeAgentCoreAuthorization = completeAgentCoreAuthorization;
|
|
345
461
|
//# sourceMappingURL=agentcore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentcore.js","sourceRoot":"","sources":["../../../src/adapters/identity/agentcore.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;;;AAEH,6DAAuD;AAMvD,
|
|
1
|
+
{"version":3,"file":"agentcore.js","sourceRoot":"","sources":["../../../src/adapters/identity/agentcore.ts"],"names":[],"mappings":"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"}
|