veryfront 0.1.64 → 0.1.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/esm/deno.js +1 -1
  2. package/esm/src/agent/runtime/index.d.ts +1 -0
  3. package/esm/src/agent/runtime/index.d.ts.map +1 -1
  4. package/esm/src/agent/runtime/index.js +10 -2
  5. package/esm/src/channels/control-plane.d.ts +259 -0
  6. package/esm/src/channels/control-plane.d.ts.map +1 -0
  7. package/esm/src/channels/control-plane.js +212 -0
  8. package/esm/src/channels/invoke.d.ts +3 -40
  9. package/esm/src/channels/invoke.d.ts.map +1 -1
  10. package/esm/src/channels/invoke.js +9 -106
  11. package/esm/src/internal-agents/ag-ui-sse.d.ts +35 -0
  12. package/esm/src/internal-agents/ag-ui-sse.d.ts.map +1 -0
  13. package/esm/src/internal-agents/ag-ui-sse.js +263 -0
  14. package/esm/src/internal-agents/control-plane-auth.d.ts +20 -0
  15. package/esm/src/internal-agents/control-plane-auth.d.ts.map +1 -0
  16. package/esm/src/internal-agents/control-plane-auth.js +56 -0
  17. package/esm/src/internal-agents/request-body.d.ts +9 -0
  18. package/esm/src/internal-agents/request-body.d.ts.map +1 -0
  19. package/esm/src/internal-agents/request-body.js +28 -0
  20. package/esm/src/internal-agents/run-stream.d.ts +14 -0
  21. package/esm/src/internal-agents/run-stream.d.ts.map +1 -0
  22. package/esm/src/internal-agents/run-stream.js +259 -0
  23. package/esm/src/internal-agents/schema.d.ts +268 -0
  24. package/esm/src/internal-agents/schema.d.ts.map +1 -0
  25. package/esm/src/internal-agents/schema.js +71 -0
  26. package/esm/src/internal-agents/session-manager.d.ts +63 -0
  27. package/esm/src/internal-agents/session-manager.d.ts.map +1 -0
  28. package/esm/src/internal-agents/session-manager.js +258 -0
  29. package/esm/src/platform/adapters/runtime/deno/adapter.d.ts.map +1 -1
  30. package/esm/src/platform/adapters/runtime/deno/adapter.js +4 -13
  31. package/esm/src/platform/compat/process.d.ts.map +1 -1
  32. package/esm/src/platform/compat/process.js +42 -5
  33. package/esm/src/server/handlers/request/agent-run-cancel.handler.d.ts +11 -0
  34. package/esm/src/server/handlers/request/agent-run-cancel.handler.d.ts.map +1 -0
  35. package/esm/src/server/handlers/request/agent-run-cancel.handler.js +62 -0
  36. package/esm/src/server/handlers/request/agent-run-resume.handler.d.ts +11 -0
  37. package/esm/src/server/handlers/request/agent-run-resume.handler.d.ts.map +1 -0
  38. package/esm/src/server/handlers/request/agent-run-resume.handler.js +77 -0
  39. package/esm/src/server/handlers/request/agent-stream.handler.d.ts +14 -0
  40. package/esm/src/server/handlers/request/agent-stream.handler.d.ts.map +1 -0
  41. package/esm/src/server/handlers/request/agent-stream.handler.js +86 -0
  42. package/esm/src/server/handlers/request/{channel-assistants.handler.d.ts → internal-agents-list.handler.d.ts} +4 -4
  43. package/esm/src/server/handlers/request/internal-agents-list.handler.d.ts.map +1 -0
  44. package/esm/src/server/handlers/request/internal-agents-list.handler.js +73 -0
  45. package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
  46. package/esm/src/server/runtime-handler/index.js +8 -2
  47. package/package.json +1 -1
  48. package/src/deno.js +1 -1
  49. package/src/src/agent/runtime/index.ts +12 -2
  50. package/src/src/channels/control-plane.ts +332 -0
  51. package/src/src/channels/invoke.ts +12 -157
  52. package/src/src/internal-agents/ag-ui-sse.ts +327 -0
  53. package/src/src/internal-agents/control-plane-auth.ts +82 -0
  54. package/src/src/internal-agents/request-body.ts +42 -0
  55. package/src/src/internal-agents/run-stream.ts +354 -0
  56. package/src/src/internal-agents/schema.ts +102 -0
  57. package/src/src/internal-agents/session-manager.ts +358 -0
  58. package/src/src/platform/adapters/runtime/deno/adapter.ts +9 -11
  59. package/src/src/platform/compat/process.ts +56 -3
  60. package/src/src/server/handlers/request/agent-run-cancel.handler.ts +86 -0
  61. package/src/src/server/handlers/request/agent-run-resume.handler.ts +108 -0
  62. package/src/src/server/handlers/request/agent-stream.handler.ts +125 -0
  63. package/src/src/server/handlers/request/internal-agents-list.handler.ts +100 -0
  64. package/src/src/server/runtime-handler/index.ts +8 -2
  65. package/esm/src/server/handlers/request/channel-assistants.handler.d.ts.map +0 -1
  66. package/esm/src/server/handlers/request/channel-assistants.handler.js +0 -71
  67. package/src/src/server/handlers/request/channel-assistants.handler.ts +0 -94
@@ -1,12 +1,10 @@
1
- import * as dntShim from "../../_dnt.shims.js";
2
1
  import { fromError } from "../errors/veryfront-error.js";
3
2
  import { serverLogger } from "../utils/index.js";
4
- import { base64urlEncodeBytes } from "../utils/base64url.js";
5
3
  import { z } from "zod";
6
4
  import { getAgent as getRegisteredAgent, getAllAgentIds as getRegisteredAgentIds, } from "../agent/composition/composition.js";
5
+ import { listRuntimeAgents } from "./control-plane.js";
7
6
  import { ensureProjectDiscovery as ensureProjectDiscoveryForProject } from "../server/handlers/request/api/project-discovery.js";
8
7
  const logger = serverLogger.component("channels-invoke");
9
- const SIGNATURE_SKEW_SECONDS = 5;
10
8
  const rawHistoryPartSchema = z.object({
11
9
  type: z.string(),
12
10
  }).passthrough();
@@ -103,117 +101,22 @@ export const ChannelInvokeResponseSchema = z.object({
103
101
  retryable: z.boolean(),
104
102
  }).optional(),
105
103
  });
106
- const dispatchHeaderSchema = z.object({
107
- alg: z.literal("EdDSA"),
108
- typ: z.string().optional(),
109
- kid: z.string().optional(),
110
- });
111
- const dispatchClaimsSchema = z.object({
112
- iss: z.string(),
113
- aud: z.string(),
114
- sub: z.string(),
115
- project_id: z.string(),
116
- platform: z.string(),
117
- body_sha256: z.string(),
118
- iat: z.number().int(),
119
- exp: z.number().int(),
120
- });
121
104
  export const defaultChannelInvokeDeps = {
122
105
  ensureProjectDiscovery: ensureProjectDiscoveryForProject,
123
106
  getAgent: getRegisteredAgent,
124
107
  getAllAgentIds: getRegisteredAgentIds,
125
108
  };
126
- function getAssistantMetadata(agent) {
127
- const rawConfig = agent.config;
128
- return ChannelAssistantSchema.parse({
129
- id: agent.id,
130
- name: typeof rawConfig.name === "string" && rawConfig.name.trim().length > 0
131
- ? rawConfig.name
132
- : agent.id,
133
- description: typeof rawConfig.description === "string" ? rawConfig.description : null,
134
- model: agent.config.model ?? null,
135
- });
136
- }
137
109
  export async function listChannelAssistants(ctx, deps) {
138
- await deps.ensureProjectDiscovery(ctx);
139
- const assistants = deps.getAllAgentIds()
140
- .map((id) => deps.getAgent(id))
141
- .filter((agent) => Boolean(agent))
142
- .map(getAssistantMetadata)
143
- .sort((left, right) => left.name.localeCompare(right.name));
110
+ const response = await listRuntimeAgents(ctx, deps);
111
+ const assistants = response.agents.map((agent) => ChannelAssistantSchema.parse({
112
+ id: agent.id,
113
+ name: agent.name,
114
+ description: agent.description ?? null,
115
+ model: agent.model ?? null,
116
+ }));
144
117
  return ChannelAssistantsResponseSchema.parse({ assistants });
145
118
  }
146
- function base64urlDecodeToBytes(input) {
147
- const normalized = input
148
- .replaceAll("-", "+")
149
- .replaceAll("_", "/")
150
- .padEnd(Math.ceil(input.length / 4) * 4, "=");
151
- return toArrayBuffer(Uint8Array.from(atob(normalized), (char) => char.charCodeAt(0)));
152
- }
153
- function toArrayBuffer(bytes) {
154
- const buffer = new ArrayBuffer(bytes.byteLength);
155
- new Uint8Array(buffer).set(bytes);
156
- return buffer;
157
- }
158
- function pemToDer(pem, label) {
159
- const body = pem
160
- .replace(`-----BEGIN ${label}-----`, "")
161
- .replace(`-----END ${label}-----`, "")
162
- .replace(/\s/g, "");
163
- return toArrayBuffer(Uint8Array.from(atob(body), (char) => char.charCodeAt(0)));
164
- }
165
- async function importEd25519PublicKey(pem) {
166
- return dntShim.crypto.subtle.importKey("spki", pemToDer(pem, "PUBLIC KEY"), "Ed25519", false, ["verify"]);
167
- }
168
- async function sha256Base64url(body) {
169
- const hash = await dntShim.crypto.subtle.digest("SHA-256", new TextEncoder().encode(body));
170
- return base64urlEncodeBytes(new Uint8Array(hash));
171
- }
172
- export async function verifyDispatchJws(jws, body, options) {
173
- const parts = jws.split(".");
174
- if (parts.length !== 3) {
175
- throw new Error("Channel dispatch signature must be a compact JWS");
176
- }
177
- const encodedHeader = parts[0];
178
- const encodedPayload = parts[1];
179
- const encodedSignature = parts[2];
180
- if (!encodedHeader || !encodedPayload || !encodedSignature) {
181
- throw new Error("Channel dispatch signature must include header, payload, and signature");
182
- }
183
- const header = dispatchHeaderSchema.parse(JSON.parse(new TextDecoder().decode(base64urlDecodeToBytes(encodedHeader))));
184
- const claims = dispatchClaimsSchema.parse(JSON.parse(new TextDecoder().decode(base64urlDecodeToBytes(encodedPayload))));
185
- if (header.alg !== "EdDSA") {
186
- throw new Error("Unsupported channel dispatch JWS algorithm");
187
- }
188
- const signingInput = new TextEncoder().encode(`${encodedHeader}.${encodedPayload}`);
189
- const signature = base64urlDecodeToBytes(encodedSignature);
190
- const publicKey = await importEd25519PublicKey(options.publicKeyPem);
191
- const verified = await dntShim.crypto.subtle.verify("Ed25519", publicKey, signature, signingInput);
192
- if (!verified) {
193
- throw new Error("Channel dispatch signature verification failed");
194
- }
195
- if (claims.aud !== options.audience) {
196
- throw new Error("Channel dispatch audience mismatch");
197
- }
198
- if (options.expectedProjectId && claims.project_id !== options.expectedProjectId) {
199
- throw new Error("Channel dispatch project mismatch");
200
- }
201
- const now = Math.floor(Date.now() / 1000);
202
- if (claims.exp <= now) {
203
- throw new Error("Channel dispatch signature expired");
204
- }
205
- if (claims.iat > now + SIGNATURE_SKEW_SECONDS) {
206
- throw new Error("Channel dispatch signature issued in the future");
207
- }
208
- if (now - claims.iat > options.maxAgeSeconds) {
209
- throw new Error("Channel dispatch signature is too old");
210
- }
211
- const bodySha256 = await sha256Base64url(body);
212
- if (claims.body_sha256 !== bodySha256) {
213
- throw new Error("Channel dispatch body hash mismatch");
214
- }
215
- return claims;
216
- }
119
+ export { verifyDispatchJws } from "./control-plane.js";
217
120
  function normalizeConversationPart(part) {
218
121
  if (part.type === "text" && typeof part.text === "string") {
219
122
  return { type: "text", text: part.text };
@@ -0,0 +1,35 @@
1
+ import type { AgentResponse } from "../agent/index.js";
2
+ type RuntimeDataEvent = Record<string, unknown> & {
3
+ type: string;
4
+ };
5
+ export interface RunFinishedMetadata {
6
+ provider?: string;
7
+ model?: string;
8
+ inputTokens?: number;
9
+ outputTokens?: number;
10
+ totalTokens?: number;
11
+ finishReason?: string;
12
+ }
13
+ export interface StreamTransformState {
14
+ messageId: string | null;
15
+ textOpen: boolean;
16
+ stepIndex: number;
17
+ sawTerminalError: boolean;
18
+ metadata: RunFinishedMetadata;
19
+ }
20
+ export declare function createStreamTransformState(): StreamTransformState;
21
+ export declare function formatAgUiEvent(event: string, payload: Record<string, unknown>): Uint8Array;
22
+ export declare function parseSseJsonEvents(chunk: string): {
23
+ events: RuntimeDataEvent[];
24
+ remainder: string;
25
+ };
26
+ export declare function mapRuntimeEventToAgUi(state: StreamTransformState, event: RuntimeDataEvent): Array<{
27
+ event: string;
28
+ payload: Record<string, unknown>;
29
+ }>;
30
+ export declare function finalizeRunEvents(state: StreamTransformState, response: AgentResponse | null): Array<{
31
+ event: string;
32
+ payload: Record<string, unknown>;
33
+ }>;
34
+ export {};
35
+ //# sourceMappingURL=ag-ui-sse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ag-ui-sse.d.ts","sourceRoot":"","sources":["../../../src/src/internal-agents/ag-ui-sse.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAOvD,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,mBAAmB,CAAC;CAC/B;AAED,wBAAgB,0BAA0B,IAAI,oBAAoB,CAQjE;AA2DD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,CAI3F;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;IACjD,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB,CAyBA;AAkDD,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,gBAAgB,GACtB,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAoH5D;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,oBAAoB,EAC3B,QAAQ,EAAE,aAAa,GAAG,IAAI,GAC7B,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAwB5D"}
@@ -0,0 +1,263 @@
1
+ import * as dntShim from "../../_dnt.shims.js";
2
+ import { serverLogger } from "../utils/index.js";
3
+ import { z } from "zod";
4
+ const encoder = new TextEncoder();
5
+ const logger = serverLogger.component("internal-agents-ag-ui-sse");
6
+ export function createStreamTransformState() {
7
+ return {
8
+ messageId: null,
9
+ textOpen: false,
10
+ stepIndex: 0,
11
+ sawTerminalError: false,
12
+ metadata: {},
13
+ };
14
+ }
15
+ const agUiEventPayloadSchemas = {
16
+ RunStarted: z.object({
17
+ runId: z.string().min(1),
18
+ threadId: z.string().min(1),
19
+ agentId: z.string().min(1),
20
+ }),
21
+ TextMessageStart: z.object({
22
+ messageId: z.string().min(1),
23
+ role: z.literal("assistant"),
24
+ }),
25
+ TextMessageContent: z.object({
26
+ messageId: z.string().min(1),
27
+ delta: z.string(),
28
+ }),
29
+ TextMessageEnd: z.object({
30
+ messageId: z.string().min(1),
31
+ }),
32
+ ToolCallStart: z.object({
33
+ toolCallId: z.string().min(1),
34
+ toolCallName: z.string().min(1),
35
+ }),
36
+ ToolCallArgs: z.object({
37
+ toolCallId: z.string().min(1),
38
+ delta: z.string(),
39
+ }),
40
+ ToolCallEnd: z.object({
41
+ toolCallId: z.string().min(1),
42
+ }),
43
+ ToolCallResult: z.object({
44
+ toolCallId: z.string().min(1),
45
+ result: z.unknown(),
46
+ isError: z.boolean().optional(),
47
+ }),
48
+ StepStarted: z.object({
49
+ stepIndex: z.number().int().positive(),
50
+ }),
51
+ StepFinished: z.object({
52
+ stepIndex: z.number().int().positive(),
53
+ }),
54
+ RunError: z.object({
55
+ code: z.string().min(1).optional(),
56
+ message: z.string().min(1),
57
+ }),
58
+ RunFinished: z.object({
59
+ metadata: z.object({
60
+ provider: z.string().optional(),
61
+ model: z.string().optional(),
62
+ inputTokens: z.number().int().nonnegative().optional(),
63
+ outputTokens: z.number().int().nonnegative().optional(),
64
+ totalTokens: z.number().int().nonnegative().optional(),
65
+ finishReason: z.string().optional(),
66
+ }),
67
+ }),
68
+ };
69
+ export function formatAgUiEvent(event, payload) {
70
+ const schema = agUiEventPayloadSchemas[event];
71
+ const validatedPayload = schema ? schema.parse(payload) : payload;
72
+ return encoder.encode(`event: ${event}\ndata: ${JSON.stringify(validatedPayload)}\n\n`);
73
+ }
74
+ export function parseSseJsonEvents(chunk) {
75
+ const blocks = chunk.split("\n\n");
76
+ const remainder = blocks.pop() ?? "";
77
+ const events = blocks.flatMap((block) => {
78
+ const dataLines = block.split("\n")
79
+ .filter((line) => line.startsWith("data:"))
80
+ .map((line) => line.slice(5).trimStart());
81
+ if (!dataLines.length) {
82
+ return [];
83
+ }
84
+ try {
85
+ const payload = JSON.parse(dataLines.join("\n"));
86
+ return [payload];
87
+ }
88
+ catch (error) {
89
+ logger.warn("Skipping malformed runtime SSE event payload", {
90
+ error,
91
+ dataLength: dataLines.join("\n").length,
92
+ });
93
+ return [];
94
+ }
95
+ });
96
+ return { events, remainder };
97
+ }
98
+ function getMessageId(state, event) {
99
+ if (typeof event.messageId === "string") {
100
+ state.messageId = event.messageId;
101
+ return event.messageId;
102
+ }
103
+ if (!state.messageId && typeof event.id === "string") {
104
+ state.messageId = event.id;
105
+ }
106
+ if (!state.messageId) {
107
+ state.messageId = dntShim.crypto.randomUUID();
108
+ }
109
+ return state.messageId;
110
+ }
111
+ function applyDataMetadata(state, event) {
112
+ const data = event.data && typeof event.data === "object" && !Array.isArray(event.data)
113
+ ? event.data
114
+ : event;
115
+ if (typeof data.model === "string") {
116
+ state.metadata.model = data.model;
117
+ const provider = data.model.split("/")[0];
118
+ if (provider) {
119
+ state.metadata.provider = provider;
120
+ }
121
+ }
122
+ }
123
+ function applyResponseMetadata(state, response) {
124
+ if (!response)
125
+ return;
126
+ if (response.usage) {
127
+ state.metadata.inputTokens = response.usage.promptTokens;
128
+ state.metadata.outputTokens = response.usage.completionTokens;
129
+ state.metadata.totalTokens = response.usage.totalTokens;
130
+ }
131
+ const finishReason = response.metadata && typeof response.metadata === "object"
132
+ ? response.metadata.finishReason
133
+ : undefined;
134
+ if (typeof finishReason === "string") {
135
+ state.metadata.finishReason = finishReason;
136
+ }
137
+ }
138
+ export function mapRuntimeEventToAgUi(state, event) {
139
+ switch (event.type) {
140
+ case "message-start":
141
+ getMessageId(state, event);
142
+ return [];
143
+ case "text-start": {
144
+ if (state.textOpen)
145
+ return [];
146
+ const messageId = getMessageId(state, event);
147
+ state.textOpen = true;
148
+ return [{
149
+ event: "TextMessageStart",
150
+ payload: { messageId, role: "assistant" },
151
+ }];
152
+ }
153
+ case "text-delta": {
154
+ const messageId = getMessageId(state, event);
155
+ if (!state.textOpen) {
156
+ state.textOpen = true;
157
+ return [
158
+ { event: "TextMessageStart", payload: { messageId, role: "assistant" } },
159
+ {
160
+ event: "TextMessageContent",
161
+ payload: { messageId, delta: typeof event.delta === "string" ? event.delta : "" },
162
+ },
163
+ ];
164
+ }
165
+ return [{
166
+ event: "TextMessageContent",
167
+ payload: { messageId, delta: typeof event.delta === "string" ? event.delta : "" },
168
+ }];
169
+ }
170
+ case "text-end": {
171
+ if (!state.textOpen)
172
+ return [];
173
+ state.textOpen = false;
174
+ return [{
175
+ event: "TextMessageEnd",
176
+ payload: { messageId: getMessageId(state, event) },
177
+ }];
178
+ }
179
+ case "tool-input-start":
180
+ return [{
181
+ event: "ToolCallStart",
182
+ payload: {
183
+ toolCallId: event.toolCallId,
184
+ toolCallName: event.toolName,
185
+ },
186
+ }];
187
+ case "tool-input-delta":
188
+ return [{
189
+ event: "ToolCallArgs",
190
+ payload: {
191
+ toolCallId: event.toolCallId,
192
+ delta: typeof event.inputTextDelta === "string" ? event.inputTextDelta : "",
193
+ },
194
+ }];
195
+ case "tool-input-available":
196
+ return [{
197
+ event: "ToolCallEnd",
198
+ payload: { toolCallId: event.toolCallId },
199
+ }];
200
+ case "tool-output-available":
201
+ return [{
202
+ event: "ToolCallResult",
203
+ payload: {
204
+ toolCallId: event.toolCallId,
205
+ result: event.output,
206
+ },
207
+ }];
208
+ case "tool-output-error":
209
+ return [{
210
+ event: "ToolCallResult",
211
+ payload: {
212
+ toolCallId: event.toolCallId,
213
+ result: { error: event.errorText },
214
+ isError: true,
215
+ },
216
+ }];
217
+ case "step-start":
218
+ state.stepIndex += 1;
219
+ return [{
220
+ event: "StepStarted",
221
+ payload: { stepIndex: state.stepIndex },
222
+ }];
223
+ case "step-end":
224
+ return [{
225
+ event: "StepFinished",
226
+ payload: { stepIndex: state.stepIndex },
227
+ }];
228
+ case "data":
229
+ applyDataMetadata(state, event);
230
+ return [];
231
+ case "error":
232
+ state.sawTerminalError = true;
233
+ return [{
234
+ event: "RunError",
235
+ payload: {
236
+ message: typeof event.error === "string" ? event.error : "Agent run failed",
237
+ },
238
+ }];
239
+ default:
240
+ return [];
241
+ }
242
+ }
243
+ export function finalizeRunEvents(state, response) {
244
+ applyResponseMetadata(state, response);
245
+ if (state.sawTerminalError) {
246
+ return [];
247
+ }
248
+ const events = [];
249
+ if (state.textOpen) {
250
+ state.textOpen = false;
251
+ events.push({
252
+ event: "TextMessageEnd",
253
+ payload: { messageId: getMessageId(state, { type: "text-end" }) },
254
+ });
255
+ }
256
+ events.push({
257
+ event: "RunFinished",
258
+ payload: {
259
+ metadata: state.metadata,
260
+ },
261
+ });
262
+ return events;
263
+ }
@@ -0,0 +1,20 @@
1
+ import * as dntShim from "../../_dnt.shims.js";
2
+ import type { HandlerContext } from "../types/index.js";
3
+ export declare class ControlPlaneRequestError extends Error {
4
+ readonly status: number;
5
+ constructor(status: number, message: string);
6
+ }
7
+ export declare function verifyControlPlaneRequest(req: dntShim.Request, ctx: HandlerContext, rawBody: string, options?: {
8
+ expectedSubject?: string;
9
+ expectedSurface?: "studio" | "channels" | "a2a" | "mcp";
10
+ }): Promise<{
11
+ project_id: string;
12
+ sub: string;
13
+ surface: "mcp" | "studio" | "channels" | "a2a";
14
+ iss: string;
15
+ aud: string;
16
+ iat: number;
17
+ exp: number;
18
+ request_hash: string;
19
+ }>;
20
+ //# sourceMappingURL=control-plane-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-plane-auth.d.ts","sourceRoot":"","sources":["../../../src/src/internal-agents/control-plane-auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAE/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAQxD,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK5C;AAED,wBAAsB,yBAAyB,CAC7C,GAAG,EAAE,OAAO,CAAC,OAAO,EACpB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,KAAK,GAAG,KAAK,CAAC;CACpD;;;;;;;;;GAsDP"}
@@ -0,0 +1,56 @@
1
+ import { verifyControlPlaneJws } from "../channels/control-plane.js";
2
+ import { serverLogger } from "../utils/index.js";
3
+ import { HTTP_INTERNAL_SERVER_ERROR } from "../utils/constants/index.js";
4
+ const CONTROL_PLANE_JWS_HEADER = "x-veryfront-control-plane-jws";
5
+ const MAX_CONTROL_PLANE_SIGNATURE_AGE_SECONDS = 60;
6
+ const logger = serverLogger.component("internal-agents-auth");
7
+ export class ControlPlaneRequestError extends Error {
8
+ status;
9
+ constructor(status, message) {
10
+ super(message);
11
+ this.status = status;
12
+ this.name = "ControlPlaneRequestError";
13
+ }
14
+ }
15
+ export async function verifyControlPlaneRequest(req, ctx, rawBody, options = {}) {
16
+ const publicKeyPem = ctx.adapter.env.get("CHANNEL_DISPATCH_SIGNING_PUBLIC_KEY");
17
+ if (!publicKeyPem) {
18
+ throw new ControlPlaneRequestError(HTTP_INTERNAL_SERVER_ERROR, "Control-plane verification is not configured");
19
+ }
20
+ const projectSlug = ctx.projectSlug;
21
+ if (!projectSlug) {
22
+ throw new ControlPlaneRequestError(400, "Project context is unavailable");
23
+ }
24
+ const controlPlaneJws = req.headers.get(CONTROL_PLANE_JWS_HEADER);
25
+ if (!controlPlaneJws) {
26
+ throw new ControlPlaneRequestError(401, "Missing control-plane signature");
27
+ }
28
+ try {
29
+ return await verifyControlPlaneJws(controlPlaneJws, rawBody, {
30
+ audience: projectSlug,
31
+ expectedProjectId: ctx.projectId,
32
+ expectedSubject: options.expectedSubject,
33
+ expectedSurface: options.expectedSurface,
34
+ publicKeyPem,
35
+ maxAgeSeconds: MAX_CONTROL_PLANE_SIGNATURE_AGE_SECONDS,
36
+ });
37
+ }
38
+ catch (error) {
39
+ const isAuthError = error instanceof Error && (error.message.includes("Control-plane") ||
40
+ error.message.includes("Unsupported"));
41
+ if (isAuthError) {
42
+ logger.warn("Invalid control-plane signature", {
43
+ error,
44
+ projectSlug,
45
+ expectedSubject: options.expectedSubject,
46
+ expectedSurface: options.expectedSurface,
47
+ });
48
+ throw new ControlPlaneRequestError(401, "Invalid control-plane signature");
49
+ }
50
+ logger.error("Unexpected error during control-plane verification", {
51
+ error,
52
+ projectSlug,
53
+ });
54
+ throw new ControlPlaneRequestError(HTTP_INTERNAL_SERVER_ERROR, "Internal error during request verification");
55
+ }
56
+ }
@@ -0,0 +1,9 @@
1
+ import * as dntShim from "../../_dnt.shims.js";
2
+ export declare const INTERNAL_AGENT_STREAM_MAX_BODY_BYTES: number;
3
+ export declare const INTERNAL_AGENT_CONTROL_PLANE_MAX_BODY_BYTES: number;
4
+ export declare class InternalAgentRequestBodyTooLargeError extends Error {
5
+ readonly status = 413;
6
+ constructor(message?: string);
7
+ }
8
+ export declare function readInternalAgentRequestBody(request: dntShim.Request, maxBodyBytes?: number): Promise<string>;
9
+ //# sourceMappingURL=request-body.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-body.d.ts","sourceRoot":"","sources":["../../../src/src/internal-agents/request-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAQ/C,eAAO,MAAM,oCAAoC,QAA8B,CAAC;AAChF,eAAO,MAAM,2CAA2C,QAAa,CAAC;AAEtE,qBAAa,qCAAsC,SAAQ,KAAK;IAC9D,QAAQ,CAAC,MAAM,OAA0B;gBAE7B,OAAO,SAAsB;CAI1C;AAED,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,OAAO,CAAC,OAAO,EACxB,YAAY,SAAuC,GAClD,OAAO,CAAC,MAAM,CAAC,CAkBjB"}
@@ -0,0 +1,28 @@
1
+ import { VeryfrontError } from "../errors/types.js";
2
+ import { readBodyWithLimit } from "../security/index.js";
3
+ import { DEFAULT_MAX_BODY_SIZE_BYTES, HTTP_PAYLOAD_TOO_LARGE, } from "../utils/constants/index.js";
4
+ export const INTERNAL_AGENT_STREAM_MAX_BODY_BYTES = DEFAULT_MAX_BODY_SIZE_BYTES;
5
+ export const INTERNAL_AGENT_CONTROL_PLANE_MAX_BODY_BYTES = 128 * 1024;
6
+ export class InternalAgentRequestBodyTooLargeError extends Error {
7
+ status = HTTP_PAYLOAD_TOO_LARGE;
8
+ constructor(message = "Payload too large") {
9
+ super(message);
10
+ this.name = "InternalAgentRequestBodyTooLargeError";
11
+ }
12
+ }
13
+ export async function readInternalAgentRequestBody(request, maxBodyBytes = INTERNAL_AGENT_STREAM_MAX_BODY_BYTES) {
14
+ if (!request.body) {
15
+ return "";
16
+ }
17
+ try {
18
+ return await readBodyWithLimit(request, maxBodyBytes);
19
+ }
20
+ catch (error) {
21
+ if (error instanceof VeryfrontError &&
22
+ error.slug === "input-validation-failed" &&
23
+ error.detail === "Request body exceeds size limit") {
24
+ throw new InternalAgentRequestBodyTooLargeError();
25
+ }
26
+ throw error;
27
+ }
28
+ }
@@ -0,0 +1,14 @@
1
+ import * as dntShim from "../../_dnt.shims.js";
2
+ import { type Agent, type AgentMessage as Message, type AgentResponse } from "../agent/index.js";
3
+ import { type AgentRunSessionManager } from "./session-manager.js";
4
+ import type { RuntimeRunAgentInput } from "./schema.js";
5
+ export interface RuntimeAgentStreamExecutionDeps {
6
+ sessionManager: AgentRunSessionManager;
7
+ createRuntime?: (agent: Agent, mergedTools: Agent["config"]["tools"]) => {
8
+ stream: (messages: Message[], context?: Record<string, unknown>, callbacks?: {
9
+ onFinish?: (response: AgentResponse) => void;
10
+ }) => Promise<ReadableStream<Uint8Array>>;
11
+ };
12
+ }
13
+ export declare function createRuntimeAgentStreamResponse(input: RuntimeRunAgentInput, agent: Agent, deps: RuntimeAgentStreamExecutionDeps): Promise<dntShim.Response>;
14
+ //# sourceMappingURL=run-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-stream.d.ts","sourceRoot":"","sources":["../../../src/src/internal-agents/run-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EACL,KAAK,KAAK,EACV,KAAK,YAAY,IAAI,OAAO,EAC5B,KAAK,aAAa,EAEnB,MAAM,mBAAmB,CAAC;AAW3B,OAAO,EAA0B,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAIxD,MAAM,WAAW,+BAA+B;IAC9C,cAAc,EAAE,sBAAsB,CAAC;IACvC,aAAa,CAAC,EAAE,CACd,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAClC;QACH,MAAM,EAAE,CACN,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,SAAS,CAAC,EAAE;YACV,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;SAC9C,KACE,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;KAC1C,CAAC;CACH;AAsKD,wBAAsB,gCAAgC,CACpD,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,+BAA+B,GACpC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAmJ3B"}