oh-langfuse 0.1.75 → 0.1.77

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.
@@ -258,7 +258,7 @@ function basicAuth(publicKey, secretKey) {
258
258
  return `Basic ${Buffer.from(`${publicKey}:${secretKey}`, "utf8").toString("base64")}`;
259
259
  }
260
260
 
261
- async function langfuseGet(config, pathname, params = {}) {
261
+ async function langfuseGet(config, pathname, params = {}) {
262
262
  const url = new URL(`${apiBase(config.baseUrl)}${pathname}`);
263
263
  for (const [key, value] of Object.entries(params)) {
264
264
  if (value !== undefined && value !== null && String(value) !== "") url.searchParams.set(key, String(value));
@@ -278,17 +278,22 @@ async function langfuseGet(config, pathname, params = {}) {
278
278
  error.status = response.status;
279
279
  throw error;
280
280
  }
281
- return await response.json();
282
- }
283
-
284
- async function langfuseGetLenient(config, pathname, params = {}) {
285
- try {
286
- return await langfuseGet(config, pathname, params);
287
- } catch (error) {
288
- if (error.status !== 400) throw error;
289
- const fallback = {};
290
- for (const key of ["limit", "page", "userId", "fields"]) {
291
- if (params[key] !== undefined) fallback[key] = params[key];
281
+ return await response.json();
282
+ }
283
+
284
+ function isLangfuseQueryShapeError(error) {
285
+ if (!error) return false;
286
+ return error.status === 400 || error.status === 422;
287
+ }
288
+
289
+ async function langfuseGetLenient(config, pathname, params = {}) {
290
+ try {
291
+ return await langfuseGet(config, pathname, params);
292
+ } catch (error) {
293
+ if (!isLangfuseQueryShapeError(error)) throw error;
294
+ const fallback = {};
295
+ for (const key of ["limit", "page", "userId", "fields"]) {
296
+ if (params[key] !== undefined) fallback[key] = params[key];
292
297
  }
293
298
  return await langfuseGet(config, pathname, fallback);
294
299
  }
@@ -407,18 +412,18 @@ function expectedAgentTurnName(target) {
407
412
  async function observationsForTrace(config, traceId, since) {
408
413
  if (!traceId) return [];
409
414
  const params = { limit: 100, fields: "core,basic,usage", traceId };
410
- try {
411
- return dataArray(await langfuseGet(config, "/v2/observations", params));
412
- } catch (error) {
413
- if (error.status !== 400 && error.status !== 404) throw error;
414
- }
415
- try {
416
- return dataArray(await langfuseGet(config, "/observations", { limit: 100, traceId }));
417
- } catch (error) {
418
- if (error.status !== 400) throw error;
419
- }
420
- const fallback = dataArray(await langfuseGetLenient(config, "/observations", { limit: 100, fromTimestamp: since.toISOString() }));
421
- return fallback.filter((item) => item.traceId === traceId || item.trace_id === traceId);
415
+ try {
416
+ return dataArray(await langfuseGet(config, "/v2/observations", params));
417
+ } catch (error) {
418
+ if (!isLangfuseQueryShapeError(error) && error.status !== 404) throw error;
419
+ }
420
+ try {
421
+ return dataArray(await langfuseGet(config, "/observations", { limit: 100, traceId }));
422
+ } catch (error) {
423
+ if (!isLangfuseQueryShapeError(error)) throw error;
424
+ }
425
+ const fallback = dataArray(await langfuseGetLenient(config, "/observations", { limit: 100, fromTimestamp: since.toISOString() }));
426
+ return fallback.filter((item) => item.traceId === traceId || item.trace_id === traceId);
422
427
  }
423
428
 
424
429
  function mergeMetricCandidates(items) {
@@ -439,12 +444,12 @@ async function recentMetricCandidates(config, since) {
439
444
  const candidates = [];
440
445
  for (const pathname of ["/traces"]) {
441
446
  for (const params of [{ ...baseParams, userId: config.userId }, baseParams]) {
442
- try {
443
- candidates.push(...dataArray(await langfuseGetLenient(config, pathname, params)));
444
- } catch (error) {
445
- if (error.name === "AbortError" || error.status === 404) continue;
446
- throw error;
447
- }
447
+ try {
448
+ candidates.push(...dataArray(await langfuseGetLenient(config, pathname, params)));
449
+ } catch (error) {
450
+ if (error.name === "AbortError" || error.status === 404 || isLangfuseQueryShapeError(error)) continue;
451
+ throw error;
452
+ }
448
453
  }
449
454
  }
450
455
  return mergeMetricCandidates(candidates);
@@ -564,12 +569,12 @@ async function findLangfuseMarker(config, marker, { since, target }) {
564
569
 
565
570
  for (const params of traceQueries) {
566
571
  let traces;
567
- try {
568
- traces = await langfuseGetLenient(config, "/traces", params);
569
- } catch (error) {
570
- if (error.status === 404) continue;
571
- throw error;
572
- }
572
+ try {
573
+ traces = await langfuseGetLenient(config, "/traces", params);
574
+ } catch (error) {
575
+ if (error.status === 404 || isLangfuseQueryShapeError(error)) continue;
576
+ throw error;
577
+ }
573
578
  for (const trace of dataArray(traces)) {
574
579
  if (containsMarker(trace, marker)) return { kind: "trace-list", target, id: idOf(trace), item: trace };
575
580
  }
@@ -597,10 +602,10 @@ async function findLangfuseMarker(config, marker, { since, target }) {
597
602
  for (const observation of dataArray(observations)) {
598
603
  if (containsMarker(observation, marker)) return { kind: pathname, target, id: idOf(observation), item: observation };
599
604
  }
600
- } catch (error) {
601
- if (error.status === 404 || error.status === 400) continue;
602
- throw error;
603
- }
605
+ } catch (error) {
606
+ if (error.status === 404 || isLangfuseQueryShapeError(error)) continue;
607
+ throw error;
608
+ }
604
609
  }
605
610
 
606
611
  return null;
@@ -29,23 +29,27 @@ export function resolveOpencodeCli(preferred) {
29
29
  const home = os.homedir();
30
30
 
31
31
  /** @type {string[]} */
32
- const candidates = [];
33
- if (process.platform === "win32") {
34
- candidates.push(path.join(home, ".opencode", "bin", "opencode.exe"));
35
- candidates.push(path.join(home, ".opencode", "bin", "opencode.cmd"));
36
- candidates.push(path.join(home, "bin", "opencode.exe"));
37
- if (process.env.LOCALAPPDATA) {
38
- candidates.push(path.join(process.env.LOCALAPPDATA, "Programs", "opencode", "opencode.exe"));
39
- }
32
+ const candidates = [];
33
+ if (process.platform === "win32") {
34
+ candidates.push(path.join(home, ".opencode", "bin", "opencode.exe"));
40
35
  if (process.env.APPDATA) {
41
- candidates.push(path.join(process.env.APPDATA, "npm", "opencode.cmd"));
42
- candidates.push(path.join(process.env.APPDATA, "npm", "opencode"));
43
36
  candidates.push(path.join(process.env.APPDATA, "npm", "node_modules", "opencode-ai", "node_modules", "opencode-windows-x64", "bin", "opencode.exe"));
44
37
  candidates.push(path.join(process.env.APPDATA, "npm", "node_modules", "opencode-ai", "node_modules", "opencode-windows-x64-baseline", "bin", "opencode.exe"));
45
38
  candidates.push(path.join(process.env.APPDATA, "npm", "node_modules", "opencode-windows-x64", "bin", "opencode.exe"));
46
39
  candidates.push(path.join(process.env.APPDATA, "npm", "node_modules", "opencode-windows-x64-baseline", "bin", "opencode.exe"));
47
40
  }
48
- candidates.push(path.join(home, "scoop", "shims", "opencode.exe"));
41
+ if (process.env.LOCALAPPDATA) {
42
+ candidates.push(path.join(process.env.LOCALAPPDATA, "Programs", "opencode", "opencode.exe"));
43
+ }
44
+ candidates.push(path.join(home, ".config", "opencode", "bin", "opencode.exe"));
45
+ candidates.push(path.join(home, ".config", "opencode", "bin", "opencode.cmd"));
46
+ candidates.push(path.join(home, ".opencode", "bin", "opencode.cmd"));
47
+ candidates.push(path.join(home, "bin", "opencode.exe"));
48
+ if (process.env.APPDATA) {
49
+ candidates.push(path.join(process.env.APPDATA, "npm", "opencode.cmd"));
50
+ candidates.push(path.join(process.env.APPDATA, "npm", "opencode"));
51
+ }
52
+ candidates.push(path.join(home, "scoop", "shims", "opencode.exe"));
49
53
  } else {
50
54
  candidates.push(path.join(home, ".opencode", "bin", "opencode"));
51
55
  candidates.push(path.join(home, ".local", "bin", "opencode"));