veryfront 0.1.62 → 0.1.64

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 (73) hide show
  1. package/esm/cli/templates/manifest.js +37 -37
  2. package/esm/deno.d.ts +3 -0
  3. package/esm/deno.js +6 -3
  4. package/esm/src/agent/composition/composition.d.ts.map +1 -1
  5. package/esm/src/agent/composition/composition.js +13 -3
  6. package/esm/src/agent/factory.d.ts.map +1 -1
  7. package/esm/src/agent/factory.js +3 -3
  8. package/esm/src/agent/middleware/security/validator.d.ts +92 -0
  9. package/esm/src/agent/middleware/security/validator.d.ts.map +1 -0
  10. package/esm/src/agent/middleware/security/validator.js +187 -0
  11. package/esm/src/agent/runtime/index.d.ts +3 -2
  12. package/esm/src/agent/runtime/index.d.ts.map +1 -1
  13. package/esm/src/agent/runtime/index.js +16 -8
  14. package/esm/src/agent/types.d.ts +4 -0
  15. package/esm/src/agent/types.d.ts.map +1 -1
  16. package/esm/src/channels/invoke.d.ts +491 -0
  17. package/esm/src/channels/invoke.d.ts.map +1 -0
  18. package/esm/src/channels/invoke.js +417 -0
  19. package/esm/src/embedding/embedding.js +2 -2
  20. package/esm/src/integrations/endpoint-executor.d.ts +1 -0
  21. package/esm/src/integrations/endpoint-executor.d.ts.map +1 -1
  22. package/esm/src/integrations/endpoint-executor.js +44 -0
  23. package/esm/src/integrations/schema.d.ts +2 -2
  24. package/esm/src/oauth/handlers/init-handler.d.ts +6 -2
  25. package/esm/src/oauth/handlers/init-handler.d.ts.map +1 -1
  26. package/esm/src/oauth/handlers/init-handler.js +8 -2
  27. package/esm/src/platform/compat/opaque-deps.d.ts.map +1 -1
  28. package/esm/src/platform/compat/opaque-deps.js +10 -1
  29. package/esm/src/prompt/factory.d.ts.map +1 -1
  30. package/esm/src/prompt/factory.js +9 -1
  31. package/esm/src/react/components/ai/markdown.d.ts.map +1 -1
  32. package/esm/src/react/components/ai/markdown.js +4 -4
  33. package/esm/src/server/handlers/dev/framework-candidates.generated.d.ts.map +1 -1
  34. package/esm/src/server/handlers/dev/framework-candidates.generated.js +5 -4
  35. package/esm/src/server/handlers/preview/markdown-html-generator.js +1 -1
  36. package/esm/src/server/handlers/request/api/api-handler-wrapper.d.ts.map +1 -1
  37. package/esm/src/server/handlers/request/api/api-handler-wrapper.js +1 -74
  38. package/esm/src/server/handlers/request/api/project-discovery.d.ts +9 -0
  39. package/esm/src/server/handlers/request/api/project-discovery.d.ts.map +1 -0
  40. package/esm/src/server/handlers/request/api/project-discovery.js +74 -0
  41. package/esm/src/server/handlers/request/channel-assistants.handler.d.ts +11 -0
  42. package/esm/src/server/handlers/request/channel-assistants.handler.d.ts.map +1 -0
  43. package/esm/src/server/handlers/request/channel-assistants.handler.js +71 -0
  44. package/esm/src/server/handlers/request/channel-invoke.handler.d.ts +11 -0
  45. package/esm/src/server/handlers/request/channel-invoke.handler.d.ts.map +1 -0
  46. package/esm/src/server/handlers/request/channel-invoke.handler.js +72 -0
  47. package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
  48. package/esm/src/server/runtime-handler/index.js +4 -0
  49. package/esm/src/transforms/md/compiler/md-compiler.d.ts.map +1 -1
  50. package/esm/src/transforms/md/compiler/md-compiler.js +25 -1
  51. package/package.json +3 -1
  52. package/src/cli/templates/manifest.js +37 -37
  53. package/src/deno.js +6 -3
  54. package/src/src/agent/composition/composition.ts +15 -3
  55. package/src/src/agent/factory.ts +19 -6
  56. package/src/src/agent/middleware/security/validator.ts +288 -0
  57. package/src/src/agent/runtime/index.ts +26 -3
  58. package/src/src/agent/types.ts +4 -0
  59. package/src/src/channels/invoke.ts +546 -0
  60. package/src/src/embedding/embedding.ts +2 -2
  61. package/src/src/integrations/endpoint-executor.ts +51 -0
  62. package/src/src/oauth/handlers/init-handler.ts +20 -5
  63. package/src/src/platform/compat/opaque-deps.ts +19 -4
  64. package/src/src/prompt/factory.ts +10 -1
  65. package/src/src/react/components/ai/markdown.tsx +5 -4
  66. package/src/src/server/handlers/dev/framework-candidates.generated.ts +5 -4
  67. package/src/src/server/handlers/preview/markdown-html-generator.ts +1 -1
  68. package/src/src/server/handlers/request/api/api-handler-wrapper.ts +1 -85
  69. package/src/src/server/handlers/request/api/project-discovery.ts +86 -0
  70. package/src/src/server/handlers/request/channel-assistants.handler.ts +94 -0
  71. package/src/src/server/handlers/request/channel-invoke.handler.ts +95 -0
  72. package/src/src/server/runtime-handler/index.ts +4 -0
  73. package/src/src/transforms/md/compiler/md-compiler.ts +27 -1
@@ -0,0 +1,417 @@
1
+ import * as dntShim from "../../_dnt.shims.js";
2
+ import { fromError } from "../errors/veryfront-error.js";
3
+ import { serverLogger } from "../utils/index.js";
4
+ import { base64urlEncodeBytes } from "../utils/base64url.js";
5
+ import { z } from "zod";
6
+ import { getAgent as getRegisteredAgent, getAllAgentIds as getRegisteredAgentIds, } from "../agent/composition/composition.js";
7
+ import { ensureProjectDiscovery as ensureProjectDiscoveryForProject } from "../server/handlers/request/api/project-discovery.js";
8
+ const logger = serverLogger.component("channels-invoke");
9
+ const SIGNATURE_SKEW_SECONDS = 5;
10
+ const rawHistoryPartSchema = z.object({
11
+ type: z.string(),
12
+ }).passthrough();
13
+ const channelAttachmentSchema = z.object({
14
+ id: z.string(),
15
+ kind: z.enum(["image", "file"]),
16
+ filename: z.string().optional(),
17
+ mediaType: z.string().optional(),
18
+ privateUrl: z.string().optional(),
19
+ });
20
+ const channelInvokeHistoryMessageSchema = z.object({
21
+ id: z.string(),
22
+ role: z.enum(["user", "assistant", "system", "tool"]),
23
+ parts: z.array(rawHistoryPartSchema),
24
+ metadata: z.record(z.unknown()).optional(),
25
+ createdAt: z.string().optional(),
26
+ });
27
+ const channelInvokeRequestWireSchema = z.object({
28
+ dispatchId: z.string().min(1),
29
+ conversationId: z.string().min(1),
30
+ projectId: z.string().min(1),
31
+ assistantId: z.string().min(1),
32
+ platform: z.literal("slack"),
33
+ inboundMessage: z.object({
34
+ text: z.string(),
35
+ userId: z.string(),
36
+ userName: z.string(),
37
+ isDirectMessage: z.boolean(),
38
+ attachments: z.array(channelAttachmentSchema).optional(),
39
+ }),
40
+ conversationHistory: z.array(channelInvokeHistoryMessageSchema),
41
+ generation: z.object({
42
+ maxResponseTokens: z.number().int().positive().max(16384).optional(),
43
+ }).optional(),
44
+ });
45
+ export const ChannelInvokeRequestSchema = channelInvokeRequestWireSchema;
46
+ export const ChannelAssistantsRequestSchema = z.object({
47
+ requestId: z.string().min(1),
48
+ projectId: z.string().min(1),
49
+ platform: z.literal("slack"),
50
+ });
51
+ export const ChannelAssistantSchema = z.object({
52
+ id: z.string().min(1),
53
+ name: z.string().min(1),
54
+ description: z.string().nullable().optional(),
55
+ model: z.string().nullable().optional(),
56
+ });
57
+ export const ChannelAssistantsResponseSchema = z.object({
58
+ assistants: z.array(ChannelAssistantSchema),
59
+ });
60
+ const channelTextPartSchema = z.object({
61
+ type: z.literal("text"),
62
+ text: z.string(),
63
+ });
64
+ const channelToolCallPartSchema = z.object({
65
+ type: z.literal("tool_call"),
66
+ id: z.string(),
67
+ name: z.string(),
68
+ input: z.record(z.unknown()),
69
+ state: z.enum(["streaming", "pending", "completed", "error"]),
70
+ });
71
+ const channelToolResultPartSchema = z.object({
72
+ type: z.literal("tool_result"),
73
+ tool_call_id: z.string(),
74
+ output: z.unknown(),
75
+ is_error: z.boolean().optional(),
76
+ });
77
+ const channelReasoningPartSchema = z.object({
78
+ type: z.literal("reasoning"),
79
+ text: z.string(),
80
+ });
81
+ const channelErrorPartSchema = z.object({
82
+ type: z.literal("error"),
83
+ code: z.string(),
84
+ message: z.string(),
85
+ });
86
+ export const ChannelResponsePartSchema = z.discriminatedUnion("type", [
87
+ channelTextPartSchema,
88
+ channelToolCallPartSchema,
89
+ channelToolResultPartSchema,
90
+ channelReasoningPartSchema,
91
+ channelErrorPartSchema,
92
+ ]);
93
+ export const ChannelInvokeResponseSchema = z.object({
94
+ ignored: z.boolean(),
95
+ responseParts: z.array(ChannelResponsePartSchema).optional(),
96
+ tokenUsage: z.object({
97
+ inputTokens: z.number().int().nonnegative().optional(),
98
+ outputTokens: z.number().int().nonnegative().optional(),
99
+ totalTokens: z.number().int().nonnegative().optional(),
100
+ }).optional(),
101
+ error: z.object({
102
+ code: z.enum(["provider_error", "internal_error"]),
103
+ retryable: z.boolean(),
104
+ }).optional(),
105
+ });
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
+ export const defaultChannelInvokeDeps = {
122
+ ensureProjectDiscovery: ensureProjectDiscoveryForProject,
123
+ getAgent: getRegisteredAgent,
124
+ getAllAgentIds: getRegisteredAgentIds,
125
+ };
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
+ 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));
144
+ return ChannelAssistantsResponseSchema.parse({ assistants });
145
+ }
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
+ }
217
+ function normalizeConversationPart(part) {
218
+ if (part.type === "text" && typeof part.text === "string") {
219
+ return { type: "text", text: part.text };
220
+ }
221
+ if (part.type === "tool_call" &&
222
+ typeof part.id === "string" &&
223
+ typeof part.name === "string" &&
224
+ part.input &&
225
+ typeof part.input === "object" &&
226
+ !Array.isArray(part.input)) {
227
+ return {
228
+ type: `tool-${part.name}`,
229
+ toolCallId: part.id,
230
+ toolName: part.name,
231
+ args: part.input,
232
+ };
233
+ }
234
+ if (part.type === "tool_result" && typeof part.tool_call_id === "string") {
235
+ return {
236
+ type: "tool-result",
237
+ toolCallId: part.tool_call_id,
238
+ toolName: typeof part.tool_name === "string" ? part.tool_name : "unknown",
239
+ result: "output" in part ? part.output : undefined,
240
+ };
241
+ }
242
+ return null;
243
+ }
244
+ export function normalizeConversationHistoryForRuntime(messages) {
245
+ return messages.map((message) => ({
246
+ id: message.id,
247
+ role: message.role,
248
+ parts: message.parts
249
+ .map((part) => normalizeConversationPart(part))
250
+ .filter((part) => part !== null),
251
+ ...(message.createdAt ? { timestamp: Date.parse(message.createdAt) || undefined } : {}),
252
+ ...(message.metadata ? { metadata: message.metadata } : {}),
253
+ }));
254
+ }
255
+ export function resolveChannelInvokeAgent(assistantId, deps) {
256
+ return deps.getAgent(assistantId);
257
+ }
258
+ function normalizeToolCallState(status) {
259
+ switch (status) {
260
+ case "completed":
261
+ return "completed";
262
+ case "error":
263
+ return "error";
264
+ default:
265
+ return "pending";
266
+ }
267
+ }
268
+ function convertAssistantPartToChannelResponsePart(part, knownToolCallIds) {
269
+ if (part.type === "text" && "text" in part) {
270
+ return channelTextPartSchema.parse({
271
+ type: "text",
272
+ text: part.text,
273
+ });
274
+ }
275
+ const isToolCallPart = part.type === "tool-call" ||
276
+ (part.type.startsWith("tool-") && part.type !== "tool-result");
277
+ if (isToolCallPart &&
278
+ "toolCallId" in part &&
279
+ "toolName" in part &&
280
+ !knownToolCallIds.has(part.toolCallId)) {
281
+ return channelToolCallPartSchema.parse({
282
+ type: "tool_call",
283
+ id: part.toolCallId,
284
+ name: part.toolName,
285
+ input: "args" in part ? part.args : ("input" in part ? part.input : {}),
286
+ state: "pending",
287
+ });
288
+ }
289
+ return null;
290
+ }
291
+ function findLastAssistantMessage(messages) {
292
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
293
+ if (messages[index]?.role === "assistant") {
294
+ return messages[index];
295
+ }
296
+ }
297
+ return undefined;
298
+ }
299
+ export function buildChannelResponseParts(response) {
300
+ const responseParts = [];
301
+ const knownToolCallIds = new Set();
302
+ if (response.thinking?.trim()) {
303
+ responseParts.push(channelReasoningPartSchema.parse({
304
+ type: "reasoning",
305
+ text: response.thinking,
306
+ }));
307
+ }
308
+ for (const toolCall of response.toolCalls) {
309
+ knownToolCallIds.add(toolCall.id);
310
+ responseParts.push(channelToolCallPartSchema.parse({
311
+ type: "tool_call",
312
+ id: toolCall.id,
313
+ name: toolCall.name,
314
+ input: toolCall.args,
315
+ state: normalizeToolCallState(toolCall.status),
316
+ }));
317
+ if (toolCall.status === "completed" || toolCall.status === "error") {
318
+ responseParts.push(channelToolResultPartSchema.parse({
319
+ type: "tool_result",
320
+ tool_call_id: toolCall.id,
321
+ output: toolCall.status === "error"
322
+ ? { error: toolCall.error ?? "Tool execution failed" }
323
+ : toolCall.result,
324
+ ...(toolCall.status === "error" ? { is_error: true } : {}),
325
+ }));
326
+ }
327
+ }
328
+ const lastAssistantMessage = findLastAssistantMessage(response.messages);
329
+ if (lastAssistantMessage) {
330
+ for (const part of lastAssistantMessage.parts) {
331
+ const converted = convertAssistantPartToChannelResponsePart(part, knownToolCallIds);
332
+ if (converted) {
333
+ responseParts.push(converted);
334
+ }
335
+ }
336
+ }
337
+ else if (response.text.trim()) {
338
+ responseParts.push(channelTextPartSchema.parse({
339
+ type: "text",
340
+ text: response.text,
341
+ }));
342
+ }
343
+ return responseParts;
344
+ }
345
+ function classifyRuntimeError(error) {
346
+ const veryfrontError = fromError(error);
347
+ if (veryfrontError?.type === "no_ai_available") {
348
+ return { code: "provider_error", retryable: false };
349
+ }
350
+ if (veryfrontError?.type === "api" || veryfrontError?.type === "network") {
351
+ return { code: "provider_error", retryable: true };
352
+ }
353
+ return { code: "internal_error", retryable: true };
354
+ }
355
+ export async function executeChannelInvoke(payload, ctx, deps) {
356
+ await deps.ensureProjectDiscovery(ctx);
357
+ const agent = resolveChannelInvokeAgent(payload.assistantId, deps);
358
+ if (!agent) {
359
+ logger.error("Channel invoke could not resolve a runtime agent for the request", {
360
+ requestedAssistantId: payload.assistantId,
361
+ discoveredAgentIds: deps.getAllAgentIds(),
362
+ projectSlug: ctx.projectSlug,
363
+ projectId: ctx.projectId,
364
+ });
365
+ return {
366
+ ignored: false,
367
+ error: {
368
+ code: "internal_error",
369
+ retryable: false,
370
+ },
371
+ };
372
+ }
373
+ const messages = normalizeConversationHistoryForRuntime(payload.conversationHistory);
374
+ await agent.clearMemory();
375
+ try {
376
+ const result = await agent.generate({
377
+ input: messages,
378
+ context: {
379
+ requestId: payload.dispatchId,
380
+ dispatchId: payload.dispatchId,
381
+ conversationId: payload.conversationId,
382
+ projectId: payload.projectId,
383
+ assistantId: payload.assistantId,
384
+ channel: payload.inboundMessage,
385
+ },
386
+ ...(payload.generation?.maxResponseTokens
387
+ ? {
388
+ maxOutputTokens: payload.generation.maxResponseTokens,
389
+ }
390
+ : {}),
391
+ });
392
+ return ChannelInvokeResponseSchema.parse({
393
+ ignored: false,
394
+ responseParts: buildChannelResponseParts(result),
395
+ tokenUsage: result.usage
396
+ ? {
397
+ inputTokens: result.usage.promptTokens,
398
+ outputTokens: result.usage.completionTokens,
399
+ totalTokens: result.usage.totalTokens,
400
+ }
401
+ : undefined,
402
+ });
403
+ }
404
+ catch (error) {
405
+ logger.error("Channel invoke runtime execution failed", {
406
+ error: error instanceof Error ? error.message : String(error),
407
+ stack: error instanceof Error ? error.stack : undefined,
408
+ projectSlug: ctx.projectSlug,
409
+ projectId: ctx.projectId,
410
+ dispatchId: payload.dispatchId,
411
+ });
412
+ return {
413
+ ignored: false,
414
+ error: classifyRuntimeError(error),
415
+ };
416
+ }
417
+ }
@@ -30,10 +30,10 @@ export function embedding(config) {
30
30
  return {
31
31
  model: modelId,
32
32
  async embed(text) {
33
- const value = queryPrefix + text;
34
- if (!value.trim()) {
33
+ if (!text.trim()) {
35
34
  throw new Error("Cannot embed an empty string");
36
35
  }
36
+ const value = queryPrefix + text;
37
37
  const result = await embed({ model, value });
38
38
  return result.embedding;
39
39
  },
@@ -1,4 +1,5 @@
1
1
  import type { IntegrationEndpoint } from "./types.js";
2
+ export declare function validateEndpointUrl(url: string): void;
2
3
  interface ExecutionContext {
3
4
  integration: string;
4
5
  toolId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint-executor.d.ts","sourceRoot":"","sources":["../../../src/src/integrations/endpoint-executor.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGtD,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,mBAAmB,EAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAK9C"}
1
+ {"version":3,"file":"endpoint-executor.d.ts","sourceRoot":"","sources":["../../../src/src/integrations/endpoint-executor.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAetD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAiCrD;AAED,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,mBAAmB,EAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAK9C"}
@@ -8,6 +8,48 @@
8
8
  import * as dntShim from "../../_dnt.shims.js";
9
9
  import { logger } from "../utils/index.js";
10
10
  import { INVALID_ARGUMENT } from "../errors/index.js";
11
+ const PRIVATE_IP_RANGES = [
12
+ /^127\./, // 127.0.0.0/8
13
+ /^10\./, // 10.0.0.0/8
14
+ /^172\.(1[6-9]|2\d|3[01])\./, // 172.16.0.0/12
15
+ /^192\.168\./, // 192.168.0.0/16
16
+ /^169\.254\./, // 169.254.0.0/16
17
+ /^0\./, // 0.0.0.0/8
18
+ /^::1$/, // IPv6 loopback
19
+ /^f[cd][0-9a-f]{2}:/i, // IPv6 unique local (fc00::/7)
20
+ /^fe80:/i, // IPv6 link-local (fe80::/10)
21
+ ];
22
+ export function validateEndpointUrl(url) {
23
+ let parsed;
24
+ try {
25
+ parsed = new URL(url);
26
+ }
27
+ catch {
28
+ throw INVALID_ARGUMENT.create({ detail: `Invalid endpoint URL: ${url}` });
29
+ }
30
+ if (parsed.protocol !== "https:") {
31
+ throw INVALID_ARGUMENT.create({
32
+ detail: `Endpoint URL must use HTTPS: ${parsed.protocol}`,
33
+ });
34
+ }
35
+ const hostname = parsed.hostname.toLowerCase();
36
+ if (hostname === "localhost") {
37
+ throw INVALID_ARGUMENT.create({
38
+ detail: "Endpoint URL must not target localhost",
39
+ });
40
+ }
41
+ // Strip IPv6 brackets for regex matching
42
+ const bare = hostname.startsWith("[") && hostname.endsWith("]")
43
+ ? hostname.slice(1, -1)
44
+ : hostname;
45
+ for (const range of PRIVATE_IP_RANGES) {
46
+ if (range.test(bare)) {
47
+ throw INVALID_ARGUMENT.create({
48
+ detail: "Endpoint URL must not target private/internal networks",
49
+ });
50
+ }
51
+ }
52
+ }
11
53
  export async function executeEndpoint(endpoint, args, accessToken, ctx) {
12
54
  if (endpoint.type === "graphql") {
13
55
  return executeGraphQL(endpoint, args, accessToken, ctx);
@@ -40,6 +82,7 @@ async function executeGraphQL(endpoint, args, accessToken, ctx) {
40
82
  headers[key] = args[key] !== undefined ? String(args[key]) : String(def.default ?? "");
41
83
  }
42
84
  }
85
+ validateEndpointUrl(endpoint.url);
43
86
  logger.debug("Executing GraphQL endpoint", {
44
87
  integration: ctx.integration,
45
88
  tool: ctx.toolId,
@@ -112,6 +155,7 @@ async function executeRest(endpoint, args, accessToken, ctx) {
112
155
  body = JSON.stringify(bodyObj);
113
156
  headers["Content-Type"] = endpoint.contentType ?? "application/json";
114
157
  }
158
+ validateEndpointUrl(urlObj.toString());
115
159
  logger.debug("Executing REST endpoint", {
116
160
  integration: ctx.integration,
117
161
  tool: ctx.toolId,
@@ -458,7 +458,7 @@ export declare const IntegrationConfigSchema: z.ZodObject<{
458
458
  id?: string | undefined;
459
459
  requiresWrite?: boolean | undefined;
460
460
  }[];
461
- name: "github" | "aws" | "twitter" | "zoom" | "anthropic" | "linear" | "gmail" | "calendar" | "sheets" | "drive" | "outlook" | "teams" | "sharepoint" | "onedrive" | "jira" | "confluence" | "bitbucket" | "slack" | "notion" | "figma" | "discord" | "gitlab" | "airtable" | "dropbox" | "hubspot" | "salesforce" | "asana" | "monday" | "intercom" | "freshdesk" | "mailchimp" | "shopify" | "quickbooks" | "xero" | "box" | "webex" | "trello" | "clickup" | "pipedrive" | "servicenow" | "supabase" | "neon" | "stripe" | "sentry" | "posthog" | "zendesk" | "docs-google" | "snowflake" | "mixpanel" | "twilio";
461
+ name: "github" | "aws" | "twitter" | "zoom" | "anthropic" | "linear" | "slack" | "gmail" | "calendar" | "sheets" | "drive" | "outlook" | "teams" | "sharepoint" | "onedrive" | "jira" | "confluence" | "bitbucket" | "notion" | "figma" | "discord" | "gitlab" | "airtable" | "dropbox" | "hubspot" | "salesforce" | "asana" | "monday" | "intercom" | "freshdesk" | "mailchimp" | "shopify" | "quickbooks" | "xero" | "box" | "webex" | "trello" | "clickup" | "pipedrive" | "servicenow" | "supabase" | "neon" | "stripe" | "sentry" | "posthog" | "zendesk" | "docs-google" | "snowflake" | "mixpanel" | "twilio";
462
462
  displayName: string;
463
463
  category?: string | undefined;
464
464
  icon?: string | undefined;
@@ -524,7 +524,7 @@ export declare const IntegrationConfigSchema: z.ZodObject<{
524
524
  id?: string | undefined;
525
525
  requiresWrite?: boolean | undefined;
526
526
  }[];
527
- name: "github" | "aws" | "twitter" | "zoom" | "anthropic" | "linear" | "gmail" | "calendar" | "sheets" | "drive" | "outlook" | "teams" | "sharepoint" | "onedrive" | "jira" | "confluence" | "bitbucket" | "slack" | "notion" | "figma" | "discord" | "gitlab" | "airtable" | "dropbox" | "hubspot" | "salesforce" | "asana" | "monday" | "intercom" | "freshdesk" | "mailchimp" | "shopify" | "quickbooks" | "xero" | "box" | "webex" | "trello" | "clickup" | "pipedrive" | "servicenow" | "supabase" | "neon" | "stripe" | "sentry" | "posthog" | "zendesk" | "docs-google" | "snowflake" | "mixpanel" | "twilio";
527
+ name: "github" | "aws" | "twitter" | "zoom" | "anthropic" | "linear" | "slack" | "gmail" | "calendar" | "sheets" | "drive" | "outlook" | "teams" | "sharepoint" | "onedrive" | "jira" | "confluence" | "bitbucket" | "notion" | "figma" | "discord" | "gitlab" | "airtable" | "dropbox" | "hubspot" | "salesforce" | "asana" | "monday" | "intercom" | "freshdesk" | "mailchimp" | "shopify" | "quickbooks" | "xero" | "box" | "webex" | "trello" | "clickup" | "pipedrive" | "servicenow" | "supabase" | "neon" | "stripe" | "sentry" | "posthog" | "zendesk" | "docs-google" | "snowflake" | "mixpanel" | "twilio";
528
528
  displayName: string;
529
529
  category?: string | undefined;
530
530
  icon?: string | undefined;
@@ -20,9 +20,13 @@ export interface OAuthStatusHandlerOptions {
20
20
  tokenStore?: TokenStore;
21
21
  /** EnvReader for dynamic env vars (defaults to getEnv) */
22
22
  envReader?: EnvReader;
23
+ /** Optional authentication check — return true if the request is authenticated */
24
+ isAuthenticated?: (req: dntShim.Request) => boolean | Promise<boolean>;
23
25
  }
24
- export declare function createOAuthStatusHandler(config: OAuthServiceConfig, options?: OAuthStatusHandlerOptions): () => Promise<dntShim.Response>;
26
+ export declare function createOAuthStatusHandler(config: OAuthServiceConfig, options?: OAuthStatusHandlerOptions): (req: dntShim.Request) => Promise<dntShim.Response>;
25
27
  export declare function createOAuthDisconnectHandler(config: OAuthServiceConfig, options?: {
26
28
  tokenStore?: TokenStore;
27
- }): () => Promise<dntShim.Response>;
29
+ /** Optional authentication check — return true if the request is authenticated */
30
+ isAuthenticated?: (req: dntShim.Request) => boolean | Promise<boolean>;
31
+ }): (req: dntShim.Request) => Promise<dntShim.Response>;
28
32
  //# sourceMappingURL=init-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init-handler.d.ts","sourceRoot":"","sources":["../../../../src/src/oauth/handlers/init-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AAElD,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK3F,MAAM,WAAW,uBAAuB;IACtC,oDAAoD;IACpD,UAAU,CAAC,EAAE,UAAU,CAAC;IAExB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,uCAAuC;IACvC,WAAW,CAAC,EAAE,uBAAuB,CAAC;IAEtC,gFAAgF;IAChF,GAAG,CAAC,EAAE,iBAAiB,CAAC;IAExB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,uBAA4B,GACpC,MAAM,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAsCjC;AAED,MAAM,WAAW,yBAAyB;IACxC,oDAAoD;IACpD,UAAU,CAAC,EAAE,UAAU,CAAC;IAExB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,yBAA8B,GACtC,MAAM,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAoBjC;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,UAAU,CAAA;CAAO,GACxC,MAAM,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAWjC"}
1
+ {"version":3,"file":"init-handler.d.ts","sourceRoot":"","sources":["../../../../src/src/oauth/handlers/init-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AAElD,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK3F,MAAM,WAAW,uBAAuB;IACtC,oDAAoD;IACpD,UAAU,CAAC,EAAE,UAAU,CAAC;IAExB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,uCAAuC;IACvC,WAAW,CAAC,EAAE,uBAAuB,CAAC;IAEtC,gFAAgF;IAChF,GAAG,CAAC,EAAE,iBAAiB,CAAC;IAExB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,uBAA4B,GACpC,MAAM,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAsCjC;AAED,MAAM,WAAW,yBAAyB;IACxC,oDAAoD;IACpD,UAAU,CAAC,EAAE,UAAU,CAAC;IAExB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB,kFAAkF;IAClF,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,yBAA8B,GACtC,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAwBrD;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE;IACP,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,kFAAkF;IAClF,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnE,GACL,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAerD"}
@@ -37,7 +37,10 @@ export function createOAuthInitHandler(config, options = {}) {
37
37
  export function createOAuthStatusHandler(config, options = {}) {
38
38
  const tokenStore = options.tokenStore ?? memoryTokenStore;
39
39
  const envReader = options.envReader ?? getEnv;
40
- return async function handler() {
40
+ return async function handler(req) {
41
+ if (options.isAuthenticated && !(await options.isAuthenticated(req))) {
42
+ return dntShim.Response.json({ error: "Unauthorized" }, { status: 401 });
43
+ }
41
44
  const tokens = await tokenStore.getTokens(config.serviceId);
42
45
  const isConnected = !!tokens?.accessToken;
43
46
  const isExpired = tokens?.expiresAt ? Date.now() > tokens.expiresAt : false;
@@ -54,7 +57,10 @@ export function createOAuthStatusHandler(config, options = {}) {
54
57
  }
55
58
  export function createOAuthDisconnectHandler(config, options = {}) {
56
59
  const tokenStore = options.tokenStore ?? memoryTokenStore;
57
- return async function handler() {
60
+ return async function handler(req) {
61
+ if (options.isAuthenticated && !(await options.isAuthenticated(req))) {
62
+ return dntShim.Response.json({ error: "Unauthorized" }, { status: 401 });
63
+ }
58
64
  await tokenStore.clearTokens(config.serviceId);
59
65
  return dntShim.Response.json({
60
66
  success: true,
@@ -1 +1 @@
1
- {"version":3,"file":"opaque-deps.d.ts","sourceRoot":"","sources":["../../../../src/src/platform/compat/opaque-deps.ts"],"names":[],"mappings":"AA2BA,KAAK,YAAY,GAAG,GAAG,CAAC;AAExB,yEAAyE;AACzE,wBAAgB,kBAAkB,IAAI,OAAO,CAAC,YAAY,CAAC,CAE1D;AAED,8DAA8D;AAC9D,wBAAgB,oBAAoB,IAAI,OAAO,CAAC,YAAY,CAAC,CAK5D;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAC/C,YAAY,EAAE,CACZ,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnC,CAAC,CAWD"}
1
+ {"version":3,"file":"opaque-deps.d.ts","sourceRoot":"","sources":["../../../../src/src/platform/compat/opaque-deps.ts"],"names":[],"mappings":"AA2BA,KAAK,YAAY,GAAG,GAAG,CAAC;AAUxB,yEAAyE;AACzE,wBAAgB,kBAAkB,IAAI,OAAO,CAAC,YAAY,CAAC,CAE1D;AAED,8DAA8D;AAC9D,wBAAgB,oBAAoB,IAAI,OAAO,CAAC,YAAY,CAAC,CAK5D;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAC/C,YAAY,EAAE,CACZ,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnC,CAAC,CAkBD"}
@@ -15,7 +15,7 @@
15
15
  * @module platform/compat
16
16
  */
17
17
  import * as dntShim from "../../../_dnt.shims.js";
18
- import { isDeno } from "./runtime.js";
18
+ import { isDeno, isDenoCompiled } from "./runtime.js";
19
19
  import { dynamicImport } from "./dynamic-import.js";
20
20
  function resolve(pkg, version) {
21
21
  return isDeno ? `npm:${pkg}@${version}` : pkg;
@@ -45,6 +45,15 @@ export async function importKreuzberg() {
45
45
  if (isDeno) {
46
46
  // Regular import — visible to deno compile, resolved via deno.json import map
47
47
  const mod = await import("@kreuzberg/wasm");
48
+ if (isDenoCompiled) {
49
+ // Kreuzberg's initWasm() internally uses a computed dynamic import() to
50
+ // load the WASM glue module (kreuzberg_wasm.js). deno compile cannot
51
+ // trace computed import() paths, so the glue module is absent from the
52
+ // binary's embedded module graph. Pre-importing it here populates Deno's
53
+ // in-process module cache so the subsequent import() inside initWasm()
54
+ // resolves from cache instead of hitting the missing file.
55
+ await import("@kreuzberg/wasm/dist/pkg/kreuzberg_wasm.js");
56
+ }
48
57
  await mod.initWasm?.();
49
58
  return mod;
50
59
  }
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/src/prompt/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAGvD,wBAAgB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA0BnD"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/src/prompt/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAIvD,wBAAgB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA0BnD"}
@@ -1,4 +1,5 @@
1
1
  import { createError, toError } from "../errors/veryfront-error.js";
2
+ import { COMMON_BLOCKED_PATTERNS } from "../agent/middleware/security/validator.js";
2
3
  export function prompt(config) {
3
4
  const id = config.id ?? generatePromptId();
4
5
  return {
@@ -24,9 +25,16 @@ let promptIdCounter = 0;
24
25
  function generatePromptId() {
25
26
  return `prompt_${Date.now()}_${promptIdCounter++}`;
26
27
  }
28
+ function sanitizeVariableValue(value) {
29
+ let sanitized = value;
30
+ for (const pattern of COMMON_BLOCKED_PATTERNS.promptInjection) {
31
+ sanitized = sanitized.replace(pattern, "");
32
+ }
33
+ return sanitized;
34
+ }
27
35
  function interpolateVariables(template, variables) {
28
36
  return template.replace(/\{(\w+)\}/g, (match, key) => {
29
37
  const value = variables[key];
30
- return value != null ? String(value) : match;
38
+ return value != null ? sanitizeVariableValue(String(value)) : match;
31
39
  });
32
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../../../../src/src/react/components/ai/markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iCAAiC;IACjC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,KAAK,CAAC,SAAS,CAAC;CAC9D;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAkJD,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,SAAS,EACT,aAAoB,EACpB,eAAe,GAChB,EAAE,aAAa,GAAG,KAAK,CAAC,YAAY,CA+FpC"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../../../../src/src/react/components/ai/markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iCAAiC;IACjC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,KAAK,CAAC,SAAS,CAAC;CAC9D;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAmJD,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,SAAS,EACT,aAAoB,EACpB,eAAe,GAChB,EAAE,aAAa,GAAG,KAAK,CAAC,YAAY,CA+FpC"}
@@ -3,10 +3,10 @@ import { cn } from "./theme.js";
3
3
  import { isBrowserEnvironment } from "../../../platform/compat/runtime.js";
4
4
  import { validateTrustedHtml } from "../../../security/client/html-sanitizer.js";
5
5
  import { RichCodeBlock } from "./chat/components/code-block.js";
6
- const ESM_REACT_MARKDOWN = "https://esm.sh/react-markdown@9?external=react&target=es2022";
7
- const ESM_REMARK_GFM = "https://esm.sh/remark-gfm@4?target=es2022";
8
- const ESM_REHYPE_HIGHLIGHT = "https://esm.sh/rehype-highlight@7?target=es2022";
9
- const ESM_MERMAID = "https://esm.sh/mermaid@11";
6
+ const ESM_REACT_MARKDOWN = "https://esm.sh/react-markdown@9.0.3?external=react&target=es2022&pin=v135";
7
+ const ESM_REMARK_GFM = "https://esm.sh/remark-gfm@4.0.1?target=es2022&pin=v135";
8
+ const ESM_REHYPE_HIGHLIGHT = "https://esm.sh/rehype-highlight@7.0.2?target=es2022&pin=v135";
9
+ const ESM_MERMAID = "https://esm.sh/mermaid@11.4.1?pin=v135";
10
10
  const dynamicImport = new Function("url", "return import(url)");
11
11
  // deno-lint-ignore no-explicit-any
12
12
  let ReactMarkdown = null;