@valbuild/server 0.94.0 → 0.95.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.
@@ -48,7 +48,7 @@ export declare const ENABLE_COOKIE_VALUE: {
48
48
  readonly sameSite: "lax";
49
49
  };
50
50
  };
51
- export declare function bufferToReadableStream(buffer: Buffer): import("node:stream/web").ReadableStream<any>;
51
+ export declare function bufferToReadableStream(buffer: Buffer): ReadableStream<any>;
52
52
  export declare function getRedirectUrl(query: {
53
53
  redirect_to?: string | undefined;
54
54
  }, overrideHost: string | undefined): string | {
@@ -2405,8 +2405,8 @@ class ValOps {
2405
2405
  }
2406
2406
 
2407
2407
  // #region createPatch
2408
- async createPatch(path, patch, patchId, parentRef, authorId) {
2409
- const saveRes = await this.saveSourceFilePatch(path, patch, patchId, parentRef, authorId);
2408
+ async createPatch(path, patch, patchId, parentRef, sessionId, authorId) {
2409
+ const saveRes = await this.saveSourceFilePatch(path, patch, patchId, parentRef, authorId, sessionId);
2410
2410
  if (fp.result.isErr(saveRes)) {
2411
2411
  console.error(`Could not save source patch at path: '${path}'. Error: ${saveRes.error.errorType === "other" ? saveRes.error.message : saveRes.error.errorType}`);
2412
2412
  if (saveRes.error.errorType === "patch-head-conflict") {
@@ -2798,11 +2798,17 @@ class ValOpsFS extends ValOps {
2798
2798
  parentPatchId: dir
2799
2799
  });
2800
2800
  } else {
2801
- if (includes && includes.length > 0 && !includes.includes(parsedPatch.data.patchId)) {
2801
+ const patchId = parsedPatch.data.patchId;
2802
+ if (includes && includes.length > 0 && !includes.includes(patchId)) {
2802
2803
  return;
2803
2804
  }
2804
- patches[parsedPatch.data.patchId] = {
2805
- ...parsedPatch.data,
2805
+ patches[patchId] = {
2806
+ path: parsedPatch.data.path,
2807
+ patch: parsedPatch.data.patch,
2808
+ parentRef: parsedPatch.data.parentRef,
2809
+ baseSha: parsedPatch.data.baseSha,
2810
+ createdAt: parsedPatch.data.createdAt,
2811
+ authorId: parsedPatch.data.authorId,
2806
2812
  appliedAt: null
2807
2813
  };
2808
2814
  }
@@ -2973,7 +2979,7 @@ class ValOpsFS extends ValOps {
2973
2979
  };
2974
2980
  }
2975
2981
  }
2976
- async saveSourceFilePatch(path, patch, patchId, parentRef, authorId) {
2982
+ async saveSourceFilePatch(path, patch, patchId, parentRef, authorId, sessionId) {
2977
2983
  const patchDir = this.getParentPatchIdFromParentRef(parentRef);
2978
2984
  try {
2979
2985
  const baseSha = await this.getBaseSha();
@@ -2983,6 +2989,7 @@ class ValOpsFS extends ValOps {
2983
2989
  parentRef,
2984
2990
  path,
2985
2991
  authorId,
2992
+ sessionId,
2986
2993
  baseSha,
2987
2994
  coreVersion: core.Internal.VERSION.core,
2988
2995
  createdAt: new Date().toISOString()
@@ -3421,12 +3428,6 @@ class ValOpsFS extends ValOps {
3421
3428
  return fp.result.ok(Object.fromEntries(Object.entries(patches.patches).map(([patchId, value]) => [patchId, this.getParentPatchIdFromParentRef(value.parentRef)])));
3422
3429
  }
3423
3430
 
3424
- // #region profiles
3425
- async getProfiles() {
3426
- // We do not have profiles in FS mode
3427
- return [];
3428
- }
3429
-
3430
3431
  // #region fs file path helpers
3431
3432
  getPatchesDir() {
3432
3433
  return path__namespace["default"].join(this.rootDir, ValOpsFS.VAL_DIR, "patches");
@@ -3535,7 +3536,9 @@ const FSPatch = zod.z.object({
3535
3536
  parentRef: internal.ParentRef,
3536
3537
  authorId: zod.z.string().refine(p => true).nullable(),
3537
3538
  createdAt: zod.z.string().datetime(),
3538
- coreVersion: zod.z.string().nullable() // TODO: use this to check if patch is compatible with current core version?
3539
+ coreVersion: zod.z.string().nullable(),
3540
+ // TODO: use this to check if patch is compatible with current core version?
3541
+ sessionId: zod.z.string().nullable()
3539
3542
  });
3540
3543
  const FSPatchBase = zod.z.object({
3541
3544
  baseSha: zod.z.string().refine(p => true),
@@ -3637,17 +3640,6 @@ const CommitResponse = zod.z.object({
3637
3640
  commit: CommitSha,
3638
3641
  branch: zod.z.string()
3639
3642
  });
3640
- const ProfilesResponse = zod.z.object({
3641
- profiles: zod.z.array(zod.z.object({
3642
- profileId: zod.z.string(),
3643
- fullName: zod.z.string(),
3644
- email: zod.z.string().optional(),
3645
- // TODO: make this required once this can be guaranteed
3646
- avatar: zod.z.object({
3647
- url: zod.z.string()
3648
- }).nullable()
3649
- }))
3650
- });
3651
3643
  const NonceResponse = zod.z.object({
3652
3644
  nonce: zod.z.string(),
3653
3645
  url: zod.z.string()
@@ -4098,7 +4090,7 @@ class ValOpsHttp extends ValOps {
4098
4090
  };
4099
4091
  }
4100
4092
  }
4101
- async saveSourceFilePatch(path, patch, patchId, parentRef, authorId) {
4093
+ async saveSourceFilePatch(path, patch, patchId, parentRef, authorId, sessionId) {
4102
4094
  const baseSha = await this.getBaseSha();
4103
4095
  return fetch(`${this.contentUrl}/v1/${this.project}/patches`, {
4104
4096
  method: "POST",
@@ -4110,6 +4102,7 @@ class ValOpsHttp extends ValOps {
4110
4102
  path,
4111
4103
  patch,
4112
4104
  authorId,
4105
+ sessionId,
4113
4106
  patchId,
4114
4107
  parentPatchId: parentRef.type === "patch" ? parentRef.patchId : null,
4115
4108
  baseSha,
@@ -4533,31 +4526,6 @@ class ValOpsHttp extends ValOps {
4533
4526
  };
4534
4527
  }
4535
4528
  }
4536
-
4537
- // #region profiles
4538
- async getProfiles() {
4539
- var _res$headers$get6;
4540
- const res = await fetch(`${this.contentUrl}/v1/${this.project}/profiles`, {
4541
- headers: {
4542
- ...this.authHeaders,
4543
- "Content-Type": "application/json"
4544
- }
4545
- });
4546
- if (res.ok) {
4547
- const parsed = ProfilesResponse.safeParse(await res.json());
4548
- if (parsed.error) {
4549
- console.error("Could not parse profiles response", parsed.error);
4550
- throw Error(`Could not get profiles from remote server: wrong format. You might need to upgrade Val.`);
4551
- }
4552
- return parsed.data.profiles;
4553
- }
4554
- if ((_res$headers$get6 = res.headers.get("Content-Type")) !== null && _res$headers$get6 !== void 0 && _res$headers$get6.includes("application/json")) {
4555
- const json = await res.json();
4556
- const message = internal.getErrorMessageFromUnknownJson(json, "Unknown error");
4557
- throw Error(`Could not get profiles (status: ${res.status}): ${message}`);
4558
- }
4559
- throw Error(`Could not get profiles. Got status: ${res.status}`);
4560
- }
4561
4529
  }
4562
4530
 
4563
4531
  const host = process.env.VAL_CONTENT_URL || core.DEFAULT_CONTENT_HOST;
@@ -4710,6 +4678,16 @@ function hasRemoteFileSchema(schema) {
4710
4678
 
4711
4679
  /* eslint-disable @typescript-eslint/no-unused-vars */
4712
4680
  const ValServer = (valModules, options, callbacks) => {
4681
+ const ProfilesResponse = zod.z.object({
4682
+ profiles: zod.z.array(zod.z.object({
4683
+ profileId: zod.z.string(),
4684
+ fullName: zod.z.string(),
4685
+ email: zod.z.string().optional(),
4686
+ avatar: zod.z.object({
4687
+ url: zod.z.string()
4688
+ }).nullable()
4689
+ }))
4690
+ });
4713
4691
  let serverOps;
4714
4692
  if (options.mode === "fs") {
4715
4693
  serverOps = new ValOpsFS(options.valContentUrl, options.cwd, valModules, {
@@ -5559,10 +5537,11 @@ const ValServer = (valModules, options, callbacks) => {
5559
5537
  }
5560
5538
  const patches = req.body.patches;
5561
5539
  let parentRef = req.body.parentRef;
5540
+ const sessionId = req.body.sessionId ?? null;
5562
5541
  const authorId = "id" in auth ? auth.id : null;
5563
5542
  const newPatchIds = [];
5564
5543
  for (const patch of patches) {
5565
- const createPatchRes = await serverOps.createPatch(patch.path, patch.patch, patch.patchId, parentRef, authorId);
5544
+ const createPatchRes = await serverOps.createPatch(patch.path, patch.patch, patch.patchId, parentRef, sessionId, authorId);
5566
5545
  if (fp.result.isErr(createPatchRes)) {
5567
5546
  if (createPatchRes.error.errorType === "patch-head-conflict") {
5568
5547
  return {
@@ -5923,13 +5902,87 @@ const ValServer = (valModules, options, callbacks) => {
5923
5902
  }
5924
5903
  };
5925
5904
  }
5926
- const profiles = await serverOps.getProfiles();
5927
- return {
5928
- status: 200,
5929
- json: {
5930
- profiles
5905
+ if (!options.project) {
5906
+ return {
5907
+ status: 500,
5908
+ json: {
5909
+ message: "Project is not configured"
5910
+ }
5911
+ };
5912
+ }
5913
+ const authDataRes = await getRemoteFileAuth();
5914
+ if (authDataRes.status !== 200) {
5915
+ if (serverOps instanceof ValOpsFS && authDataRes.json.errorCode === "pat-error") {
5916
+ return {
5917
+ status: 200,
5918
+ json: {
5919
+ profiles: []
5920
+ }
5921
+ };
5922
+ }
5923
+ return {
5924
+ status: 500,
5925
+ json: {
5926
+ message: authDataRes.json.message
5927
+ }
5928
+ };
5929
+ }
5930
+ const authData = authDataRes.json.remoteFileAuth;
5931
+ const execFetch = async headers => {
5932
+ try {
5933
+ const upstreamUrl = `${options.valContentUrl}/v1/${options.project}/profiles`;
5934
+ const upstreamRes = await fetch(upstreamUrl, {
5935
+ method: "GET",
5936
+ headers
5937
+ });
5938
+ if (!upstreamRes.ok) {
5939
+ const text = await upstreamRes.text();
5940
+ const isAuthError = upstreamRes.status === 401 || upstreamRes.status === 403;
5941
+ return {
5942
+ status: isAuthError ? 401 : 500,
5943
+ json: {
5944
+ message: isAuthError ? `Profile authentication failed: ${upstreamRes.status} ${text}` : `Profiles failed: ${upstreamRes.status} ${text}`
5945
+ }
5946
+ };
5947
+ }
5948
+ const parseRes = ProfilesResponse.safeParse(await upstreamRes.json());
5949
+ if (!parseRes.success) {
5950
+ return {
5951
+ status: 500,
5952
+ json: {
5953
+ message: "Could not parse profiles response: " + zodValidationError.fromError(parseRes.error).toString()
5954
+ }
5955
+ };
5956
+ }
5957
+ return {
5958
+ status: 200,
5959
+ json: {
5960
+ profiles: parseRes.data.profiles
5961
+ }
5962
+ };
5963
+ } catch (err) {
5964
+ return {
5965
+ status: 500,
5966
+ json: {
5967
+ message: err instanceof Error ? err.message : "Profiles request failed"
5968
+ }
5969
+ };
5931
5970
  }
5932
5971
  };
5972
+ if (serverOps instanceof ValOpsFS) {
5973
+ return execFetch(getProfileAuthHeaders(authData, null, "application/json"));
5974
+ }
5975
+ if (!options.valSecret) {
5976
+ return {
5977
+ status: 500,
5978
+ json: {
5979
+ message: "Secret is not configured"
5980
+ }
5981
+ };
5982
+ }
5983
+ return withAuth(options.valSecret, cookies, "profiles", data => {
5984
+ return execFetch(getProfileAuthHeaders(authData, data, "application/json"));
5985
+ });
5933
5986
  }
5934
5987
  },
5935
5988
  "/commit-summary": {
@@ -6111,6 +6164,381 @@ const ValServer = (valModules, options, callbacks) => {
6111
6164
  }
6112
6165
  }
6113
6166
  },
6167
+ //#region ai proxy
6168
+ "/ai/initialize": {
6169
+ POST: async req => {
6170
+ const cookies = req.cookies;
6171
+ const auth = getAuth(cookies);
6172
+ if (auth.error) {
6173
+ return {
6174
+ status: 401,
6175
+ json: {
6176
+ message: auth.error
6177
+ }
6178
+ };
6179
+ }
6180
+ if (!options.project) {
6181
+ return {
6182
+ status: 500,
6183
+ json: {
6184
+ message: "Project is not configured"
6185
+ }
6186
+ };
6187
+ }
6188
+ const authDataRes = await getRemoteFileAuth();
6189
+ if (authDataRes.status !== 200) {
6190
+ return {
6191
+ status: 500,
6192
+ json: {
6193
+ message: authDataRes.json.message
6194
+ }
6195
+ };
6196
+ }
6197
+ const authData = authDataRes.json.remoteFileAuth;
6198
+ const execFetch = async headers => {
6199
+ try {
6200
+ const upstreamUrl = `${options.valContentUrl}/v1/${options.project}/ai/initialize`;
6201
+ const upstreamRes = await fetch(upstreamUrl, {
6202
+ method: "POST",
6203
+ headers,
6204
+ body: JSON.stringify({})
6205
+ });
6206
+ if (!upstreamRes.ok) {
6207
+ const text = await upstreamRes.text();
6208
+ return {
6209
+ status: 500,
6210
+ json: {
6211
+ message: `AI initialize failed: ${upstreamRes.status} ${text}`
6212
+ }
6213
+ };
6214
+ }
6215
+ const json = await upstreamRes.json();
6216
+ const wsUrl = options.valContentUrl.replace(/^https:/, "wss:").replace(/^http:/, "ws:") + `/v1/${options.project}/ai/connect`;
6217
+ return {
6218
+ status: 200,
6219
+ json: {
6220
+ nonce: json.nonce,
6221
+ wsUrl
6222
+ }
6223
+ };
6224
+ } catch (err) {
6225
+ return {
6226
+ status: 500,
6227
+ json: {
6228
+ message: err instanceof Error ? err.message : "AI initialize error"
6229
+ }
6230
+ };
6231
+ }
6232
+ };
6233
+ if (serverOps instanceof ValOpsFS) {
6234
+ return execFetch(getProfileAuthHeaders(authData, null, "application/json"));
6235
+ }
6236
+ if (!options.valSecret) {
6237
+ return {
6238
+ status: 500,
6239
+ json: {
6240
+ message: "Secret is not configured"
6241
+ }
6242
+ };
6243
+ }
6244
+ return withAuth(options.valSecret, cookies, "ai/initialize", data => {
6245
+ return execFetch(getProfileAuthHeaders(authData, data, "application/json"));
6246
+ });
6247
+ }
6248
+ },
6249
+ "/ai/sessions": {
6250
+ GET: async req => {
6251
+ const cookies = req.cookies;
6252
+ const auth = getAuth(cookies);
6253
+ if (auth.error) {
6254
+ return {
6255
+ status: 401,
6256
+ json: {
6257
+ message: auth.error
6258
+ }
6259
+ };
6260
+ }
6261
+ if (!options.project) {
6262
+ return {
6263
+ status: 500,
6264
+ json: {
6265
+ message: "Project is not configured"
6266
+ }
6267
+ };
6268
+ }
6269
+ const authDataRes = await getRemoteFileAuth();
6270
+ if (authDataRes.status !== 200) {
6271
+ return {
6272
+ status: 500,
6273
+ json: {
6274
+ message: authDataRes.json.message
6275
+ }
6276
+ };
6277
+ }
6278
+ const authData = authDataRes.json.remoteFileAuth;
6279
+ const execFetch = async headers => {
6280
+ try {
6281
+ const SessionsResponse = zod.z.object({
6282
+ sessions: zod.z.array(zod.z.object({
6283
+ id: zod.z.string(),
6284
+ name: zod.z.string().nullable(),
6285
+ createdAt: zod.z.string(),
6286
+ updatedAt: zod.z.string()
6287
+ })),
6288
+ nextCursor: zod.z.object({
6289
+ updatedAt: zod.z.string(),
6290
+ id: zod.z.string()
6291
+ }).nullable().optional()
6292
+ });
6293
+ const params = new URLSearchParams();
6294
+ if (req.query.limit) params.set("limit", req.query.limit);
6295
+ if (req.query.cursor_updatedAt) {
6296
+ params.set("cursor_updatedAt", req.query.cursor_updatedAt);
6297
+ }
6298
+ if (req.query.cursor_id) {
6299
+ params.set("cursor_id", req.query.cursor_id);
6300
+ }
6301
+ const qs = params.toString();
6302
+ const upstreamUrl = `${options.valContentUrl}/v1/${options.project}/ai/sessions${qs ? `?${qs}` : ""}`;
6303
+ const upstreamRes = await fetch(upstreamUrl, {
6304
+ headers
6305
+ });
6306
+ if (!upstreamRes.ok) {
6307
+ const text = await upstreamRes.text();
6308
+ return {
6309
+ status: 500,
6310
+ json: {
6311
+ message: `AI sessions failed: ${upstreamRes.status} ${text}`
6312
+ }
6313
+ };
6314
+ }
6315
+ const json = SessionsResponse.safeParse(await upstreamRes.json());
6316
+ if (!json.success) {
6317
+ return {
6318
+ status: 500,
6319
+ json: {
6320
+ message: "Could not parse AI sessions response: " + zodValidationError.fromError(json.error).toString()
6321
+ }
6322
+ };
6323
+ }
6324
+ return {
6325
+ status: 200,
6326
+ json: json.data
6327
+ };
6328
+ } catch (err) {
6329
+ return {
6330
+ status: 500,
6331
+ json: {
6332
+ message: err instanceof Error ? err.message : "AI sessions error"
6333
+ }
6334
+ };
6335
+ }
6336
+ };
6337
+ if (serverOps instanceof ValOpsFS) {
6338
+ return execFetch(getProfileAuthHeaders(authData, null, "application/json"));
6339
+ }
6340
+ if (!options.valSecret) {
6341
+ return {
6342
+ status: 500,
6343
+ json: {
6344
+ message: "Secret is not configured"
6345
+ }
6346
+ };
6347
+ }
6348
+ return withAuth(options.valSecret, cookies, "ai/sessions", data => {
6349
+ return execFetch(getProfileAuthHeaders(authData, data, "application/json"));
6350
+ });
6351
+ },
6352
+ PATCH: async req => {
6353
+ const cookies = req.cookies;
6354
+ const auth = getAuth(cookies);
6355
+ if (auth.error) {
6356
+ return {
6357
+ status: 401,
6358
+ json: {
6359
+ message: auth.error
6360
+ }
6361
+ };
6362
+ }
6363
+ if (!options.project) {
6364
+ return {
6365
+ status: 500,
6366
+ json: {
6367
+ message: "Project is not configured"
6368
+ }
6369
+ };
6370
+ }
6371
+ const pathParts = (req.path || "").split("/").filter(Boolean);
6372
+ const sessionId = pathParts[0];
6373
+ if (!sessionId) {
6374
+ return {
6375
+ status: 500,
6376
+ json: {
6377
+ message: "Missing sessionId in path"
6378
+ }
6379
+ };
6380
+ }
6381
+ const authDataRes = await getRemoteFileAuth();
6382
+ if (authDataRes.status !== 200) {
6383
+ return {
6384
+ status: 500,
6385
+ json: {
6386
+ message: authDataRes.json.message
6387
+ }
6388
+ };
6389
+ }
6390
+ const authData = authDataRes.json.remoteFileAuth;
6391
+ const execFetch = async headers => {
6392
+ try {
6393
+ const upstreamUrl = `${options.valContentUrl}/v1/${options.project}/ai/sessions/${encodeURIComponent(sessionId)}`;
6394
+ const upstreamRes = await fetch(upstreamUrl, {
6395
+ method: "PATCH",
6396
+ headers,
6397
+ body: JSON.stringify({
6398
+ name: req.body.name
6399
+ })
6400
+ });
6401
+ if (!upstreamRes.ok) {
6402
+ const text = await upstreamRes.text();
6403
+ return {
6404
+ status: 500,
6405
+ json: {
6406
+ message: `AI session rename failed: ${upstreamRes.status} ${text}`
6407
+ }
6408
+ };
6409
+ }
6410
+ return {
6411
+ status: 200,
6412
+ json: {}
6413
+ };
6414
+ } catch (err) {
6415
+ return {
6416
+ status: 500,
6417
+ json: {
6418
+ message: err instanceof Error ? err.message : "AI session rename error"
6419
+ }
6420
+ };
6421
+ }
6422
+ };
6423
+ if (serverOps instanceof ValOpsFS) {
6424
+ return execFetch(getProfileAuthHeaders(authData, null, "application/json"));
6425
+ }
6426
+ if (!options.valSecret) {
6427
+ return {
6428
+ status: 500,
6429
+ json: {
6430
+ message: "Secret is not configured"
6431
+ }
6432
+ };
6433
+ }
6434
+ return withAuth(options.valSecret, cookies, "ai/sessions/rename", data => {
6435
+ return execFetch(getProfileAuthHeaders(authData, data, "application/json"));
6436
+ });
6437
+ }
6438
+ },
6439
+ "/ai/messages": {
6440
+ GET: async req => {
6441
+ const cookies = req.cookies;
6442
+ const auth = getAuth(cookies);
6443
+ if (auth.error) {
6444
+ return {
6445
+ status: 401,
6446
+ json: {
6447
+ message: auth.error
6448
+ }
6449
+ };
6450
+ }
6451
+ if (!options.project) {
6452
+ return {
6453
+ status: 500,
6454
+ json: {
6455
+ message: "Project is not configured"
6456
+ }
6457
+ };
6458
+ }
6459
+ const pathParts = (req.path || "").split("/").filter(Boolean);
6460
+ const sessionId = pathParts[0];
6461
+ if (!sessionId) {
6462
+ return {
6463
+ status: 500,
6464
+ json: {
6465
+ message: "Missing sessionId in path"
6466
+ }
6467
+ };
6468
+ }
6469
+ const authDataRes = await getRemoteFileAuth();
6470
+ if (authDataRes.status !== 200) {
6471
+ return {
6472
+ status: 500,
6473
+ json: {
6474
+ message: authDataRes.json.message
6475
+ }
6476
+ };
6477
+ }
6478
+ const authData = authDataRes.json.remoteFileAuth;
6479
+ const execFetch = async headers => {
6480
+ try {
6481
+ const SessionMessagesResponse = zod.z.object({
6482
+ messages: zod.z.array(zod.z.object({
6483
+ role: zod.z.string(),
6484
+ content: zod.z.string()
6485
+ })),
6486
+ nextCursor: zod.z.object({
6487
+ updatedAt: zod.z.string(),
6488
+ id: zod.z.string()
6489
+ }).nullable().optional()
6490
+ });
6491
+ const upstreamUrl = `${options.valContentUrl}/v1/${options.project}/ai/sessions/${encodeURIComponent(sessionId)}/messages`;
6492
+ const upstreamRes = await fetch(upstreamUrl, {
6493
+ headers
6494
+ });
6495
+ if (!upstreamRes.ok) {
6496
+ const text = await upstreamRes.text();
6497
+ return {
6498
+ status: 500,
6499
+ json: {
6500
+ message: `AI session messages failed: ${upstreamRes.status} ${text}`
6501
+ }
6502
+ };
6503
+ }
6504
+ const json = SessionMessagesResponse.safeParse(await upstreamRes.json());
6505
+ if (!json.success) {
6506
+ return {
6507
+ status: 500,
6508
+ json: {
6509
+ message: "Could not parse AI session messages response: " + zodValidationError.fromError(json.error).toString()
6510
+ }
6511
+ };
6512
+ }
6513
+ return {
6514
+ status: 200,
6515
+ json: json.data
6516
+ };
6517
+ } catch (err) {
6518
+ return {
6519
+ status: 500,
6520
+ json: {
6521
+ message: err instanceof Error ? err.message : "AI session messages error"
6522
+ }
6523
+ };
6524
+ }
6525
+ };
6526
+ if (serverOps instanceof ValOpsFS) {
6527
+ return execFetch(getProfileAuthHeaders(authData, null, "application/json"));
6528
+ }
6529
+ if (!options.valSecret) {
6530
+ return {
6531
+ status: 500,
6532
+ json: {
6533
+ message: "Secret is not configured"
6534
+ }
6535
+ };
6536
+ }
6537
+ return withAuth(options.valSecret, cookies, "ai/sessions/messages", data => {
6538
+ return execFetch(getProfileAuthHeaders(authData, data, "application/json"));
6539
+ });
6540
+ }
6541
+ },
6114
6542
  //#region files
6115
6543
  "/files": {
6116
6544
  GET: async req => {
@@ -6332,6 +6760,21 @@ async function withAuth(secret, cookies, errorMessageType, handler) {
6332
6760
  };
6333
6761
  }
6334
6762
  }
6763
+ function getProfileAuthHeaders(auth, data, type) {
6764
+ if ("pat" in auth) {
6765
+ return {
6766
+ "x-val-pat": auth.pat,
6767
+ "Content-Type": type
6768
+ };
6769
+ }
6770
+ if ("apiKey" in auth && data) {
6771
+ return {
6772
+ ...getAuthHeaders(auth.apiKey, type),
6773
+ "x-val-profile-id": data.sub
6774
+ };
6775
+ }
6776
+ throw new Error("Invalid auth");
6777
+ }
6335
6778
  function getAuthHeaders(token, type) {
6336
6779
  if (!type) {
6337
6780
  return {