@deslop/gateway 0.1.1260 → 0.1.1261

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.
@@ -15,9 +15,9 @@
15
15
  <link rel="manifest" href="/manifest.webmanifest" />
16
16
 
17
17
  <title>Gateway</title>
18
- <script type="module" crossorigin src="/assets/index-DXPokkvI.js"></script>
18
+ <script type="module" crossorigin src="/assets/index-DWNgL0cx.js"></script>
19
19
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-XKyaHtl9.js">
20
- <link rel="modulepreload" crossorigin href="/assets/effect-CmAQ3NBe.js">
20
+ <link rel="modulepreload" crossorigin href="/assets/effect-DmsZG62Z.js">
21
21
  <link rel="modulepreload" crossorigin href="/assets/react-BPjvcVqE.js">
22
22
  <link rel="stylesheet" crossorigin href="/assets/index-CD0fisUK.css">
23
23
  </head>
package/dist/server.js CHANGED
@@ -38285,6 +38285,36 @@ function decodeUnknownResult(schema, options) {
38285
38285
  };
38286
38286
  }
38287
38287
  /**
38288
+ * Decodes a typed input (the schema's `Encoded` type) against a schema,
38289
+ * returning a `Result` that succeeds with the decoded value or fails with a
38290
+ * {@link SchemaError} for schema mismatches.
38291
+ *
38292
+ * **When to use**
38293
+ *
38294
+ * Use when you already have input typed as the schema's `Encoded` type and want
38295
+ * schema mismatches returned as `Result.fail` with `SchemaError`.
38296
+ *
38297
+ * **Details**
38298
+ *
38299
+ * For `unknown` input use {@link decodeUnknownResult}.
38300
+ * Options may be provided either when creating the decoder or when applying it;
38301
+ * application options override creation options.
38302
+ * Schema mismatches are returned as `Result.fail` with `SchemaError`.
38303
+ *
38304
+ * **Gotchas**
38305
+ *
38306
+ * Only causes made entirely of schema issues are returned as `Result.fail`.
38307
+ * Causes that contain defects, interruptions, or other non-schema reasons throw
38308
+ * instead.
38309
+ *
38310
+ * @see {@link SchemaParser.decodeResult} for the adapter that fails with `SchemaIssue.Issue` directly
38311
+ *
38312
+ * @stability stable
38313
+ * @category decoding
38314
+ * @since 4.0.0
38315
+ */
38316
+ const decodeResult = decodeUnknownResult;
38317
+ /**
38288
38318
  * Decodes an `unknown` input against a schema synchronously, returning the
38289
38319
  * decoded value or throwing a {@link SchemaError} for schema mismatches.
38290
38320
  *
@@ -89976,6 +90006,9 @@ function layerOtlp(serviceName, url, runtime, version) {
89976
90006
  const ISSUER_PATH = "/api/auth";
89977
90007
  const APPS_PATH = "/api/apps";
89978
90008
  const SESSION_COOKIE = "__Host-session";
90009
+ function matchingSessions(saved, userId) {
90010
+ return sort(filter$5(getSomes(saved), (session) => session.value.user.id === userId), mapInput(flip$1(Number$6), (session) => session.value.expiresAt));
90011
+ }
89979
90012
  function bearerOf(headers) {
89980
90013
  return flatMapNullishOr(match$3(/^bearer +(?<token>\S+) *$/iu)(headers["authorization"] ?? ""), (found) => found.groups?.["token"]);
89981
90014
  }
@@ -91035,8 +91068,7 @@ var Sessions = class Sessions extends Service$1()("@deslop/runtime/auth/sessions
91035
91068
  key,
91036
91069
  value
91037
91070
  }))), { concurrency: "unbounded" });
91038
- const candidates = sort(filter$5(getSomes(saved), (session) => session.value.user.id === userId), mapInput(flip$1(Number$6), (session) => session.value.expiresAt));
91039
- for (const session of candidates) {
91071
+ for (const session of matchingSessions(saved, userId)) {
91040
91072
  if (yield* fresh(session.value)) return session.value.access;
91041
91073
  const renewed = yield* result$1(pipe$1(refreshed(session.key), rejected$1("AI access is temporarily unavailable")));
91042
91074
  if (renewed._tag === "Success") return renewed.success.access;
@@ -91899,7 +91931,7 @@ const Usage = Struct({
91899
91931
  }))
91900
91932
  })),
91901
91933
  model: optionalKey(String$6),
91902
- usage: optionalKey(Struct({
91934
+ usage: optionalKey(NullOr(Struct({
91903
91935
  cache_creation_input_tokens: optionalKey(Finite),
91904
91936
  cache_read_input_tokens: optionalKey(Finite),
91905
91937
  completion_tokens: optionalKey(Finite),
@@ -91911,36 +91943,37 @@ const Usage = Struct({
91911
91943
  cache_write_tokens: optionalKey(Finite),
91912
91944
  cached_tokens: optionalKey(Finite)
91913
91945
  }))
91914
- }))
91946
+ })))
91915
91947
  });
91916
91948
  // src/services/ai/usage.ts
91917
91949
  function readUsage(text, entry) {
91918
- const decoded = decodeOption(fromJsonString(Usage))(text);
91919
- if (decoded._tag === "None") return entry;
91920
- const usage = {
91921
- ...decoded.value.message?.usage,
91922
- ...decoded.value.usage
91923
- };
91924
- const cacheReadTokens = usage.cache_read_input_tokens ?? decoded.value.usage?.prompt_tokens_details?.cached_tokens ?? entry.cacheReadTokens;
91925
- const cacheWriteTokens = usage.cache_creation_input_tokens ?? decoded.value.usage?.prompt_tokens_details?.cache_write_tokens ?? entry.cacheWriteTokens;
91926
- return {
91927
- ...entry,
91928
- cacheReadTokens,
91929
- cacheWriteTokens,
91930
- inputTokens: usage.input_tokens ?? match$8(fromUndefinedOr(usage.prompt_tokens), {
91931
- onNone: () => entry.inputTokens,
91932
- onSome: (prompt) => max(0, prompt - cacheReadTokens - cacheWriteTokens)
91933
- }),
91934
- model: decoded.value.model ?? decoded.value.message?.model ?? entry.model,
91935
- outputTokens: usage.output_tokens ?? usage.completion_tokens ?? entry.outputTokens,
91936
- ...match$1(decoded.value.usage?.cost !== void 0 || decoded.value.cost !== void 0, {
91937
- onFalse: () => ({}),
91938
- onTrue: () => ({
91939
- costSource: "provider",
91940
- costUsd: decoded.value.usage?.cost ?? decoded.value.cost
91950
+ if (isEmpty$1(trim(text)) || text === "[DONE]") return succeed$10(entry);
91951
+ return map$10(decodeResult(fromJsonString(Usage))(text), (decoded) => {
91952
+ const usage = {
91953
+ ...decoded.message?.usage,
91954
+ ...decoded.usage
91955
+ };
91956
+ const cacheReadTokens = usage.cache_read_input_tokens ?? decoded.usage?.prompt_tokens_details?.cached_tokens ?? entry.cacheReadTokens;
91957
+ const cacheWriteTokens = usage.cache_creation_input_tokens ?? decoded.usage?.prompt_tokens_details?.cache_write_tokens ?? entry.cacheWriteTokens;
91958
+ return {
91959
+ ...entry,
91960
+ cacheReadTokens,
91961
+ cacheWriteTokens,
91962
+ inputTokens: usage.input_tokens ?? match$8(fromUndefinedOr(usage.prompt_tokens), {
91963
+ onNone: () => entry.inputTokens,
91964
+ onSome: (prompt) => max(0, prompt - cacheReadTokens - cacheWriteTokens)
91965
+ }),
91966
+ model: decoded.model ?? decoded.message?.model ?? entry.model,
91967
+ outputTokens: usage.output_tokens ?? usage.completion_tokens ?? entry.outputTokens,
91968
+ ...match$1(decoded.usage?.cost !== void 0 || decoded.cost !== void 0, {
91969
+ onFalse: () => ({}),
91970
+ onTrue: () => ({
91971
+ costSource: "provider",
91972
+ costUsd: decoded.usage?.cost ?? decoded.cost
91973
+ })
91941
91974
  })
91942
- })
91943
- };
91975
+ };
91976
+ });
91944
91977
  }
91945
91978
  function totals(rows) {
91946
91979
  return reduce(rows, {
@@ -91991,10 +92024,10 @@ function report(entries, query) {
91991
92024
  model: group[0].model ?? "unknown",
91992
92025
  ...totals(group)
91993
92026
  })),
91994
- series: sort(map$8(toEntries(groupBy(selected, (entry) => `${bucket(entry)}`)), (group) => ({
91995
- at: getOrElse(parse$4(group[0]), () => 0),
91996
- byApp: grouped(group[1], (entry) => entry.app),
91997
- byModel: grouped(group[1], (entry) => entry.model ?? "unknown")
92027
+ series: sort(map$8(values(groupBy(selected, (entry) => `${bucket(entry)}`)), (group) => ({
92028
+ at: bucket(group[0]),
92029
+ byApp: grouped(group, (entry) => entry.app),
92030
+ byModel: grouped(group, (entry) => entry.model ?? "unknown")
91998
92031
  })), mapInput(Order$3, (entry) => entry.at)),
91999
92032
  totals: totals(selected)
92000
92033
  };
@@ -92057,7 +92090,7 @@ const make = gen(function* () {
92057
92090
  const now = yield* currentTimeMillis;
92058
92091
  if (now - pricing.refreshed < 864e5) return;
92059
92092
  pricing.refreshed = now;
92060
- pricing.catalog = yield* pipe$1(client.get("https://models.dev/api.json"), flatMap$2(schemaBodyJson$1(ModelsCatalog)), timeout$1("10 seconds"), orElseSucceed(() => pricing.catalog));
92093
+ pricing.catalog = yield* pipe$1(client.get("https://models.dev/api.json"), flatMap$2(schemaBodyJson$1(ModelsCatalog)), timeout$1("10 seconds"), tapError$3((error) => logWarning("The pricing catalog could not be refreshed; keeping cached pricing", error)), orElseSucceed(() => pricing.catalog));
92061
92094
  }), withPermit(pricingLock));
92062
92095
  const catalogProvider = match$1(entry.provider === "opencode-zen", {
92063
92096
  onFalse: () => entry.provider,
@@ -92145,6 +92178,9 @@ const make = gen(function* () {
92145
92178
  current: entry,
92146
92179
  pending: ""
92147
92180
  };
92181
+ const updateUsage = fnUntraced(function* (text) {
92182
+ state.current = yield* pipe$1(fromResult(readUsage(text, state.current)), catch_$2((error) => as(logWarning("AI usage was malformed; keeping previously read usage", error), state.current)));
92183
+ });
92148
92184
  const sse = includes("text/event-stream")(response.headers["content-type"] ?? "");
92149
92185
  const decoder = new TextDecoder();
92150
92186
  yield* pipe$1(fromReadableStream({
@@ -92153,20 +92189,20 @@ const make = gen(function* () {
92153
92189
  cause,
92154
92190
  message: "AI usage could not be read"
92155
92191
  })
92156
- }), takeWhile(() => state.pending.length <= 10485760), runForEach((chunk) => sync(() => {
92192
+ }), takeWhile(() => state.pending.length <= 10485760), runForEach((chunk) => gen(function* () {
92157
92193
  state.pending += decoder.decode(chunk, { stream: true });
92158
92194
  if (!sse) return;
92159
92195
  const lines = split$2(/\r?\n/u)(state.pending);
92160
92196
  state.pending = getOrElse(last(lines), () => "");
92161
- for (const line of dropRight(lines, 1)) if (startsWith("data:")(line)) state.current = readUsage(trim(slice$1(5)(line)), state.current);
92197
+ for (const line of dropRight(lines, 1)) if (startsWith("data:")(line)) yield* updateUsage(trim(slice$1(5)(line)));
92162
92198
  })), ignore$1({
92163
92199
  log: "Warn",
92164
92200
  message: "AI usage response could not be read"
92165
92201
  }));
92166
- state.current = readUsage(match$1(sse, {
92202
+ yield* updateUsage(match$1(sse, {
92167
92203
  onFalse: () => state.pending,
92168
92204
  onTrue: () => replace(/^data:\s*/u, "")(state.pending)
92169
- }), state.current);
92205
+ }));
92170
92206
  yield* saveUsage(id, state.current);
92171
92207
  }), catch_$2((error) => logWarning("AI usage could not be saved", error)), forkIn(scope));
92172
92208
  const responseBlocked = [
@@ -119397,6 +119433,10 @@ var Connections = class Connections extends Service$1()("@deslop/gateway/service
119397
119433
  static layer = effect(Connections)(Connections.make);
119398
119434
  };
119399
119435
  // src/services/gateway/lib/utils.ts
119436
+ function prunedTools(definitions, installed) {
119437
+ const connected = fromIterable$2(map$8(filter$5(definitions, (server) => server.link._tag !== "Disconnected"), (server) => make$83(server.id, server.generation)));
119438
+ return map$8(filter$5(toEntries(installed), (entry) => !has(connected, make$83(entry[1].id, entry[1].generation))), (entry) => entry[0]);
119439
+ }
119400
119440
  function quiet(property) {
119401
119441
  if (isBoolean$1(property)) return property;
119402
119442
  return filter$6(property, (value, key) => !((key === "maximum" || key === "minimum") && isNumber(value) && Math.abs(value) >= 9007199254740991));
@@ -119454,8 +119494,10 @@ var Gateway = class Gateway extends Service$1()("@deslop/gateway/services/gatewa
119454
119494
  yield* registry.notifications["notifications/tools/list_changed"]({});
119455
119495
  });
119456
119496
  const prune = gen(function* () {
119457
- const connected = fromIterable$2(map$8(filter$5(yield* connections.definitions, (server) => server.link._tag !== "Disconnected"), (server) => make$83(server.id, server.generation)));
119458
- for (const entry of toEntries(yield* get$1(installed))) if (!has(connected, make$83(entry[1].id, entry[1].generation))) yield* remove(entry[0]);
119497
+ yield* forEach$1(prunedTools(yield* connections.definitions, yield* get$1(installed)), remove, {
119498
+ concurrency: 1,
119499
+ discard: true
119500
+ });
119459
119501
  });
119460
119502
  const updateVisible = fnUntraced(function* (server, names) {
119461
119503
  if (yield* modify$1(visible, (current) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deslop/gateway",
3
- "version": "0.1.1260",
3
+ "version": "0.1.1261",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/MP281X/deslop.git",
@@ -33,5 +33,5 @@
33
33
  "engines": {
34
34
  "node": ">=26"
35
35
  },
36
- "fingerprint": "c24d4a97778975903d7919c24db6d9b7a3c8c821e90dfe152782f4652da7efdc"
36
+ "fingerprint": "0c513e501147583b164de1e24922f61c17a06b686fb4ee51b82860feaaef3244"
37
37
  }