@heddleagent/execution-host-client 6.0.0-next.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/LICENSE +21 -0
- package/README.md +305 -0
- package/dist/authority/index.d.ts +3 -0
- package/dist/authority/index.d.ts.map +1 -0
- package/dist/authority/index.js +2 -0
- package/dist/authority/index.js.map +1 -0
- package/dist/authority/jose-execution-authority.d.ts +14 -0
- package/dist/authority/jose-execution-authority.d.ts.map +1 -0
- package/dist/authority/jose-execution-authority.js +266 -0
- package/dist/authority/jose-execution-authority.js.map +1 -0
- package/dist/authority/types.d.ts +63 -0
- package/dist/authority/types.d.ts.map +1 -0
- package/dist/authority/types.js +2 -0
- package/dist/authority/types.js.map +1 -0
- package/dist/contracts/index.d.ts +163 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +149 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/conversation/durable-hosted-conversation-turn-service.d.ts +23 -0
- package/dist/conversation/durable-hosted-conversation-turn-service.d.ts.map +1 -0
- package/dist/conversation/durable-hosted-conversation-turn-service.js +273 -0
- package/dist/conversation/durable-hosted-conversation-turn-service.js.map +1 -0
- package/dist/conversation/hosted-conversation-turn-service.d.ts +17 -0
- package/dist/conversation/hosted-conversation-turn-service.d.ts.map +1 -0
- package/dist/conversation/hosted-conversation-turn-service.js +60 -0
- package/dist/conversation/hosted-conversation-turn-service.js.map +1 -0
- package/dist/conversation/index.d.ts +7 -0
- package/dist/conversation/index.d.ts.map +1 -0
- package/dist/conversation/index.js +5 -0
- package/dist/conversation/index.js.map +1 -0
- package/dist/conversation/lifecycle-types.d.ts +208 -0
- package/dist/conversation/lifecycle-types.d.ts.map +1 -0
- package/dist/conversation/lifecycle-types.js +92 -0
- package/dist/conversation/lifecycle-types.js.map +1 -0
- package/dist/conversation/types.d.ts +35 -0
- package/dist/conversation/types.d.ts.map +1 -0
- package/dist/conversation/types.js +11 -0
- package/dist/conversation/types.js.map +1 -0
- package/dist/http-sse/direct-http-execution-host.d.ts +12 -0
- package/dist/http-sse/direct-http-execution-host.d.ts.map +1 -0
- package/dist/http-sse/direct-http-execution-host.js +279 -0
- package/dist/http-sse/direct-http-execution-host.js.map +1 -0
- package/dist/http-sse/errors.d.ts +19 -0
- package/dist/http-sse/errors.d.ts.map +1 -0
- package/dist/http-sse/errors.js +29 -0
- package/dist/http-sse/errors.js.map +1 -0
- package/dist/http-sse/index.d.ts +4 -0
- package/dist/http-sse/index.d.ts.map +1 -0
- package/dist/http-sse/index.js +3 -0
- package/dist/http-sse/index.js.map +1 -0
- package/dist/http-sse/types.d.ts +20 -0
- package/dist/http-sse/types.d.ts.map +1 -0
- package/dist/http-sse/types.js +2 -0
- package/dist/http-sse/types.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/errors.d.ts +11 -0
- package/dist/mcp/errors.d.ts.map +1 -0
- package/dist/mcp/errors.js +15 -0
- package/dist/mcp/errors.js.map +1 -0
- package/dist/mcp/index.d.ts +5 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +3 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/jwt-capability-verifier.d.ts +12 -0
- package/dist/mcp/jwt-capability-verifier.d.ts.map +1 -0
- package/dist/mcp/jwt-capability-verifier.js +136 -0
- package/dist/mcp/jwt-capability-verifier.js.map +1 -0
- package/dist/mcp/node/index.d.ts +4 -0
- package/dist/mcp/node/index.d.ts.map +1 -0
- package/dist/mcp/node/index.js +3 -0
- package/dist/mcp/node/index.js.map +1 -0
- package/dist/mcp/node/json-toolset.d.ts +23 -0
- package/dist/mcp/node/json-toolset.d.ts.map +1 -0
- package/dist/mcp/node/json-toolset.js +94 -0
- package/dist/mcp/node/json-toolset.js.map +1 -0
- package/dist/mcp/node/streamable-http-mcp-service.d.ts +18 -0
- package/dist/mcp/node/streamable-http-mcp-service.d.ts.map +1 -0
- package/dist/mcp/node/streamable-http-mcp-service.js +229 -0
- package/dist/mcp/node/streamable-http-mcp-service.js.map +1 -0
- package/dist/mcp/node/types.d.ts +53 -0
- package/dist/mcp/node/types.d.ts.map +1 -0
- package/dist/mcp/node/types.js +2 -0
- package/dist/mcp/node/types.js.map +1 -0
- package/dist/mcp/types.d.ts +37 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +2 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/node/authority-key.d.ts +14 -0
- package/dist/node/authority-key.d.ts.map +1 -0
- package/dist/node/authority-key.js +89 -0
- package/dist/node/authority-key.js.map +1 -0
- package/dist/node/direct-credentials.d.ts +21 -0
- package/dist/node/direct-credentials.d.ts.map +1 -0
- package/dist/node/direct-credentials.js +47 -0
- package/dist/node/direct-credentials.js.map +1 -0
- package/dist/node/http-service.d.ts +21 -0
- package/dist/node/http-service.d.ts.map +1 -0
- package/dist/node/http-service.js +389 -0
- package/dist/node/http-service.js.map +1 -0
- package/dist/node/index.d.ts +6 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +4 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/types.d.ts +52 -0
- package/dist/node/types.d.ts.map +1 -0
- package/dist/node/types.js +2 -0
- package/dist/node/types.js.map +1 -0
- package/dist/testing/event-stream.d.ts +17 -0
- package/dist/testing/event-stream.d.ts.map +1 -0
- package/dist/testing/event-stream.js +83 -0
- package/dist/testing/event-stream.js.map +1 -0
- package/dist/testing/hosted-conversation-turn-store-conformance.d.ts +17 -0
- package/dist/testing/hosted-conversation-turn-store-conformance.d.ts.map +1 -0
- package/dist/testing/hosted-conversation-turn-store-conformance.js +137 -0
- package/dist/testing/hosted-conversation-turn-store-conformance.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +3 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/invocation.d.ts +20 -0
- package/dist/testing/invocation.d.ts.map +1 -0
- package/dist/testing/invocation.js +39 -0
- package/dist/testing/invocation.js.map +1 -0
- package/dist/testing/local-execution-host-contract-fixture.d.ts +21 -0
- package/dist/testing/local-execution-host-contract-fixture.d.ts.map +1 -0
- package/dist/testing/local-execution-host-contract-fixture.js +197 -0
- package/dist/testing/local-execution-host-contract-fixture.js.map +1 -0
- package/dist/testing/request.d.ts +10 -0
- package/dist/testing/request.d.ts.map +1 -0
- package/dist/testing/request.js +140 -0
- package/dist/testing/request.js.map +1 -0
- package/dist/testing/types.d.ts +42 -0
- package/dist/testing/types.d.ts.map +1 -0
- package/dist/testing/types.js +2 -0
- package/dist/testing/types.js.map +1 -0
- package/package.json +92 -0
- package/spec/v1/README.md +101 -0
- package/spec/v1/durable-hosted-conversation-lifecycle.md +139 -0
- package/spec/v1/fixtures/ambiguous-eof.sse +9 -0
- package/spec/v1/fixtures/authority.json +70 -0
- package/spec/v1/fixtures/cancelled.sse +9 -0
- package/spec/v1/fixtures/durable-conversation-lifecycle.json +890 -0
- package/spec/v1/fixtures/invalid-request-extra-field.json +8 -0
- package/spec/v1/fixtures/invalid-sequence-gap.sse +9 -0
- package/spec/v1/fixtures/manifest.json +53 -0
- package/spec/v1/fixtures/valid-request.json +7 -0
- package/spec/v1/fixtures/valid-result.sse +13 -0
- package/spec/v1/openapi.json +896 -0
- package/spec/v1/schema-bundle.json +1286 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { isExecutionHostTerminalEvent, } from '../contracts/index.js';
|
|
4
|
+
import { ExecutionHostInvocationCancelledError, ExecutionHostProtocolError, ExecutionHostRejectedError, ExecutionHostStreamInterruptedError, } from '../http-sse/index.js';
|
|
5
|
+
import { HostedConversationAcceptedTurnSchema, HostedConversationExpiredTurnReconciliationSchema, HostedConversationRequestedTurnSchema, HostedConversationTurnSettlementSchema, } from './lifecycle-types.js';
|
|
6
|
+
import { HostedConversationTurnInputSchema } from './types.js';
|
|
7
|
+
const DEFAULT_MAX_SUMMARY_CHARACTERS = 100_000;
|
|
8
|
+
const DEFAULT_EXPIRED_TURN_GRACE_MS = 60_000;
|
|
9
|
+
const LifecycleOptionsSchema = z.object({
|
|
10
|
+
maxSummaryCharacters: z.number().int().positive().max(1_000_000),
|
|
11
|
+
expiredTurnGraceMs: z.number().int().nonnegative().max(86_400_000),
|
|
12
|
+
}).strict();
|
|
13
|
+
const MODEL_FAILURE_CODE = {
|
|
14
|
+
authentication: 'model_authentication',
|
|
15
|
+
permission: 'model_permission',
|
|
16
|
+
quota: 'model_quota',
|
|
17
|
+
rate_limit: 'model_rate_limit',
|
|
18
|
+
context_window: 'model_context_window',
|
|
19
|
+
request: 'model_request',
|
|
20
|
+
transport: 'model_transport',
|
|
21
|
+
empty_response: 'model_empty_response',
|
|
22
|
+
unknown: 'model_unknown',
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Applies one reusable durable lifecycle around an Execution Host turn.
|
|
26
|
+
*
|
|
27
|
+
* Requested state is written before execution starts. Accepted and terminal
|
|
28
|
+
* writes complete before their corresponding public events are released. A
|
|
29
|
+
* persistence failure therefore fails closed instead of acknowledging state
|
|
30
|
+
* that the adopter cannot later recover.
|
|
31
|
+
*/
|
|
32
|
+
export class DurableHostedConversationTurnService {
|
|
33
|
+
#turns;
|
|
34
|
+
#store;
|
|
35
|
+
#maxSummaryCharacters;
|
|
36
|
+
#expiredTurnGraceMs;
|
|
37
|
+
#now;
|
|
38
|
+
constructor(config, options = {}) {
|
|
39
|
+
const lifecycle = LifecycleOptionsSchema.parse({
|
|
40
|
+
maxSummaryCharacters: config.maxSummaryCharacters
|
|
41
|
+
?? DEFAULT_MAX_SUMMARY_CHARACTERS,
|
|
42
|
+
expiredTurnGraceMs: config.expiredTurnGraceMs
|
|
43
|
+
?? DEFAULT_EXPIRED_TURN_GRACE_MS,
|
|
44
|
+
});
|
|
45
|
+
this.#turns = config.turns;
|
|
46
|
+
this.#store = config.store;
|
|
47
|
+
this.#maxSummaryCharacters = lifecycle.maxSummaryCharacters;
|
|
48
|
+
this.#expiredTurnGraceMs = lifecycle.expiredTurnGraceMs;
|
|
49
|
+
this.#now = options.now ?? (() => new Date());
|
|
50
|
+
}
|
|
51
|
+
async *streamTurn(rawInput) {
|
|
52
|
+
const input = HostedConversationTurnInputSchema.parse(rawInput);
|
|
53
|
+
const scope = Object.freeze({ ...input.scope });
|
|
54
|
+
const turn = { ...input, scope };
|
|
55
|
+
const identity = {
|
|
56
|
+
invocationId: turn.invocationId,
|
|
57
|
+
scope,
|
|
58
|
+
};
|
|
59
|
+
await this.#store.createTurn(HostedConversationRequestedTurnSchema.parse({
|
|
60
|
+
...identity,
|
|
61
|
+
prompt: turn.prompt,
|
|
62
|
+
...(turn.deadlineAt ? { deadlineAt: turn.deadlineAt } : {}),
|
|
63
|
+
requestedAt: this.#now().toISOString(),
|
|
64
|
+
}));
|
|
65
|
+
let persistenceState = 'open';
|
|
66
|
+
let streamAccepted = false;
|
|
67
|
+
const settle = async (settlement) => {
|
|
68
|
+
persistenceState = 'settling';
|
|
69
|
+
await this.#store.settleTurn(HostedConversationTurnSettlementSchema.parse({
|
|
70
|
+
...identity,
|
|
71
|
+
...settlement,
|
|
72
|
+
}));
|
|
73
|
+
persistenceState = 'settled';
|
|
74
|
+
};
|
|
75
|
+
try {
|
|
76
|
+
turn.signal?.throwIfAborted();
|
|
77
|
+
for await (const event of this.#turns.streamTurn(turn)) {
|
|
78
|
+
if (event.kind === 'accepted') {
|
|
79
|
+
if (streamAccepted) {
|
|
80
|
+
throw new ExecutionHostProtocolError('Hosted turn emitted more than one accepted event.');
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
await this.#store.recordAccepted(HostedConversationAcceptedTurnSchema.parse({
|
|
84
|
+
...identity,
|
|
85
|
+
runId: event.runId,
|
|
86
|
+
acceptedAt: event.timestamp,
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
persistenceState = 'write_failed';
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
streamAccepted = true;
|
|
94
|
+
yield event;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (!streamAccepted) {
|
|
98
|
+
throw new ExecutionHostProtocolError('Hosted turn emitted data before its accepted event.');
|
|
99
|
+
}
|
|
100
|
+
if (isExecutionHostTerminalEvent(event)) {
|
|
101
|
+
const projection = projectTerminalEvent(event, this.#maxSummaryCharacters);
|
|
102
|
+
await settle({
|
|
103
|
+
...projection.settlement,
|
|
104
|
+
settledAt: event.timestamp,
|
|
105
|
+
});
|
|
106
|
+
yield projection.event;
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
yield event;
|
|
110
|
+
}
|
|
111
|
+
if (!streamAccepted) {
|
|
112
|
+
throw new ExecutionHostProtocolError('Hosted turn stream omitted its accepted event.');
|
|
113
|
+
}
|
|
114
|
+
if (persistenceState === 'open') {
|
|
115
|
+
await settle({
|
|
116
|
+
status: 'interrupted',
|
|
117
|
+
failureCode: 'stream_ended_without_terminal',
|
|
118
|
+
settledAt: this.#now().toISOString(),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (persistenceState === 'open') {
|
|
124
|
+
await settle({
|
|
125
|
+
...projectThrownFailure(error, turn.signal),
|
|
126
|
+
settledAt: this.#now().toISOString(),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
// Returning from a consumer closes an async generator without throwing.
|
|
133
|
+
// Settle that still-open invocation before releasing the managed stream.
|
|
134
|
+
if (persistenceState === 'open') {
|
|
135
|
+
await settle({
|
|
136
|
+
status: 'interrupted',
|
|
137
|
+
failureCode: 'stream_ended_without_terminal',
|
|
138
|
+
settledAt: this.#now().toISOString(),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/** Reconciles only expired open turns within one already-authorized scope. */
|
|
144
|
+
interruptExpiredTurns(scope) {
|
|
145
|
+
return interruptExpiredHostedConversationTurns(this.#store, scope, {
|
|
146
|
+
expiredTurnGraceMs: this.#expiredTurnGraceMs,
|
|
147
|
+
now: this.#now,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
export function interruptExpiredHostedConversationTurns(store, scope, options = {}) {
|
|
152
|
+
const { expiredTurnGraceMs } = LifecycleOptionsSchema.pick({
|
|
153
|
+
expiredTurnGraceMs: true,
|
|
154
|
+
}).parse({
|
|
155
|
+
expiredTurnGraceMs: options.expiredTurnGraceMs
|
|
156
|
+
?? DEFAULT_EXPIRED_TURN_GRACE_MS,
|
|
157
|
+
});
|
|
158
|
+
const now = (options.now ?? (() => new Date()))();
|
|
159
|
+
return store.interruptExpiredTurns(HostedConversationExpiredTurnReconciliationSchema.parse({
|
|
160
|
+
scope: Object.freeze({ ...scope }),
|
|
161
|
+
expiredBefore: dayjs(now)
|
|
162
|
+
.subtract(expiredTurnGraceMs, 'millisecond')
|
|
163
|
+
.toISOString(),
|
|
164
|
+
settledAt: now.toISOString(),
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
167
|
+
export function projectHostedConversationTerminalEvent(event, options = {}) {
|
|
168
|
+
const { maxSummaryCharacters } = LifecycleOptionsSchema.pick({
|
|
169
|
+
maxSummaryCharacters: true,
|
|
170
|
+
}).parse({
|
|
171
|
+
maxSummaryCharacters: options.maxSummaryCharacters
|
|
172
|
+
?? DEFAULT_MAX_SUMMARY_CHARACTERS,
|
|
173
|
+
});
|
|
174
|
+
return projectTerminalEvent(event, maxSummaryCharacters);
|
|
175
|
+
}
|
|
176
|
+
function projectTerminalEvent(event, maxSummaryCharacters) {
|
|
177
|
+
if (event.kind === 'cancelled') {
|
|
178
|
+
return {
|
|
179
|
+
event,
|
|
180
|
+
settlement: {
|
|
181
|
+
status: 'cancelled',
|
|
182
|
+
failureCode: 'invocation_cancelled',
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
if (event.kind === 'error') {
|
|
187
|
+
return {
|
|
188
|
+
event,
|
|
189
|
+
settlement: {
|
|
190
|
+
status: 'failed',
|
|
191
|
+
failureCode: 'execution_error',
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
const summary = event.result.summary === undefined
|
|
196
|
+
? undefined
|
|
197
|
+
: takeUnicodeCodePoints(event.result.summary, maxSummaryCharacters);
|
|
198
|
+
const projectedEvent = summary === event.result.summary
|
|
199
|
+
? event
|
|
200
|
+
: {
|
|
201
|
+
...event,
|
|
202
|
+
result: {
|
|
203
|
+
...event.result,
|
|
204
|
+
summary,
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
if (event.result.outcome === 'done') {
|
|
208
|
+
return {
|
|
209
|
+
event: projectedEvent,
|
|
210
|
+
settlement: {
|
|
211
|
+
status: 'completed',
|
|
212
|
+
...(summary !== undefined ? { summary } : {}),
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
if (event.result.outcome === 'max_steps') {
|
|
217
|
+
return {
|
|
218
|
+
event: projectedEvent,
|
|
219
|
+
settlement: {
|
|
220
|
+
status: 'max_steps',
|
|
221
|
+
...(summary !== undefined ? { summary } : {}),
|
|
222
|
+
},
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
if (event.result.outcome === 'interrupted') {
|
|
226
|
+
return {
|
|
227
|
+
event: projectedEvent,
|
|
228
|
+
settlement: {
|
|
229
|
+
status: 'interrupted',
|
|
230
|
+
...(summary !== undefined ? { summary } : {}),
|
|
231
|
+
failureCode: 'execution_interrupted',
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
event: projectedEvent,
|
|
237
|
+
settlement: {
|
|
238
|
+
status: 'failed',
|
|
239
|
+
...(summary !== undefined ? { summary } : {}),
|
|
240
|
+
failureCode: event.result.failure
|
|
241
|
+
? MODEL_FAILURE_CODE[event.result.failure.code]
|
|
242
|
+
: 'execution_result_error',
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function takeUnicodeCodePoints(value, maximum) {
|
|
247
|
+
let codePoints = 0;
|
|
248
|
+
let utf16End = 0;
|
|
249
|
+
for (const codePoint of value) {
|
|
250
|
+
codePoints += 1;
|
|
251
|
+
if (codePoints > maximum) {
|
|
252
|
+
return value.slice(0, utf16End);
|
|
253
|
+
}
|
|
254
|
+
utf16End += codePoint.length;
|
|
255
|
+
}
|
|
256
|
+
return value;
|
|
257
|
+
}
|
|
258
|
+
function projectThrownFailure(error, signal) {
|
|
259
|
+
if (error instanceof ExecutionHostStreamInterruptedError) {
|
|
260
|
+
return { status: 'interrupted', failureCode: 'stream_interrupted' };
|
|
261
|
+
}
|
|
262
|
+
if (signal?.aborted || error instanceof ExecutionHostInvocationCancelledError) {
|
|
263
|
+
return { status: 'interrupted', failureCode: 'invocation_aborted' };
|
|
264
|
+
}
|
|
265
|
+
if (error instanceof ExecutionHostProtocolError) {
|
|
266
|
+
return { status: 'failed', failureCode: 'host_protocol_error' };
|
|
267
|
+
}
|
|
268
|
+
if (error instanceof ExecutionHostRejectedError) {
|
|
269
|
+
return { status: 'failed', failureCode: 'host_rejected' };
|
|
270
|
+
}
|
|
271
|
+
return { status: 'failed', failureCode: 'execution_failed' };
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=durable-hosted-conversation-turn-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"durable-hosted-conversation-turn-service.js","sourceRoot":"","sources":["../../src/conversation/durable-hosted-conversation-turn-service.ts"],"names":[],"mappings":"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","sourcesContent":["import dayjs from 'dayjs';\nimport { z } from 'zod';\nimport {\n isExecutionHostTerminalEvent,\n type ExecutionHostTerminalEvent,\n} from '../contracts/index.js';\nimport {\n ExecutionHostInvocationCancelledError,\n ExecutionHostProtocolError,\n ExecutionHostRejectedError,\n ExecutionHostStreamInterruptedError,\n} from '../http-sse/index.js';\nimport {\n HostedConversationAcceptedTurnSchema,\n HostedConversationExpiredTurnReconciliationSchema,\n HostedConversationRequestedTurnSchema,\n HostedConversationTurnSettlementSchema,\n type DurableHostedConversationTurnServiceConfig,\n type DurableHostedConversationTurnServiceOptions,\n type HostedConversationFailureCode,\n type HostedConversationPersistenceScope,\n type HostedConversationTerminalProjection,\n type HostedConversationTurnIdentity,\n type HostedConversationTurnLifecycleStore,\n type HostedConversationTurnReconciliationOptions,\n} from './lifecycle-types.js';\nimport type {\n HostedConversationTurnRunner,\n} from './types.js';\nimport { HostedConversationTurnInputSchema } from './types.js';\n\nconst DEFAULT_MAX_SUMMARY_CHARACTERS = 100_000;\nconst DEFAULT_EXPIRED_TURN_GRACE_MS = 60_000;\nconst LifecycleOptionsSchema = z.object({\n maxSummaryCharacters: z.number().int().positive().max(1_000_000),\n expiredTurnGraceMs: z.number().int().nonnegative().max(86_400_000),\n}).strict();\nconst MODEL_FAILURE_CODE = {\n authentication: 'model_authentication',\n permission: 'model_permission',\n quota: 'model_quota',\n rate_limit: 'model_rate_limit',\n context_window: 'model_context_window',\n request: 'model_request',\n transport: 'model_transport',\n empty_response: 'model_empty_response',\n unknown: 'model_unknown',\n} as const satisfies Record<string, HostedConversationFailureCode>;\ntype PersistenceState = 'open' | 'settling' | 'settled' | 'write_failed';\n\n/**\n * Applies one reusable durable lifecycle around an Execution Host turn.\n *\n * Requested state is written before execution starts. Accepted and terminal\n * writes complete before their corresponding public events are released. A\n * persistence failure therefore fails closed instead of acknowledging state\n * that the adopter cannot later recover.\n */\nexport class DurableHostedConversationTurnService\nimplements HostedConversationTurnRunner {\n readonly #turns: HostedConversationTurnRunner;\n readonly #store: DurableHostedConversationTurnServiceConfig['store'];\n readonly #maxSummaryCharacters: number;\n readonly #expiredTurnGraceMs: number;\n readonly #now: () => Date;\n\n constructor(\n config: DurableHostedConversationTurnServiceConfig,\n options: DurableHostedConversationTurnServiceOptions = {},\n ) {\n const lifecycle = LifecycleOptionsSchema.parse({\n maxSummaryCharacters: config.maxSummaryCharacters\n ?? DEFAULT_MAX_SUMMARY_CHARACTERS,\n expiredTurnGraceMs: config.expiredTurnGraceMs\n ?? DEFAULT_EXPIRED_TURN_GRACE_MS,\n });\n this.#turns = config.turns;\n this.#store = config.store;\n this.#maxSummaryCharacters = lifecycle.maxSummaryCharacters;\n this.#expiredTurnGraceMs = lifecycle.expiredTurnGraceMs;\n this.#now = options.now ?? (() => new Date());\n }\n\n async *streamTurn(\n rawInput: Parameters<HostedConversationTurnRunner['streamTurn']>[0],\n ): ReturnType<HostedConversationTurnRunner['streamTurn']> {\n const input = HostedConversationTurnInputSchema.parse(rawInput);\n const scope = Object.freeze({ ...input.scope });\n const turn = { ...input, scope };\n const identity: HostedConversationTurnIdentity = {\n invocationId: turn.invocationId,\n scope,\n };\n await this.#store.createTurn(HostedConversationRequestedTurnSchema.parse({\n ...identity,\n prompt: turn.prompt,\n ...(turn.deadlineAt ? { deadlineAt: turn.deadlineAt } : {}),\n requestedAt: this.#now().toISOString(),\n }));\n\n let persistenceState: PersistenceState = 'open';\n let streamAccepted = false;\n const settle = async (\n settlement: HostedConversationTerminalProjection['settlement'] & {\n settledAt: string;\n },\n ): Promise<void> => {\n persistenceState = 'settling';\n await this.#store.settleTurn(HostedConversationTurnSettlementSchema.parse({\n ...identity,\n ...settlement,\n }));\n persistenceState = 'settled';\n };\n\n try {\n turn.signal?.throwIfAborted();\n for await (const event of this.#turns.streamTurn(turn)) {\n if (event.kind === 'accepted') {\n if (streamAccepted) {\n throw new ExecutionHostProtocolError(\n 'Hosted turn emitted more than one accepted event.',\n );\n }\n try {\n await this.#store.recordAccepted(\n HostedConversationAcceptedTurnSchema.parse({\n ...identity,\n runId: event.runId,\n acceptedAt: event.timestamp,\n }),\n );\n } catch (error) {\n persistenceState = 'write_failed';\n throw error;\n }\n streamAccepted = true;\n yield event;\n continue;\n }\n if (!streamAccepted) {\n throw new ExecutionHostProtocolError(\n 'Hosted turn emitted data before its accepted event.',\n );\n }\n if (isExecutionHostTerminalEvent(event)) {\n const projection = projectTerminalEvent(\n event,\n this.#maxSummaryCharacters,\n );\n await settle({\n ...projection.settlement,\n settledAt: event.timestamp,\n });\n yield projection.event;\n return;\n }\n yield event;\n }\n\n if (!streamAccepted) {\n throw new ExecutionHostProtocolError(\n 'Hosted turn stream omitted its accepted event.',\n );\n }\n if (persistenceState === 'open') {\n await settle({\n status: 'interrupted',\n failureCode: 'stream_ended_without_terminal',\n settledAt: this.#now().toISOString(),\n });\n }\n } catch (error) {\n if (persistenceState === 'open') {\n await settle({\n ...projectThrownFailure(error, turn.signal),\n settledAt: this.#now().toISOString(),\n });\n }\n throw error;\n } finally {\n // Returning from a consumer closes an async generator without throwing.\n // Settle that still-open invocation before releasing the managed stream.\n if (persistenceState === 'open') {\n await settle({\n status: 'interrupted',\n failureCode: 'stream_ended_without_terminal',\n settledAt: this.#now().toISOString(),\n });\n }\n }\n }\n\n /** Reconciles only expired open turns within one already-authorized scope. */\n interruptExpiredTurns(\n scope: HostedConversationPersistenceScope,\n ): Promise<void> {\n return interruptExpiredHostedConversationTurns(this.#store, scope, {\n expiredTurnGraceMs: this.#expiredTurnGraceMs,\n now: this.#now,\n });\n }\n}\n\nexport function interruptExpiredHostedConversationTurns(\n store: HostedConversationTurnLifecycleStore,\n scope: HostedConversationPersistenceScope,\n options: HostedConversationTurnReconciliationOptions = {},\n): Promise<void> {\n const { expiredTurnGraceMs } = LifecycleOptionsSchema.pick({\n expiredTurnGraceMs: true,\n }).parse({\n expiredTurnGraceMs: options.expiredTurnGraceMs\n ?? DEFAULT_EXPIRED_TURN_GRACE_MS,\n });\n const now = (options.now ?? (() => new Date()))();\n return store.interruptExpiredTurns(\n HostedConversationExpiredTurnReconciliationSchema.parse({\n scope: Object.freeze({ ...scope }),\n expiredBefore: dayjs(now)\n .subtract(expiredTurnGraceMs, 'millisecond')\n .toISOString(),\n settledAt: now.toISOString(),\n }),\n );\n}\n\nexport function projectHostedConversationTerminalEvent(\n event: ExecutionHostTerminalEvent,\n options: { maxSummaryCharacters?: number } = {},\n): HostedConversationTerminalProjection {\n const { maxSummaryCharacters } = LifecycleOptionsSchema.pick({\n maxSummaryCharacters: true,\n }).parse({\n maxSummaryCharacters: options.maxSummaryCharacters\n ?? DEFAULT_MAX_SUMMARY_CHARACTERS,\n });\n return projectTerminalEvent(event, maxSummaryCharacters);\n}\n\nfunction projectTerminalEvent(\n event: ExecutionHostTerminalEvent,\n maxSummaryCharacters: number,\n): HostedConversationTerminalProjection {\n if (event.kind === 'cancelled') {\n return {\n event,\n settlement: {\n status: 'cancelled',\n failureCode: 'invocation_cancelled',\n },\n };\n }\n if (event.kind === 'error') {\n return {\n event,\n settlement: {\n status: 'failed',\n failureCode: 'execution_error',\n },\n };\n }\n\n const summary = event.result.summary === undefined\n ? undefined\n : takeUnicodeCodePoints(event.result.summary, maxSummaryCharacters);\n const projectedEvent = summary === event.result.summary\n ? event\n : {\n ...event,\n result: {\n ...event.result,\n summary,\n },\n };\n if (event.result.outcome === 'done') {\n return {\n event: projectedEvent,\n settlement: {\n status: 'completed',\n ...(summary !== undefined ? { summary } : {}),\n },\n };\n }\n if (event.result.outcome === 'max_steps') {\n return {\n event: projectedEvent,\n settlement: {\n status: 'max_steps',\n ...(summary !== undefined ? { summary } : {}),\n },\n };\n }\n if (event.result.outcome === 'interrupted') {\n return {\n event: projectedEvent,\n settlement: {\n status: 'interrupted',\n ...(summary !== undefined ? { summary } : {}),\n failureCode: 'execution_interrupted',\n },\n };\n }\n return {\n event: projectedEvent,\n settlement: {\n status: 'failed',\n ...(summary !== undefined ? { summary } : {}),\n failureCode: event.result.failure\n ? MODEL_FAILURE_CODE[event.result.failure.code]\n : 'execution_result_error',\n },\n };\n}\n\nfunction takeUnicodeCodePoints(value: string, maximum: number): string {\n let codePoints = 0;\n let utf16End = 0;\n for (const codePoint of value) {\n codePoints += 1;\n if (codePoints > maximum) {\n return value.slice(0, utf16End);\n }\n utf16End += codePoint.length;\n }\n return value;\n}\n\nfunction projectThrownFailure(\n error: unknown,\n signal?: AbortSignal,\n): Extract<\n HostedConversationTerminalProjection['settlement'],\n { status: 'failed' | 'interrupted' }\n> {\n if (error instanceof ExecutionHostStreamInterruptedError) {\n return { status: 'interrupted', failureCode: 'stream_interrupted' };\n }\n if (signal?.aborted || error instanceof ExecutionHostInvocationCancelledError) {\n return { status: 'interrupted', failureCode: 'invocation_aborted' };\n }\n if (error instanceof ExecutionHostProtocolError) {\n return { status: 'failed', failureCode: 'host_protocol_error' };\n }\n if (error instanceof ExecutionHostRejectedError) {\n return { status: 'failed', failureCode: 'host_rejected' };\n }\n return { status: 'failed', failureCode: 'execution_failed' };\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { HostedConversationTurnRunner, HostedConversationTurnServiceConfig } from './types.js';
|
|
2
|
+
export declare class HostedConversationConfigurationError extends Error {
|
|
3
|
+
readonly name = "HostedConversationConfigurationError";
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Provider-neutral application service for one externally hosted turn.
|
|
7
|
+
*
|
|
8
|
+
* It binds authority, optional product-tool policy, model credentials, and the
|
|
9
|
+
* Execution Host stream while leaving product admission and settlement to the
|
|
10
|
+
* adopter.
|
|
11
|
+
*/
|
|
12
|
+
export declare class HostedConversationTurnService implements HostedConversationTurnRunner {
|
|
13
|
+
#private;
|
|
14
|
+
constructor(config: HostedConversationTurnServiceConfig);
|
|
15
|
+
streamTurn(rawInput: Parameters<HostedConversationTurnRunner['streamTurn']>[0]): ReturnType<HostedConversationTurnRunner['streamTurn']>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=hosted-conversation-turn-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-conversation-turn-service.d.ts","sourceRoot":"","sources":["../../src/conversation/hosted-conversation-turn-service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,4BAA4B,EAC5B,mCAAmC,EACpC,MAAM,YAAY,CAAC;AAGpB,qBAAa,oCAAqC,SAAQ,KAAK;IAC7D,QAAQ,CAAC,IAAI,0CAA0C;CACxD;AAED;;;;;;GAMG;AACH,qBAAa,6BACb,YAAW,4BAA4B;;gBAQzB,MAAM,EAAE,mCAAmC;IAShD,UAAU,CACf,QAAQ,EAAE,UAAU,CAAC,4BAA4B,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,GAClE,UAAU,CAAC,4BAA4B,CAAC,YAAY,CAAC,CAAC;CAqC1D"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { CONVERSATION_TURN_WORKFLOW, McpAllowedToolsSchema, } from '../contracts/index.js';
|
|
2
|
+
import { HostedConversationTurnInputSchema } from './types.js';
|
|
3
|
+
export class HostedConversationConfigurationError extends Error {
|
|
4
|
+
name = 'HostedConversationConfigurationError';
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Provider-neutral application service for one externally hosted turn.
|
|
8
|
+
*
|
|
9
|
+
* It binds authority, optional product-tool policy, model credentials, and the
|
|
10
|
+
* Execution Host stream while leaving product admission and settlement to the
|
|
11
|
+
* adopter.
|
|
12
|
+
*/
|
|
13
|
+
export class HostedConversationTurnService {
|
|
14
|
+
#authority;
|
|
15
|
+
#executionHost;
|
|
16
|
+
#modelCredentials;
|
|
17
|
+
#allowedTools;
|
|
18
|
+
constructor(config) {
|
|
19
|
+
this.#authority = config.authority;
|
|
20
|
+
this.#executionHost = config.executionHost;
|
|
21
|
+
this.#modelCredentials = config.modelCredentials;
|
|
22
|
+
this.#allowedTools = config.mcp
|
|
23
|
+
? Object.freeze(McpAllowedToolsSchema.parse(config.mcp.allowedTools))
|
|
24
|
+
: undefined;
|
|
25
|
+
}
|
|
26
|
+
async *streamTurn(rawInput) {
|
|
27
|
+
const input = HostedConversationTurnInputSchema.parse(rawInput);
|
|
28
|
+
input.signal?.throwIfAborted();
|
|
29
|
+
const issued = await this.#authority.issue({
|
|
30
|
+
scope: input.scope,
|
|
31
|
+
runtimeSessionId: input.runtimeSessionId,
|
|
32
|
+
invocationId: input.invocationId,
|
|
33
|
+
workflow: CONVERSATION_TURN_WORKFLOW,
|
|
34
|
+
...(this.#allowedTools
|
|
35
|
+
? { mcp: { allowedTools: this.#allowedTools } }
|
|
36
|
+
: {}),
|
|
37
|
+
});
|
|
38
|
+
const mcpCapability = issued.mcpCapability();
|
|
39
|
+
if (this.#allowedTools && !mcpCapability) {
|
|
40
|
+
throw new HostedConversationConfigurationError('Hosted conversation tool policy requires an MCP-capable execution authority.');
|
|
41
|
+
}
|
|
42
|
+
const modelApiKey = await this.#modelCredentials.resolveModelApiKey({
|
|
43
|
+
scope: input.scope,
|
|
44
|
+
invocationId: input.invocationId,
|
|
45
|
+
signal: input.signal,
|
|
46
|
+
});
|
|
47
|
+
input.signal?.throwIfAborted();
|
|
48
|
+
yield* this.#executionHost.streamConversationTurn({
|
|
49
|
+
invocationId: input.invocationId,
|
|
50
|
+
runtimeSessionId: input.runtimeSessionId,
|
|
51
|
+
prompt: input.prompt,
|
|
52
|
+
...(input.deadlineAt ? { deadlineAt: input.deadlineAt } : {}),
|
|
53
|
+
...(input.signal ? { signal: input.signal } : {}),
|
|
54
|
+
executionAssertion: issued.executionAssertion(),
|
|
55
|
+
...(mcpCapability ? { mcpCapability } : {}),
|
|
56
|
+
modelApiKey,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=hosted-conversation-turn-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-conversation-turn-service.js","sourceRoot":"","sources":["../../src/conversation/hosted-conversation-turn-service.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EAAE,iCAAiC,EAAE,MAAM,YAAY,CAAC;AAE/D,MAAM,OAAO,oCAAqC,SAAQ,KAAK;IACpD,IAAI,GAAG,sCAAsC,CAAC;CACxD;AAED;;;;;;GAMG;AACH,MAAM,OAAO,6BAA6B;IAE/B,UAAU,CAAmD;IAC7D,cAAc,CAAuD;IACrE,iBAAiB,CAExB;IACO,aAAa,CAAgC;IAEtD,YAAY,MAA2C;QACrD,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,aAAa,CAAC;QAC3C,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC,gBAAgB,CAAC;QACjD,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,GAAG;YAC7B,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YACrE,CAAC,CAAC,SAAS,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,CAAC,UAAU,CACf,QAAmE;QAEnE,MAAM,KAAK,GAAG,iCAAiC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChE,KAAK,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;YACzC,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;YACxC,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,QAAQ,EAAE,0BAA0B;YACpC,GAAG,CAAC,IAAI,CAAC,aAAa;gBACpB,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,aAAa,EAAE,EAAE;gBAC/C,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;QACH,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;QAC7C,IAAI,IAAI,CAAC,aAAa,IAAI,CAAC,aAAa,EAAE,CAAC;YACzC,MAAM,IAAI,oCAAoC,CAC5C,8EAA8E,CAC/E,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC;YAClE,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;QAE/B,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,sBAAsB,CAAC;YAChD,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;YACxC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,EAAE;YAC/C,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,WAAW;SACZ,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import {\n CONVERSATION_TURN_WORKFLOW,\n McpAllowedToolsSchema,\n} from '../contracts/index.js';\nimport type {\n HostedConversationTurnRunner,\n HostedConversationTurnServiceConfig,\n} from './types.js';\nimport { HostedConversationTurnInputSchema } from './types.js';\n\nexport class HostedConversationConfigurationError extends Error {\n readonly name = 'HostedConversationConfigurationError';\n}\n\n/**\n * Provider-neutral application service for one externally hosted turn.\n *\n * It binds authority, optional product-tool policy, model credentials, and the\n * Execution Host stream while leaving product admission and settlement to the\n * adopter.\n */\nexport class HostedConversationTurnService\nimplements HostedConversationTurnRunner {\n readonly #authority: HostedConversationTurnServiceConfig['authority'];\n readonly #executionHost: HostedConversationTurnServiceConfig['executionHost'];\n readonly #modelCredentials: HostedConversationTurnServiceConfig[\n 'modelCredentials'\n ];\n readonly #allowedTools: readonly string[] | undefined;\n\n constructor(config: HostedConversationTurnServiceConfig) {\n this.#authority = config.authority;\n this.#executionHost = config.executionHost;\n this.#modelCredentials = config.modelCredentials;\n this.#allowedTools = config.mcp\n ? Object.freeze(McpAllowedToolsSchema.parse(config.mcp.allowedTools))\n : undefined;\n }\n\n async *streamTurn(\n rawInput: Parameters<HostedConversationTurnRunner['streamTurn']>[0],\n ): ReturnType<HostedConversationTurnRunner['streamTurn']> {\n const input = HostedConversationTurnInputSchema.parse(rawInput);\n input.signal?.throwIfAborted();\n const issued = await this.#authority.issue({\n scope: input.scope,\n runtimeSessionId: input.runtimeSessionId,\n invocationId: input.invocationId,\n workflow: CONVERSATION_TURN_WORKFLOW,\n ...(this.#allowedTools\n ? { mcp: { allowedTools: this.#allowedTools } }\n : {}),\n });\n const mcpCapability = issued.mcpCapability();\n if (this.#allowedTools && !mcpCapability) {\n throw new HostedConversationConfigurationError(\n 'Hosted conversation tool policy requires an MCP-capable execution authority.',\n );\n }\n\n const modelApiKey = await this.#modelCredentials.resolveModelApiKey({\n scope: input.scope,\n invocationId: input.invocationId,\n signal: input.signal,\n });\n input.signal?.throwIfAborted();\n\n yield* this.#executionHost.streamConversationTurn({\n invocationId: input.invocationId,\n runtimeSessionId: input.runtimeSessionId,\n prompt: input.prompt,\n ...(input.deadlineAt ? { deadlineAt: input.deadlineAt } : {}),\n ...(input.signal ? { signal: input.signal } : {}),\n executionAssertion: issued.executionAssertion(),\n ...(mcpCapability ? { mcpCapability } : {}),\n modelApiKey,\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { DurableHostedConversationTurnService, interruptExpiredHostedConversationTurns, projectHostedConversationTerminalEvent, } from './durable-hosted-conversation-turn-service.js';
|
|
2
|
+
export { HOSTED_CONVERSATION_CANCELLED_CODES, HOSTED_CONVERSATION_FAILURE_CODES, HOSTED_CONVERSATION_FAILED_CODES, HOSTED_CONVERSATION_INTERRUPTED_CODES, HOSTED_CONVERSATION_TURN_STATUSES, HostedConversationAcceptedTurnSchema, HostedConversationExpiredTurnReconciliationSchema, HostedConversationFailureCodeSchema, HostedConversationPersistenceScopeSchema, HostedConversationRequestedTurnSchema, HostedConversationTurnIdentitySchema, HostedConversationTurnSettlementSchema, HostedConversationTurnStatusSchema, } from './lifecycle-types.js';
|
|
3
|
+
export { HostedConversationConfigurationError, HostedConversationTurnService, } from './hosted-conversation-turn-service.js';
|
|
4
|
+
export type { DurableHostedConversationTurnServiceConfig, DurableHostedConversationTurnServiceOptions, HostedConversationAcceptedTurn, HostedConversationExpiredTurnReconciliation, HostedConversationFailureCode, HostedConversationPersistenceScope, HostedConversationRequestedTurn, HostedConversationTerminalProjection, HostedConversationTerminalStatus, HostedConversationTurnIdentity, HostedConversationTurnLifecycleRecord, HostedConversationTurnLifecycleStore, HostedConversationTurnReconciliationOptions, HostedConversationTurnSettlement, HostedConversationTurnStatus, } from './lifecycle-types.js';
|
|
5
|
+
export { HostedConversationTurnInputSchema } from './types.js';
|
|
6
|
+
export type { HostedConversationCredentialContext, HostedConversationModelCredentialProvider, HostedConversationTurnInput, HostedConversationTurnRunner, HostedConversationTurnServiceConfig, } from './types.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/conversation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oCAAoC,EACpC,uCAAuC,EACvC,sCAAsC,GACvC,MAAM,+CAA+C,CAAC;AACvD,OAAO,EACL,mCAAmC,EACnC,iCAAiC,EACjC,gCAAgC,EAChC,qCAAqC,EACrC,iCAAiC,EACjC,oCAAoC,EACpC,iDAAiD,EACjD,mCAAmC,EACnC,wCAAwC,EACxC,qCAAqC,EACrC,oCAAoC,EACpC,sCAAsC,EACtC,kCAAkC,GACnC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,oCAAoC,EACpC,6BAA6B,GAC9B,MAAM,uCAAuC,CAAC;AAC/C,YAAY,EACV,0CAA0C,EAC1C,2CAA2C,EAC3C,8BAA8B,EAC9B,2CAA2C,EAC3C,6BAA6B,EAC7B,kCAAkC,EAClC,+BAA+B,EAC/B,oCAAoC,EACpC,gCAAgC,EAChC,8BAA8B,EAC9B,qCAAqC,EACrC,oCAAoC,EACpC,2CAA2C,EAC3C,gCAAgC,EAChC,4BAA4B,GAC7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,iCAAiC,EAAE,MAAM,YAAY,CAAC;AAC/D,YAAY,EACV,mCAAmC,EACnC,yCAAyC,EACzC,2BAA2B,EAC3B,4BAA4B,EAC5B,mCAAmC,GACpC,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { DurableHostedConversationTurnService, interruptExpiredHostedConversationTurns, projectHostedConversationTerminalEvent, } from './durable-hosted-conversation-turn-service.js';
|
|
2
|
+
export { HOSTED_CONVERSATION_CANCELLED_CODES, HOSTED_CONVERSATION_FAILURE_CODES, HOSTED_CONVERSATION_FAILED_CODES, HOSTED_CONVERSATION_INTERRUPTED_CODES, HOSTED_CONVERSATION_TURN_STATUSES, HostedConversationAcceptedTurnSchema, HostedConversationExpiredTurnReconciliationSchema, HostedConversationFailureCodeSchema, HostedConversationPersistenceScopeSchema, HostedConversationRequestedTurnSchema, HostedConversationTurnIdentitySchema, HostedConversationTurnSettlementSchema, HostedConversationTurnStatusSchema, } from './lifecycle-types.js';
|
|
3
|
+
export { HostedConversationConfigurationError, HostedConversationTurnService, } from './hosted-conversation-turn-service.js';
|
|
4
|
+
export { HostedConversationTurnInputSchema } from './types.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/conversation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oCAAoC,EACpC,uCAAuC,EACvC,sCAAsC,GACvC,MAAM,+CAA+C,CAAC;AACvD,OAAO,EACL,mCAAmC,EACnC,iCAAiC,EACjC,gCAAgC,EAChC,qCAAqC,EACrC,iCAAiC,EACjC,oCAAoC,EACpC,iDAAiD,EACjD,mCAAmC,EACnC,wCAAwC,EACxC,qCAAqC,EACrC,oCAAoC,EACpC,sCAAsC,EACtC,kCAAkC,GACnC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,oCAAoC,EACpC,6BAA6B,GAC9B,MAAM,uCAAuC,CAAC;AAkB/C,OAAO,EAAE,iCAAiC,EAAE,MAAM,YAAY,CAAC","sourcesContent":["export {\n DurableHostedConversationTurnService,\n interruptExpiredHostedConversationTurns,\n projectHostedConversationTerminalEvent,\n} from './durable-hosted-conversation-turn-service.js';\nexport {\n HOSTED_CONVERSATION_CANCELLED_CODES,\n HOSTED_CONVERSATION_FAILURE_CODES,\n HOSTED_CONVERSATION_FAILED_CODES,\n HOSTED_CONVERSATION_INTERRUPTED_CODES,\n HOSTED_CONVERSATION_TURN_STATUSES,\n HostedConversationAcceptedTurnSchema,\n HostedConversationExpiredTurnReconciliationSchema,\n HostedConversationFailureCodeSchema,\n HostedConversationPersistenceScopeSchema,\n HostedConversationRequestedTurnSchema,\n HostedConversationTurnIdentitySchema,\n HostedConversationTurnSettlementSchema,\n HostedConversationTurnStatusSchema,\n} from './lifecycle-types.js';\nexport {\n HostedConversationConfigurationError,\n HostedConversationTurnService,\n} from './hosted-conversation-turn-service.js';\nexport type {\n DurableHostedConversationTurnServiceConfig,\n DurableHostedConversationTurnServiceOptions,\n HostedConversationAcceptedTurn,\n HostedConversationExpiredTurnReconciliation,\n HostedConversationFailureCode,\n HostedConversationPersistenceScope,\n HostedConversationRequestedTurn,\n HostedConversationTerminalProjection,\n HostedConversationTerminalStatus,\n HostedConversationTurnIdentity,\n HostedConversationTurnLifecycleRecord,\n HostedConversationTurnLifecycleStore,\n HostedConversationTurnReconciliationOptions,\n HostedConversationTurnSettlement,\n HostedConversationTurnStatus,\n} from './lifecycle-types.js';\nexport { HostedConversationTurnInputSchema } from './types.js';\nexport type {\n HostedConversationCredentialContext,\n HostedConversationModelCredentialProvider,\n HostedConversationTurnInput,\n HostedConversationTurnRunner,\n HostedConversationTurnServiceConfig,\n} from './types.js';\n"]}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type ExecutionHostTerminalEvent } from '../contracts/index.js';
|
|
3
|
+
import type { HostedConversationTurnRunner } from './types.js';
|
|
4
|
+
export declare const HOSTED_CONVERSATION_TURN_STATUSES: readonly ["requested", "running", "completed", "max_steps", "failed", "cancelled", "interrupted"];
|
|
5
|
+
export declare const HOSTED_CONVERSATION_FAILED_CODES: readonly ["execution_error", "execution_failed", "execution_result_error", "host_protocol_error", "host_rejected", "model_authentication", "model_context_window", "model_empty_response", "model_permission", "model_quota", "model_rate_limit", "model_request", "model_transport", "model_unknown"];
|
|
6
|
+
export declare const HOSTED_CONVERSATION_INTERRUPTED_CODES: readonly ["deadline_elapsed", "execution_interrupted", "invocation_aborted", "stream_ended_without_terminal", "stream_interrupted"];
|
|
7
|
+
export declare const HOSTED_CONVERSATION_CANCELLED_CODES: readonly ["invocation_cancelled"];
|
|
8
|
+
export declare const HOSTED_CONVERSATION_FAILURE_CODES: readonly ["execution_error", "execution_failed", "execution_result_error", "host_protocol_error", "host_rejected", "model_authentication", "model_context_window", "model_empty_response", "model_permission", "model_quota", "model_rate_limit", "model_request", "model_transport", "model_unknown", "deadline_elapsed", "execution_interrupted", "invocation_aborted", "stream_ended_without_terminal", "stream_interrupted", "invocation_cancelled"];
|
|
9
|
+
export declare const HostedConversationTurnStatusSchema: z.ZodEnum<{
|
|
10
|
+
max_steps: "max_steps";
|
|
11
|
+
interrupted: "interrupted";
|
|
12
|
+
cancelled: "cancelled";
|
|
13
|
+
requested: "requested";
|
|
14
|
+
running: "running";
|
|
15
|
+
completed: "completed";
|
|
16
|
+
failed: "failed";
|
|
17
|
+
}>;
|
|
18
|
+
export declare const HostedConversationFailureCodeSchema: z.ZodEnum<{
|
|
19
|
+
execution_error: "execution_error";
|
|
20
|
+
execution_failed: "execution_failed";
|
|
21
|
+
execution_result_error: "execution_result_error";
|
|
22
|
+
host_protocol_error: "host_protocol_error";
|
|
23
|
+
host_rejected: "host_rejected";
|
|
24
|
+
model_authentication: "model_authentication";
|
|
25
|
+
model_context_window: "model_context_window";
|
|
26
|
+
model_empty_response: "model_empty_response";
|
|
27
|
+
model_permission: "model_permission";
|
|
28
|
+
model_quota: "model_quota";
|
|
29
|
+
model_rate_limit: "model_rate_limit";
|
|
30
|
+
model_request: "model_request";
|
|
31
|
+
model_transport: "model_transport";
|
|
32
|
+
model_unknown: "model_unknown";
|
|
33
|
+
deadline_elapsed: "deadline_elapsed";
|
|
34
|
+
execution_interrupted: "execution_interrupted";
|
|
35
|
+
invocation_aborted: "invocation_aborted";
|
|
36
|
+
stream_ended_without_terminal: "stream_ended_without_terminal";
|
|
37
|
+
stream_interrupted: "stream_interrupted";
|
|
38
|
+
invocation_cancelled: "invocation_cancelled";
|
|
39
|
+
}>;
|
|
40
|
+
export declare const HostedConversationPersistenceScopeSchema: z.ZodObject<{
|
|
41
|
+
tenantId: z.ZodString;
|
|
42
|
+
subjectId: z.ZodString;
|
|
43
|
+
productSessionId: z.ZodString;
|
|
44
|
+
}, z.core.$strict>;
|
|
45
|
+
export declare const HostedConversationTurnIdentitySchema: z.ZodObject<{
|
|
46
|
+
invocationId: z.ZodString;
|
|
47
|
+
scope: z.ZodObject<{
|
|
48
|
+
tenantId: z.ZodString;
|
|
49
|
+
subjectId: z.ZodString;
|
|
50
|
+
productSessionId: z.ZodString;
|
|
51
|
+
}, z.core.$strict>;
|
|
52
|
+
}, z.core.$strict>;
|
|
53
|
+
export declare const HostedConversationRequestedTurnSchema: z.ZodObject<{
|
|
54
|
+
invocationId: z.ZodString;
|
|
55
|
+
scope: z.ZodObject<{
|
|
56
|
+
tenantId: z.ZodString;
|
|
57
|
+
subjectId: z.ZodString;
|
|
58
|
+
productSessionId: z.ZodString;
|
|
59
|
+
}, z.core.$strict>;
|
|
60
|
+
prompt: z.ZodString;
|
|
61
|
+
deadlineAt: z.ZodOptional<z.ZodISODateTime>;
|
|
62
|
+
requestedAt: z.ZodISODateTime;
|
|
63
|
+
}, z.core.$strict>;
|
|
64
|
+
export declare const HostedConversationAcceptedTurnSchema: z.ZodObject<{
|
|
65
|
+
invocationId: z.ZodString;
|
|
66
|
+
scope: z.ZodObject<{
|
|
67
|
+
tenantId: z.ZodString;
|
|
68
|
+
subjectId: z.ZodString;
|
|
69
|
+
productSessionId: z.ZodString;
|
|
70
|
+
}, z.core.$strict>;
|
|
71
|
+
runId: z.ZodString;
|
|
72
|
+
acceptedAt: z.ZodISODateTime;
|
|
73
|
+
}, z.core.$strict>;
|
|
74
|
+
export declare const HostedConversationTurnSettlementSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
75
|
+
invocationId: z.ZodString;
|
|
76
|
+
scope: z.ZodObject<{
|
|
77
|
+
tenantId: z.ZodString;
|
|
78
|
+
subjectId: z.ZodString;
|
|
79
|
+
productSessionId: z.ZodString;
|
|
80
|
+
}, z.core.$strict>;
|
|
81
|
+
settledAt: z.ZodISODateTime;
|
|
82
|
+
status: z.ZodLiteral<"completed">;
|
|
83
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
84
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
85
|
+
invocationId: z.ZodString;
|
|
86
|
+
scope: z.ZodObject<{
|
|
87
|
+
tenantId: z.ZodString;
|
|
88
|
+
subjectId: z.ZodString;
|
|
89
|
+
productSessionId: z.ZodString;
|
|
90
|
+
}, z.core.$strict>;
|
|
91
|
+
settledAt: z.ZodISODateTime;
|
|
92
|
+
status: z.ZodLiteral<"max_steps">;
|
|
93
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
94
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
95
|
+
invocationId: z.ZodString;
|
|
96
|
+
scope: z.ZodObject<{
|
|
97
|
+
tenantId: z.ZodString;
|
|
98
|
+
subjectId: z.ZodString;
|
|
99
|
+
productSessionId: z.ZodString;
|
|
100
|
+
}, z.core.$strict>;
|
|
101
|
+
settledAt: z.ZodISODateTime;
|
|
102
|
+
status: z.ZodLiteral<"failed">;
|
|
103
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
104
|
+
failureCode: z.ZodEnum<{
|
|
105
|
+
execution_error: "execution_error";
|
|
106
|
+
execution_failed: "execution_failed";
|
|
107
|
+
execution_result_error: "execution_result_error";
|
|
108
|
+
host_protocol_error: "host_protocol_error";
|
|
109
|
+
host_rejected: "host_rejected";
|
|
110
|
+
model_authentication: "model_authentication";
|
|
111
|
+
model_context_window: "model_context_window";
|
|
112
|
+
model_empty_response: "model_empty_response";
|
|
113
|
+
model_permission: "model_permission";
|
|
114
|
+
model_quota: "model_quota";
|
|
115
|
+
model_rate_limit: "model_rate_limit";
|
|
116
|
+
model_request: "model_request";
|
|
117
|
+
model_transport: "model_transport";
|
|
118
|
+
model_unknown: "model_unknown";
|
|
119
|
+
}>;
|
|
120
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
121
|
+
invocationId: z.ZodString;
|
|
122
|
+
scope: z.ZodObject<{
|
|
123
|
+
tenantId: z.ZodString;
|
|
124
|
+
subjectId: z.ZodString;
|
|
125
|
+
productSessionId: z.ZodString;
|
|
126
|
+
}, z.core.$strict>;
|
|
127
|
+
settledAt: z.ZodISODateTime;
|
|
128
|
+
status: z.ZodLiteral<"cancelled">;
|
|
129
|
+
failureCode: z.ZodLiteral<"invocation_cancelled">;
|
|
130
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
131
|
+
invocationId: z.ZodString;
|
|
132
|
+
scope: z.ZodObject<{
|
|
133
|
+
tenantId: z.ZodString;
|
|
134
|
+
subjectId: z.ZodString;
|
|
135
|
+
productSessionId: z.ZodString;
|
|
136
|
+
}, z.core.$strict>;
|
|
137
|
+
settledAt: z.ZodISODateTime;
|
|
138
|
+
status: z.ZodLiteral<"interrupted">;
|
|
139
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
140
|
+
failureCode: z.ZodEnum<{
|
|
141
|
+
deadline_elapsed: "deadline_elapsed";
|
|
142
|
+
execution_interrupted: "execution_interrupted";
|
|
143
|
+
invocation_aborted: "invocation_aborted";
|
|
144
|
+
stream_ended_without_terminal: "stream_ended_without_terminal";
|
|
145
|
+
stream_interrupted: "stream_interrupted";
|
|
146
|
+
}>;
|
|
147
|
+
}, z.core.$strict>], "status">;
|
|
148
|
+
export declare const HostedConversationExpiredTurnReconciliationSchema: z.ZodObject<{
|
|
149
|
+
scope: z.ZodObject<{
|
|
150
|
+
tenantId: z.ZodString;
|
|
151
|
+
subjectId: z.ZodString;
|
|
152
|
+
productSessionId: z.ZodString;
|
|
153
|
+
}, z.core.$strict>;
|
|
154
|
+
expiredBefore: z.ZodISODateTime;
|
|
155
|
+
settledAt: z.ZodISODateTime;
|
|
156
|
+
}, z.core.$strict>;
|
|
157
|
+
export type HostedConversationTurnStatus = z.infer<typeof HostedConversationTurnStatusSchema>;
|
|
158
|
+
export type HostedConversationTerminalStatus = Exclude<HostedConversationTurnStatus, 'requested' | 'running'>;
|
|
159
|
+
export type HostedConversationFailureCode = z.infer<typeof HostedConversationFailureCodeSchema>;
|
|
160
|
+
export type HostedConversationPersistenceScope = z.infer<typeof HostedConversationPersistenceScopeSchema>;
|
|
161
|
+
export type HostedConversationTurnIdentity = z.infer<typeof HostedConversationTurnIdentitySchema>;
|
|
162
|
+
export type HostedConversationRequestedTurn = z.infer<typeof HostedConversationRequestedTurnSchema>;
|
|
163
|
+
export type HostedConversationAcceptedTurn = z.infer<typeof HostedConversationAcceptedTurnSchema>;
|
|
164
|
+
export type HostedConversationTurnSettlement = z.infer<typeof HostedConversationTurnSettlementSchema>;
|
|
165
|
+
export type HostedConversationTurnLifecycleRecord = HostedConversationRequestedTurn & {
|
|
166
|
+
status: HostedConversationTurnStatus;
|
|
167
|
+
runId?: string;
|
|
168
|
+
summary?: string;
|
|
169
|
+
failureCode?: HostedConversationFailureCode;
|
|
170
|
+
acceptedAt?: string;
|
|
171
|
+
settledAt?: string;
|
|
172
|
+
};
|
|
173
|
+
export type HostedConversationExpiredTurnReconciliation = z.infer<typeof HostedConversationExpiredTurnReconciliationSchema>;
|
|
174
|
+
/**
|
|
175
|
+
* Durable write port for the generic hosted-turn lifecycle.
|
|
176
|
+
*
|
|
177
|
+
* Implementations must fence every mutation by invocation and full scope.
|
|
178
|
+
* Creation rejects every duplicate invocation so a repeated request cannot
|
|
179
|
+
* start execution twice. Accepted and terminal writes allow only an exact
|
|
180
|
+
* repeat; conflicting or late transitions must fail atomically. The port
|
|
181
|
+
* deliberately cannot carry activity, raw errors, credentials, or tool data.
|
|
182
|
+
*/
|
|
183
|
+
export interface HostedConversationTurnLifecycleStore {
|
|
184
|
+
createTurn(input: HostedConversationRequestedTurn): Promise<void>;
|
|
185
|
+
recordAccepted(input: HostedConversationAcceptedTurn): Promise<void>;
|
|
186
|
+
settleTurn(input: HostedConversationTurnSettlement): Promise<void>;
|
|
187
|
+
interruptExpiredTurns(input: HostedConversationExpiredTurnReconciliation): Promise<void>;
|
|
188
|
+
}
|
|
189
|
+
export type DurableHostedConversationTurnServiceConfig = {
|
|
190
|
+
turns: HostedConversationTurnRunner;
|
|
191
|
+
store: HostedConversationTurnLifecycleStore;
|
|
192
|
+
maxSummaryCharacters?: number;
|
|
193
|
+
expiredTurnGraceMs?: number;
|
|
194
|
+
};
|
|
195
|
+
export type DurableHostedConversationTurnServiceOptions = {
|
|
196
|
+
now?: () => Date;
|
|
197
|
+
};
|
|
198
|
+
export type HostedConversationTurnReconciliationOptions = {
|
|
199
|
+
expiredTurnGraceMs?: number;
|
|
200
|
+
now?: () => Date;
|
|
201
|
+
};
|
|
202
|
+
type ProjectedSettlement<T> = T extends HostedConversationTurnSettlement ? Omit<T, keyof HostedConversationTurnIdentity | 'settledAt'> : never;
|
|
203
|
+
export type HostedConversationTerminalProjection = {
|
|
204
|
+
event: ExecutionHostTerminalEvent;
|
|
205
|
+
settlement: ProjectedSettlement<HostedConversationTurnSettlement>;
|
|
206
|
+
};
|
|
207
|
+
export {};
|
|
208
|
+
//# sourceMappingURL=lifecycle-types.d.ts.map
|