@polka-codes/runner 0.9.91 → 0.9.93

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 (2) hide show
  1. package/dist/index.js +106 -6
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -42783,7 +42783,7 @@ var {
42783
42783
  Help
42784
42784
  } = import__.default;
42785
42785
  // package.json
42786
- var version = "0.9.91";
42786
+ var version = "0.9.93";
42787
42787
 
42788
42788
  // src/runner.ts
42789
42789
  import { execSync } from "node:child_process";
@@ -56441,12 +56441,12 @@ var toolConfigSchema = exports_external.union([
56441
56441
  var memoryConfigSchema = exports_external.object({
56442
56442
  enabled: exports_external.boolean().optional().default(true),
56443
56443
  type: exports_external.enum(["sqlite", "memory"]).optional().default("sqlite"),
56444
- path: exports_external.string().optional().default("~/.config/polka-codes/memory.sqlite")
56444
+ path: exports_external.string().optional().default("~/.config/polkacodes/memory/memory.sqlite")
56445
56445
  }).strict().optional();
56446
56446
  var DEFAULT_MEMORY_CONFIG = {
56447
56447
  enabled: true,
56448
56448
  type: "sqlite",
56449
- path: "~/.config/polka-codes/memory.sqlite"
56449
+ path: "~/.config/polkacodes/memory/memory.sqlite"
56450
56450
  };
56451
56451
  function resolveHomePath(path) {
56452
56452
  if (path.startsWith("~")) {
@@ -57815,6 +57815,7 @@ var writeToFile_default = {
57815
57815
  // ../core/src/UsageMeter.ts
57816
57816
  class UsageMeter {
57817
57817
  #totals = { input: 0, output: 0, cachedRead: 0, cost: 0, messageCount: 0 };
57818
+ #providerMetadataEntries = [];
57818
57819
  #modelInfos;
57819
57820
  #maxMessages;
57820
57821
  #maxCost;
@@ -57896,8 +57897,17 @@ class UsageMeter {
57896
57897
  this.#totals.cachedRead += result.cachedRead || 0;
57897
57898
  this.#totals.cost += result.cost || 0;
57898
57899
  this.#totals.messageCount += 1;
57900
+ if (resp.providerMetadata && Object.keys(resp.providerMetadata).length > 0) {
57901
+ const providerKey = Object.keys(resp.providerMetadata)[0];
57902
+ this.#providerMetadataEntries.push({
57903
+ provider: providerKey || llm.provider,
57904
+ model: llm.modelId,
57905
+ metadata: resp.providerMetadata[providerKey] || resp.providerMetadata,
57906
+ timestamp: Date.now()
57907
+ });
57908
+ }
57899
57909
  }
57900
- setUsage(newUsage) {
57910
+ setUsage(newUsage, options = {}) {
57901
57911
  if (newUsage.input != null)
57902
57912
  this.#totals.input = newUsage.input;
57903
57913
  if (newUsage.output != null)
@@ -57908,12 +57918,16 @@ class UsageMeter {
57908
57918
  this.#totals.cost = newUsage.cost;
57909
57919
  if (newUsage.messageCount != null)
57910
57920
  this.#totals.messageCount = newUsage.messageCount;
57921
+ if (options.clearMetadata) {
57922
+ this.#providerMetadataEntries = [];
57923
+ }
57911
57924
  }
57912
57925
  incrementMessageCount(n = 1) {
57913
57926
  this.#totals.messageCount += n;
57914
57927
  }
57915
57928
  resetUsage() {
57916
57929
  this.#totals = { input: 0, output: 0, cachedRead: 0, cost: 0, messageCount: 0 };
57930
+ this.#providerMetadataEntries = [];
57917
57931
  }
57918
57932
  isLimitExceeded() {
57919
57933
  const messageCount = this.#maxMessages > 0 && this.#totals.messageCount >= this.#maxMessages;
@@ -57935,6 +57949,37 @@ class UsageMeter {
57935
57949
  get usage() {
57936
57950
  return { ...this.#totals };
57937
57951
  }
57952
+ get providerMetadata() {
57953
+ return [...this.#providerMetadataEntries];
57954
+ }
57955
+ get cacheStats() {
57956
+ const entries = this.#providerMetadataEntries;
57957
+ const totalRequests = entries.length;
57958
+ let totalCachedTokens = 0;
57959
+ let requestsWithCache = 0;
57960
+ for (const entry of entries) {
57961
+ const metadata = entry.metadata;
57962
+ if (typeof metadata !== "object" || metadata === null) {
57963
+ continue;
57964
+ }
57965
+ const cachedTokens = metadata.cachedPromptTokens ?? metadata.cacheReadTokens ?? metadata.prompt_cache_hit_tokens ?? 0;
57966
+ if (cachedTokens > 0) {
57967
+ totalCachedTokens += cachedTokens;
57968
+ requestsWithCache++;
57969
+ }
57970
+ }
57971
+ const cacheHitRate = totalRequests > 0 ? requestsWithCache / totalRequests : 0;
57972
+ return {
57973
+ totalCachedTokens,
57974
+ totalRequests,
57975
+ requestsWithCache,
57976
+ cacheHitRate,
57977
+ entries: [...this.#providerMetadataEntries]
57978
+ };
57979
+ }
57980
+ clearProviderMetadata() {
57981
+ this.#providerMetadataEntries = [];
57982
+ }
57938
57983
  merge(other) {
57939
57984
  const otherUsage = other.usage;
57940
57985
  this.#totals.input += otherUsage.input;
@@ -57942,6 +57987,7 @@ class UsageMeter {
57942
57987
  this.#totals.cachedRead += otherUsage.cachedRead;
57943
57988
  this.#totals.cost += otherUsage.cost;
57944
57989
  this.#totals.messageCount += otherUsage.messageCount;
57990
+ this.#providerMetadataEntries.push(...other.providerMetadata);
57945
57991
  }
57946
57992
  getUsageText() {
57947
57993
  const u = this.usage;
@@ -72805,17 +72851,65 @@ ${content}`;
72805
72851
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
72806
72852
  import { randomUUID } from "node:crypto";
72807
72853
  import { existsSync as existsSync2 } from "node:fs";
72808
- import { mkdir as mkdir2, readFile as readFile3, rename as rename2, writeFile as writeFile2 } from "node:fs/promises";
72809
- import { dirname as dirname2, resolve as resolve4 } from "node:path";
72854
+ import { mkdir as mkdir2, readdir, readFile as readFile3, rename as rename2, unlink as unlink2, writeFile as writeFile2 } from "node:fs/promises";
72855
+ import { basename as basename2, dirname as dirname2, resolve as resolve4 } from "node:path";
72810
72856
  import { fileURLToPath } from "node:url";
72811
72857
  var import_sql = __toESM(require_sql_wasm(), 1);
72812
72858
 
72813
72859
  class FileLock {
72814
72860
  lockfilePath;
72815
72861
  static LOCK_TIMEOUT = 30000;
72862
+ static CLEANUP_AGE = 600000;
72863
+ static lastCleanupTime = 0;
72864
+ static CLEANUP_THROTTLE = 60000;
72816
72865
  constructor(dbPath) {
72817
72866
  this.lockfilePath = `${dbPath}.lock`;
72818
72867
  }
72868
+ static resetCleanupThrottle() {
72869
+ FileLock.lastCleanupTime = 0;
72870
+ }
72871
+ static async cleanupOldLockFiles(dbPath, maxAge = FileLock.CLEANUP_AGE, force = false) {
72872
+ const now = Date.now();
72873
+ if (!force && now - FileLock.lastCleanupTime < FileLock.CLEANUP_THROTTLE) {
72874
+ return;
72875
+ }
72876
+ FileLock.lastCleanupTime = now;
72877
+ try {
72878
+ const lockDir = dirname2(dbPath);
72879
+ const dbBaseName = basename2(dbPath);
72880
+ const files = await readdir(lockDir);
72881
+ const now2 = Date.now();
72882
+ let cleanedCount = 0;
72883
+ for (const file2 of files) {
72884
+ if (!file2.startsWith(`${dbBaseName}.lock.`)) {
72885
+ continue;
72886
+ }
72887
+ const match = file2.match(/\.lock\.(released|stale|invalid|corrupt)\.(\d+)$/);
72888
+ if (!match) {
72889
+ continue;
72890
+ }
72891
+ const filePath = resolve4(lockDir, file2);
72892
+ const timestamp = Number.parseInt(match[2], 10);
72893
+ const age = now2 - timestamp;
72894
+ if (age > maxAge) {
72895
+ try {
72896
+ await unlink2(filePath);
72897
+ cleanedCount++;
72898
+ } catch (error48) {
72899
+ const errorCode = error48?.code;
72900
+ if (errorCode !== "ENOENT") {
72901
+ console.warn(`[FileLock] Failed to delete old lock file ${file2}: ${error48 instanceof Error ? error48.message : String(error48)}`);
72902
+ }
72903
+ }
72904
+ }
72905
+ }
72906
+ if (cleanedCount > 0) {
72907
+ console.log(`[FileLock] Cleaned up ${cleanedCount} old lock file(s) (older than ${maxAge}ms)`);
72908
+ }
72909
+ } catch (error48) {
72910
+ console.debug(`[FileLock] Cleanup encountered an error: ${error48 instanceof Error ? error48.message : String(error48)}`);
72911
+ }
72912
+ }
72819
72913
  async acquire(retries = 10, delay2 = 100) {
72820
72914
  for (let i2 = 0;i2 < retries; i2++) {
72821
72915
  try {
@@ -72866,6 +72960,8 @@ class FileLock {
72866
72960
  async release() {
72867
72961
  try {
72868
72962
  await rename2(this.lockfilePath, `${this.lockfilePath}.released.${Date.now()}`);
72963
+ const dbPath = this.lockfilePath.slice(0, -5);
72964
+ FileLock.cleanupOldLockFiles(dbPath).catch(() => {});
72869
72965
  } catch (error48) {
72870
72966
  const errorCode = error48.code;
72871
72967
  if (errorCode !== "ENOENT") {
@@ -72948,6 +73044,9 @@ class SQLiteMemoryStore {
72948
73044
  inTransaction = false;
72949
73045
  transactionMutex = new ReentrantMutex;
72950
73046
  fileLock;
73047
+ static resetCleanupThrottle() {
73048
+ FileLock.resetCleanupThrottle();
73049
+ }
72951
73050
  getDbPath() {
72952
73051
  return this.config.path || DEFAULT_MEMORY_CONFIG.path;
72953
73052
  }
@@ -72984,6 +73083,7 @@ class SQLiteMemoryStore {
72984
73083
  if (!existsSync2(dir)) {
72985
73084
  await mkdir2(dir, { recursive: true, mode: 448 });
72986
73085
  }
73086
+ FileLock.cleanupOldLockFiles(dbPath).catch(() => {});
72987
73087
  let dbData;
72988
73088
  if (existsSync2(dbPath)) {
72989
73089
  const lock = this.getFileLock();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polka-codes/runner",
3
- "version": "0.9.91",
3
+ "version": "0.9.93",
4
4
  "license": "AGPL-3.0",
5
5
  "author": "github@polka.codes",
6
6
  "type": "module",
@@ -18,8 +18,8 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@ai-sdk/provider": "^2.0.1",
21
- "@polka-codes/cli-shared": "0.9.89",
22
- "@polka-codes/core": "0.9.89",
21
+ "@polka-codes/cli-shared": "0.9.91",
22
+ "@polka-codes/core": "0.9.91",
23
23
  "commander": "^14.0.2",
24
24
  "dotenv": "^17.2.3",
25
25
  "ignore": "^7.0.5",