@gapi/gcli 1.8.237 → 1.8.239

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.
package/release/index.js CHANGED
@@ -12391,7 +12391,7 @@ var require_lastValueFrom = __commonJS({
12391
12391
  Object.defineProperty(exports2, "__esModule", { value: true });
12392
12392
  exports2.lastValueFrom = void 0;
12393
12393
  var EmptyError_1 = require_EmptyError();
12394
- function lastValueFrom34(source, config2) {
12394
+ function lastValueFrom38(source, config2) {
12395
12395
  var hasConfig = typeof config2 === "object";
12396
12396
  return new Promise(function(resolve, reject) {
12397
12397
  var _hasValue = false;
@@ -12414,7 +12414,7 @@ var require_lastValueFrom = __commonJS({
12414
12414
  });
12415
12415
  });
12416
12416
  }
12417
- exports2.lastValueFrom = lastValueFrom34;
12417
+ exports2.lastValueFrom = lastValueFrom38;
12418
12418
  }
12419
12419
  });
12420
12420
 
@@ -16792,7 +16792,7 @@ var require_tap = __commonJS({
16792
16792
  var lift_1 = require_lift();
16793
16793
  var OperatorSubscriber_1 = require_OperatorSubscriber();
16794
16794
  var identity_1 = require_identity();
16795
- function tap33(observerOrNext, error48, complete) {
16795
+ function tap34(observerOrNext, error48, complete) {
16796
16796
  var tapObserver = isFunction_1.isFunction(observerOrNext) || error48 || complete ? { next: observerOrNext, error: error48, complete } : observerOrNext;
16797
16797
  return tapObserver ? lift_1.operate(function(source, subscriber) {
16798
16798
  var _a2;
@@ -16821,7 +16821,7 @@ var require_tap = __commonJS({
16821
16821
  }));
16822
16822
  }) : identity_1.identity;
16823
16823
  }
16824
- exports2.tap = tap33;
16824
+ exports2.tap = tap34;
16825
16825
  }
16826
16826
  });
16827
16827
 
@@ -27839,7 +27839,7 @@ var require_auth = __commonJS({
27839
27839
  this.a = this.c;
27840
27840
  qm(this, true);
27841
27841
  };
27842
- function rm(a, b) {
27842
+ function rm2(a, b) {
27843
27843
  if (b) return a.a = a.c, a.g();
27844
27844
  b = a.a;
27845
27845
  a.a *= 2;
@@ -27848,7 +27848,7 @@ var require_auth = __commonJS({
27848
27848
  }
27849
27849
  function qm(a, b) {
27850
27850
  a.stop();
27851
- a.b = Bd(rm(a, b)).then(function() {
27851
+ a.b = Bd(rm2(a, b)).then(function() {
27852
27852
  return Ye();
27853
27853
  }).then(function() {
27854
27854
  return a.h();
@@ -35995,7 +35995,7 @@ var require_index_cjs3 = __commonJS({
35995
35995
  });
35996
35996
 
35997
35997
  // src/types.ts
35998
- var import_os, mainDirectory, tokenDirectory, refreshTokenDirectory, urlDirectory, keyDirectory, projectDirectory, generationTimeDirectory, uploadUrlDirectory;
35998
+ var import_os, mainDirectory, tokenDirectory, refreshTokenDirectory, urlDirectory, keyDirectory, projectDirectory, generationTimeDirectory, uploadUrlDirectory, runnerDirectory;
35999
35999
  var init_types = __esm({
36000
36000
  "src/types.ts"() {
36001
36001
  import_os = require("os");
@@ -36009,6 +36009,7 @@ var init_types = __esm({
36009
36009
  "/"
36010
36010
  );
36011
36011
  uploadUrlDirectory = [mainDirectory, "upload-url"].join("/");
36012
+ runnerDirectory = [mainDirectory, "runner.json"].join("/");
36012
36013
  }
36013
36014
  });
36014
36015
 
@@ -36145,6 +36146,29 @@ scaleOptions {
36145
36146
  }
36146
36147
  });
36147
36148
 
36149
+ // src/services/types/local-runner.fragment.ts
36150
+ var LocalRunnerFragment;
36151
+ var init_local_runner_fragment = __esm({
36152
+ "src/services/types/local-runner.fragment.ts"() {
36153
+ LocalRunnerFragment = `
36154
+ id
36155
+ name
36156
+ tokenPrefix
36157
+ online
36158
+ lastSeenAt
36159
+ runnerVersion
36160
+ createdAt
36161
+ enabledModels
36162
+ models {
36163
+ name
36164
+ parameterSize
36165
+ quantization
36166
+ capabilities
36167
+ }
36168
+ `;
36169
+ }
36170
+ });
36171
+
36148
36172
  // src/services/types/plugin.fragment.ts
36149
36173
  var PluginFragment, InstalledPluginFragment;
36150
36174
  var init_plugin_fragment = __esm({
@@ -36257,6 +36281,7 @@ var init_gql_client = __esm({
36257
36281
  init_cluster_fragment();
36258
36282
  init_environment_fragment();
36259
36283
  init_lambda_fragment();
36284
+ init_local_runner_fragment();
36260
36285
  init_plugin_fragment();
36261
36286
  init_project_fragment();
36262
36287
  init_rabbitmq_fragment();
@@ -36652,6 +36677,56 @@ var init_gql_client = __esm({
36652
36677
  variables: { projectId, ...input }
36653
36678
  }).pipe((0, import_operators.map)((res) => res.provisionProjectCluster));
36654
36679
  }
36680
+ static listLocalRunners() {
36681
+ return this.query({
36682
+ query: gql`
36683
+ query listLocalRunners {
36684
+ listLocalRunners {
36685
+ ${LocalRunnerFragment}
36686
+ }
36687
+ }
36688
+ `
36689
+ }).pipe((0, import_operators.map)((res) => res.listLocalRunners));
36690
+ }
36691
+ static createLocalRunner(name2) {
36692
+ return this.query({
36693
+ query: gql`
36694
+ mutation createLocalRunner($name: String!) {
36695
+ createLocalRunner(name: $name) {
36696
+ token
36697
+ runner {
36698
+ ${LocalRunnerFragment}
36699
+ }
36700
+ }
36701
+ }
36702
+ `,
36703
+ variables: { name: name2 }
36704
+ }).pipe((0, import_operators.map)((res) => res.createLocalRunner));
36705
+ }
36706
+ static setLocalRunnerModels(runnerId, models) {
36707
+ return this.query({
36708
+ query: gql`
36709
+ mutation setLocalRunnerModels($runnerId: String!, $models: [String!]) {
36710
+ setLocalRunnerModels(runnerId: $runnerId, models: $models) {
36711
+ ${LocalRunnerFragment}
36712
+ }
36713
+ }
36714
+ `,
36715
+ variables: { runnerId, models }
36716
+ }).pipe((0, import_operators.map)((res) => res.setLocalRunnerModels));
36717
+ }
36718
+ static deleteLocalRunner(runnerId) {
36719
+ return this.query({
36720
+ query: gql`
36721
+ mutation deleteLocalRunner($runnerId: String!) {
36722
+ deleteLocalRunner(runnerId: $runnerId) {
36723
+ status
36724
+ }
36725
+ }
36726
+ `,
36727
+ variables: { runnerId }
36728
+ }).pipe((0, import_operators.map)((res) => res.deleteLocalRunner));
36729
+ }
36655
36730
  static projectClusters(projectId) {
36656
36731
  return this.query({
36657
36732
  query: gql`
@@ -42106,7 +42181,7 @@ var require_typescript = __commonJS({
42106
42181
  walkUpParenthesizedTypesAndGetParentAndChild: () => walkUpParenthesizedTypesAndGetParentAndChild,
42107
42182
  whitespaceOrMapCommentRegExp: () => whitespaceOrMapCommentRegExp,
42108
42183
  writeCommentRange: () => writeCommentRange,
42109
- writeFile: () => writeFile5,
42184
+ writeFile: () => writeFile6,
42110
42185
  writeFileEnsuringDirectories: () => writeFileEnsuringDirectories,
42111
42186
  zipWith: () => zipWith
42112
42187
  });
@@ -48438,7 +48513,7 @@ ${lanes.join("\n")}
48438
48513
  writeOutputIsTTY() {
48439
48514
  return process.stdout.isTTY;
48440
48515
  },
48441
- readFile: readFile2,
48516
+ readFile: readFile3,
48442
48517
  writeFile: writeFile22,
48443
48518
  watchFile: watchFile2,
48444
48519
  watchDirectory,
@@ -48644,7 +48719,7 @@ ${lanes.join("\n")}
48644
48719
  callback
48645
48720
  );
48646
48721
  }
48647
- function readFile2(fileName, _encoding) {
48722
+ function readFile3(fileName, _encoding) {
48648
48723
  let buffer;
48649
48724
  try {
48650
48725
  buffer = _fs.readFileSync(fileName);
@@ -60749,7 +60824,7 @@ ${lanes.join("\n")}
60749
60824
  sourceFilePath = isSourceFileInCommonSourceDirectory ? sourceFilePath.substring(commonSourceDirectory.length) : sourceFilePath;
60750
60825
  return combinePaths(newDirPath, sourceFilePath);
60751
60826
  }
60752
- function writeFile5(host, diagnostics, fileName, text, writeByteOrderMark, sourceFiles, data) {
60827
+ function writeFile6(host, diagnostics, fileName, text, writeByteOrderMark, sourceFiles, data) {
60753
60828
  host.writeFile(
60754
60829
  fileName,
60755
60830
  text,
@@ -85200,7 +85275,7 @@ ${lanes.join("\n")}
85200
85275
  const possibleOption = getSpellingSuggestion(unknownOption, diagnostics.optionDeclarations, getOptionName);
85201
85276
  return possibleOption ? createDiagnosticForNodeInSourceFileOrCompilerDiagnostic(sourceFile, node, diagnostics.unknownDidYouMeanDiagnostic, unknownOptionErrorText || unknownOption, possibleOption.name) : createDiagnosticForNodeInSourceFileOrCompilerDiagnostic(sourceFile, node, diagnostics.unknownOptionDiagnostic, unknownOptionErrorText || unknownOption);
85202
85277
  }
85203
- function parseCommandLineWorker(diagnostics, commandLine, readFile2) {
85278
+ function parseCommandLineWorker(diagnostics, commandLine, readFile3) {
85204
85279
  const options = {};
85205
85280
  let watchOptions;
85206
85281
  const fileNames = [];
@@ -85248,7 +85323,7 @@ ${lanes.join("\n")}
85248
85323
  }
85249
85324
  }
85250
85325
  function parseResponseFile(fileName) {
85251
- const text = tryReadFile(fileName, readFile2 || ((fileName2) => sys.readFile(fileName2)));
85326
+ const text = tryReadFile(fileName, readFile3 || ((fileName2) => sys.readFile(fileName2)));
85252
85327
  if (!isString(text)) {
85253
85328
  errors.push(text);
85254
85329
  return;
@@ -85351,8 +85426,8 @@ ${lanes.join("\n")}
85351
85426
  unknownDidYouMeanDiagnostic: Diagnostics.Unknown_compiler_option_0_Did_you_mean_1,
85352
85427
  optionTypeMismatchDiagnostic: Diagnostics.Compiler_option_0_expects_an_argument
85353
85428
  };
85354
- function parseCommandLine(commandLine, readFile2) {
85355
- return parseCommandLineWorker(compilerOptionsDidYouMeanDiagnostics, commandLine, readFile2);
85429
+ function parseCommandLine(commandLine, readFile3) {
85430
+ return parseCommandLineWorker(compilerOptionsDidYouMeanDiagnostics, commandLine, readFile3);
85356
85431
  }
85357
85432
  function getOptionFromName(optionName, allowShort) {
85358
85433
  return getOptionDeclarationFromName(getOptionsNameMap, optionName, allowShort);
@@ -85434,8 +85509,8 @@ ${lanes.join("\n")}
85434
85509
  watchOptionsToExtend
85435
85510
  );
85436
85511
  }
85437
- function readConfigFile(fileName, readFile2) {
85438
- const textOrDiagnostic = tryReadFile(fileName, readFile2);
85512
+ function readConfigFile(fileName, readFile3) {
85513
+ const textOrDiagnostic = tryReadFile(fileName, readFile3);
85439
85514
  return isString(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic };
85440
85515
  }
85441
85516
  function parseConfigFileTextToJson(fileName, jsonText) {
@@ -85450,14 +85525,14 @@ ${lanes.join("\n")}
85450
85525
  error: jsonSourceFile.parseDiagnostics.length ? jsonSourceFile.parseDiagnostics[0] : void 0
85451
85526
  };
85452
85527
  }
85453
- function readJsonConfigFile(fileName, readFile2) {
85454
- const textOrDiagnostic = tryReadFile(fileName, readFile2);
85528
+ function readJsonConfigFile(fileName, readFile3) {
85529
+ const textOrDiagnostic = tryReadFile(fileName, readFile3);
85455
85530
  return isString(textOrDiagnostic) ? parseJsonText(fileName, textOrDiagnostic) : { fileName, parseDiagnostics: [textOrDiagnostic] };
85456
85531
  }
85457
- function tryReadFile(fileName, readFile2) {
85532
+ function tryReadFile(fileName, readFile3) {
85458
85533
  let text;
85459
85534
  try {
85460
- text = readFile2(fileName);
85535
+ text = readFile3(fileName);
85461
85536
  } catch (e2) {
85462
85537
  return createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e2.message);
85463
85538
  }
@@ -169500,7 +169575,7 @@ ${lanes.join("\n")}
169500
169575
  return;
169501
169576
  }
169502
169577
  const buildInfo = host.getBuildInfo() || { version: version2 };
169503
- writeFile5(
169578
+ writeFile6(
169504
169579
  host,
169505
169580
  emitterDiagnostics,
169506
169581
  buildInfoPath,
@@ -169712,7 +169787,7 @@ ${lanes.join("\n")}
169712
169787
  }
169713
169788
  if (sourceMapFilePath) {
169714
169789
  const sourceMap = sourceMapGenerator.toString();
169715
- writeFile5(
169790
+ writeFile6(
169716
169791
  host,
169717
169792
  emitterDiagnostics,
169718
169793
  sourceMapFilePath,
@@ -169727,7 +169802,7 @@ ${lanes.join("\n")}
169727
169802
  }
169728
169803
  const text = writer.getText();
169729
169804
  const data = { sourceMapUrlPos, diagnostics: transform22.diagnostics };
169730
- writeFile5(host, emitterDiagnostics, jsFilePath, text, !!compilerOptions.emitBOM, sourceFiles, data);
169805
+ writeFile6(host, emitterDiagnostics, jsFilePath, text, !!compilerOptions.emitBOM, sourceFiles, data);
169731
169806
  writer.clear();
169732
169807
  return !data.skippedDtsWrite;
169733
169808
  }
@@ -175115,12 +175190,12 @@ ${lanes.join("\n")}
175115
175190
  function createCompilerHost(options, setParentNodes) {
175116
175191
  return createCompilerHostWorker(options, setParentNodes);
175117
175192
  }
175118
- function createGetSourceFile(readFile2, setParentNodes) {
175193
+ function createGetSourceFile(readFile3, setParentNodes) {
175119
175194
  return (fileName, languageVersionOrOptions, onError) => {
175120
175195
  let text;
175121
175196
  try {
175122
175197
  mark("beforeIORead");
175123
- text = readFile2(fileName);
175198
+ text = readFile3(fileName);
175124
175199
  mark("afterIORead");
175125
175200
  measure("I/O Read", "beforeIORead", "afterIORead");
175126
175201
  } catch (e2) {
@@ -176024,7 +176099,7 @@ ${lanes.join("\n")}
176024
176099
  getRedirectFromOutput,
176025
176100
  forEachResolvedProjectReference: forEachResolvedProjectReference2
176026
176101
  });
176027
- const readFile2 = host.readFile.bind(host);
176102
+ const readFile3 = host.readFile.bind(host);
176028
176103
  (_e = tracing) == null ? void 0 : _e.push(tracing.Phase.Program, "shouldProgramCreateNewSourceFiles", { hasOldProgram: !!oldProgram });
176029
176104
  const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
176030
176105
  (_f = tracing) == null ? void 0 : _f.pop();
@@ -176250,7 +176325,7 @@ ${lanes.join("\n")}
176250
176325
  shouldTransformImportCall,
176251
176326
  emitBuildInfo,
176252
176327
  fileExists,
176253
- readFile: readFile2,
176328
+ readFile: readFile3,
176254
176329
  directoryExists,
176255
176330
  getSymlinkCache,
176256
176331
  realpath: (_o = host.realpath) == null ? void 0 : _o.bind(host),
@@ -237609,7 +237684,7 @@ ${options.prefix}` : "\n" : options.prefix
237609
237684
  walkUpParenthesizedTypesAndGetParentAndChild: () => walkUpParenthesizedTypesAndGetParentAndChild,
237610
237685
  whitespaceOrMapCommentRegExp: () => whitespaceOrMapCommentRegExp,
237611
237686
  writeCommentRange: () => writeCommentRange,
237612
- writeFile: () => writeFile5,
237687
+ writeFile: () => writeFile6,
237613
237688
  writeFileEnsuringDirectories: () => writeFileEnsuringDirectories,
237614
237689
  zipWith: () => zipWith
237615
237690
  });
@@ -250734,7 +250809,7 @@ var require_esbuild_decorators = __commonJS({
250734
250809
  var typescript_1 = require_typescript();
250735
250810
  var util_1 = require("util");
250736
250811
  var strip_it_1 = require_strip_it();
250737
- var { readFile: readFile2 } = fs_1.promises;
250812
+ var { readFile: readFile3 } = fs_1.promises;
250738
250813
  var theFinder = new RegExp(/((?<![(\s]\s*['"])@\w[.[\]\w\d]*\s*(?![;])[((?=\s)])/);
250739
250814
  var findDecorators = (fileContent) => theFinder.test((0, strip_it_1.strip)(fileContent));
250740
250815
  var esbuildDecorators2 = (options = {}) => ({
@@ -250758,7 +250833,7 @@ var require_esbuild_decorators = __commonJS({
250758
250833
  if (!forceTsc && (!parsedTsConfig || !parsedTsConfig.options || !parsedTsConfig.options.emitDecoratorMetadata)) {
250759
250834
  return;
250760
250835
  }
250761
- const ts = yield readFile2(args.path, "utf8").catch((err) => printDiagnostics({ file: args.path, err }));
250836
+ const ts = yield readFile3(args.path, "utf8").catch((err) => printDiagnostics({ file: args.path, err }));
250762
250837
  const hasDecorator = findDecorators(ts);
250763
250838
  if (!ts || !hasDecorator) {
250764
250839
  return;
@@ -267389,8 +267464,8 @@ var require_graceful_fs = __commonJS({
267389
267464
  fs3.createReadStream = createReadStream3;
267390
267465
  fs3.createWriteStream = createWriteStream;
267391
267466
  var fs$readFile = fs3.readFile;
267392
- fs3.readFile = readFile2;
267393
- function readFile2(path2, options, cb) {
267467
+ fs3.readFile = readFile3;
267468
+ function readFile3(path2, options, cb) {
267394
267469
  if (typeof options === "function")
267395
267470
  cb = options, options = null;
267396
267471
  return go$readFile(path2, options, cb);
@@ -267407,8 +267482,8 @@ var require_graceful_fs = __commonJS({
267407
267482
  }
267408
267483
  }
267409
267484
  var fs$writeFile = fs3.writeFile;
267410
- fs3.writeFile = writeFile5;
267411
- function writeFile5(path2, data, options, cb) {
267485
+ fs3.writeFile = writeFile6;
267486
+ function writeFile6(path2, data, options, cb) {
267412
267487
  if (typeof options === "function")
267413
267488
  cb = options, options = null;
267414
267489
  return go$writeFile(path2, data, options, cb);
@@ -316863,17 +316938,739 @@ var init_delete2 = __esm({
316863
316938
  }
316864
316939
  });
316865
316940
 
316866
- // src/commands/start/start.ts
316941
+ // src/commands/runner/config.ts
316942
+ var import_promises, DEFAULT_WS_URL, deriveSubscriptionsUrl, readLoginApiUrl, readSavedRunner, saveRunner, forgetRunner;
316943
+ var init_config = __esm({
316944
+ "src/commands/runner/config.ts"() {
316945
+ import_promises = require("fs/promises");
316946
+ init_types();
316947
+ DEFAULT_WS_URL = "wss://api.lambforge.com/subscriptions";
316948
+ deriveSubscriptionsUrl = (apiUrl) => {
316949
+ if (!apiUrl?.trim()) {
316950
+ return DEFAULT_WS_URL;
316951
+ }
316952
+ const url2 = new URL(apiUrl.trim());
316953
+ if (["localhost", "127.0.0.1"].includes(url2.hostname) && url2.port === "9004") {
316954
+ return `ws://${url2.hostname}:9000/subscriptions`;
316955
+ }
316956
+ url2.protocol = url2.protocol === "http:" ? "ws:" : "wss:";
316957
+ url2.pathname = "/subscriptions";
316958
+ url2.search = "";
316959
+ return url2.toString();
316960
+ };
316961
+ readLoginApiUrl = () => (0, import_promises.readFile)(urlDirectory, "utf-8").catch(() => "");
316962
+ readSavedRunner = async () => {
316963
+ try {
316964
+ const saved = JSON.parse(await (0, import_promises.readFile)(runnerDirectory, "utf-8"));
316965
+ return saved?.id && saved?.token ? saved : null;
316966
+ } catch {
316967
+ return null;
316968
+ }
316969
+ };
316970
+ saveRunner = async (runner) => {
316971
+ await (0, import_promises.mkdir)(mainDirectory, { recursive: true });
316972
+ await (0, import_promises.writeFile)(runnerDirectory, JSON.stringify(runner, null, 2), "utf-8");
316973
+ await (0, import_promises.chmod)(runnerDirectory, 384);
316974
+ };
316975
+ forgetRunner = () => (0, import_promises.rm)(runnerDirectory, { force: true });
316976
+ }
316977
+ });
316978
+
316979
+ // src/commands/runner/ollama.ts
316980
+ var ALLOWED_REQUESTS, isAllowedRequest, resolveOllamaUrl, OllamaModels;
316981
+ var init_ollama = __esm({
316982
+ "src/commands/runner/ollama.ts"() {
316983
+ ALLOWED_REQUESTS = [
316984
+ { method: "POST", path: "/v1/chat/completions" }
316985
+ ];
316986
+ isAllowedRequest = (method, path2) => ALLOWED_REQUESTS.some(
316987
+ (r2) => r2.method === method?.toUpperCase() && r2.path === path2
316988
+ );
316989
+ resolveOllamaUrl = (option) => {
316990
+ const raw = option || process.env.OLLAMA_HOST || "http://127.0.0.1:11434";
316991
+ const withScheme = /^https?:\/\//.test(raw) ? raw : `http://${raw}`;
316992
+ const url2 = new URL(withScheme);
316993
+ if (url2.hostname === "0.0.0.0") {
316994
+ url2.hostname = "127.0.0.1";
316995
+ }
316996
+ return url2.origin;
316997
+ };
316998
+ OllamaModels = class {
316999
+ constructor(baseUrl, fetchFn = fetch) {
317000
+ this.baseUrl = baseUrl;
317001
+ this.fetchFn = fetchFn;
317002
+ this.showCache = /* @__PURE__ */ new Map();
317003
+ }
317004
+ async list() {
317005
+ const res = await this.fetchFn(`${this.baseUrl}/api/tags`);
317006
+ if (!res.ok) {
317007
+ throw new Error(`Ollama /api/tags returned ${res.status}`);
317008
+ }
317009
+ const { models = [] } = await res.json();
317010
+ const [described, loaded] = await Promise.all([
317011
+ Promise.all(models.map((tag) => this.describe(tag))),
317012
+ this.loadedContextLengths()
317013
+ ]);
317014
+ for (const model of described) {
317015
+ model.runtimeContextLength = loaded.get(model.name);
317016
+ }
317017
+ return described.filter((m2) => !m2.unusable).filter(
317018
+ (m2) => !m2.capabilities.length || m2.capabilities.includes("completion")
317019
+ ).map((m2) => {
317020
+ delete m2.unusable;
317021
+ return m2;
317022
+ });
317023
+ }
317024
+ /**
317025
+ * The context window each LOADED model actually runs with (`/api/ps`,
317026
+ * what `ollama ps` shows) - OLLAMA_CONTEXT_LENGTH / Ollama's VRAM-based
317027
+ * default, usually far below the model's own `contextLength`. Ollama
317028
+ * silently drops the oldest messages of a prompt that doesn't fit, so the
317029
+ * backend sizes requests with this. Unloaded models aren't listed; the
317030
+ * backend keeps the last known value.
317031
+ */
317032
+ async loadedContextLengths() {
317033
+ try {
317034
+ const res = await this.fetchFn(`${this.baseUrl}/api/ps`);
317035
+ if (!res.ok) {
317036
+ return /* @__PURE__ */ new Map();
317037
+ }
317038
+ const { models = [] } = await res.json();
317039
+ return new Map(
317040
+ models.filter((m2) => typeof m2.context_length === "number").map((m2) => [m2.name ?? m2.model, m2.context_length])
317041
+ );
317042
+ } catch {
317043
+ return /* @__PURE__ */ new Map();
317044
+ }
317045
+ }
317046
+ async describe(tag) {
317047
+ const show = await this.show(tag);
317048
+ const contextLength = Object.entries(show?.model_info ?? {}).find(
317049
+ ([key]) => key.endsWith(".context_length")
317050
+ )?.[1];
317051
+ return {
317052
+ unusable: show?.unusable,
317053
+ name: tag.name,
317054
+ family: tag.details?.family,
317055
+ parameterSize: tag.details?.parameter_size,
317056
+ quantization: tag.details?.quantization_level,
317057
+ capabilities: show?.capabilities ?? [],
317058
+ contextLength: typeof contextLength === "number" ? contextLength : void 0
317059
+ };
317060
+ }
317061
+ async show(tag) {
317062
+ const key = tag.digest || tag.name;
317063
+ if (this.showCache.has(key)) {
317064
+ return this.showCache.get(key);
317065
+ }
317066
+ try {
317067
+ const res = await this.fetchFn(`${this.baseUrl}/api/show`, {
317068
+ method: "POST",
317069
+ headers: { "Content-Type": "application/json" },
317070
+ body: JSON.stringify({ model: tag.name })
317071
+ });
317072
+ if (res.status === 404 || res.status === 410) {
317073
+ const gone = { unusable: true };
317074
+ this.showCache.set(key, gone);
317075
+ return gone;
317076
+ }
317077
+ if (!res.ok) {
317078
+ return void 0;
317079
+ }
317080
+ const show = await res.json();
317081
+ this.showCache.set(key, show);
317082
+ return show;
317083
+ } catch {
317084
+ return void 0;
317085
+ }
317086
+ }
317087
+ };
317088
+ }
317089
+ });
317090
+
317091
+ // src/commands/runner/connection.ts
317092
+ var OPEN, SUBSCRIPTION_ID, MAX_CHUNK_CHARS, REQUESTS_SUBSCRIPTION, HEARTBEAT_MUTATION, RESPOND_MUTATION, RunnerAuthError, describeError, FrameSender, RunnerConnection;
317093
+ var init_connection = __esm({
317094
+ "src/commands/runner/connection.ts"() {
317095
+ init_ollama();
317096
+ OPEN = 1;
317097
+ SUBSCRIPTION_ID = "runner-requests";
317098
+ MAX_CHUNK_CHARS = 32 * 1024;
317099
+ REQUESTS_SUBSCRIPTION = `subscription {
317100
+ subscribeToRunnerRequests { requestId type method path body }
317101
+ }`;
317102
+ HEARTBEAT_MUTATION = `mutation runnerHeartbeat($models: [LocalRunnerModelInput], $runnerVersion: String) {
317103
+ runnerHeartbeat(models: $models, runnerVersion: $runnerVersion) { id name }
317104
+ }`;
317105
+ RESPOND_MUTATION = `mutation runnerRespond($frames: [RunnerResponseFrameInput!]!) {
317106
+ runnerRespond(frames: $frames) { status }
317107
+ }`;
317108
+ RunnerAuthError = class extends Error {
317109
+ };
317110
+ describeError = (e2) => e2 instanceof Error ? e2.message : String(e2);
317111
+ FrameSender = class {
317112
+ constructor(requestId, send, flushMs) {
317113
+ this.requestId = requestId;
317114
+ this.send = send;
317115
+ this.flushMs = flushMs;
317116
+ this.seq = 0;
317117
+ this.queue = [];
317118
+ this.sending = Promise.resolve();
317119
+ this.lastPushAt = Date.now();
317120
+ }
317121
+ push(frame) {
317122
+ this.lastPushAt = Date.now();
317123
+ const last = this.queue[this.queue.length - 1];
317124
+ if (frame.type === "chunk" && last?.type === "chunk" && last.data.length + frame.data.length <= MAX_CHUNK_CHARS) {
317125
+ last.data += frame.data;
317126
+ } else {
317127
+ this.queue.push({ ...frame, requestId: this.requestId, seq: this.seq++ });
317128
+ }
317129
+ if (!this.timer) {
317130
+ this.timer = setTimeout(() => void this.flush(), this.flushMs);
317131
+ }
317132
+ }
317133
+ flush() {
317134
+ clearTimeout(this.timer);
317135
+ this.timer = void 0;
317136
+ const frames = this.queue.splice(0);
317137
+ if (frames.length) {
317138
+ this.sending = this.sending.then(() => this.send(frames)).then(
317139
+ () => void 0,
317140
+ () => void 0
317141
+ );
317142
+ }
317143
+ return this.sending;
317144
+ }
317145
+ };
317146
+ RunnerConnection = class {
317147
+ constructor(options) {
317148
+ this.options = options;
317149
+ this.stopped = false;
317150
+ this.nextOperationId = 1;
317151
+ this.operations = /* @__PURE__ */ new Map();
317152
+ this.activeRequests = /* @__PURE__ */ new Map();
317153
+ this.announcedModels = "";
317154
+ this.fetchFn = options.fetchFn ?? fetch;
317155
+ this.ollama = new OllamaModels(options.ollamaUrl, this.fetchFn);
317156
+ }
317157
+ /** Runs until `stop()`; rejects only when the token is refused. */
317158
+ async run() {
317159
+ let attempt = 0;
317160
+ while (!this.stopped) {
317161
+ const connected = await this.connectOnce();
317162
+ if (this.fatal) {
317163
+ throw this.fatal;
317164
+ }
317165
+ if (this.stopped) {
317166
+ return;
317167
+ }
317168
+ attempt = connected ? 0 : attempt + 1;
317169
+ const delay = Math.min(
317170
+ this.options.maxReconnectDelayMs ?? 3e4,
317171
+ 1e3 * 2 ** attempt
317172
+ );
317173
+ this.options.logger.warn(
317174
+ `Disconnected from Lambforge; reconnecting in ${Math.round(delay / 1e3)}s...`
317175
+ );
317176
+ await new Promise((r2) => setTimeout(r2, delay));
317177
+ }
317178
+ }
317179
+ stop() {
317180
+ this.stopped = true;
317181
+ this.socket?.close(1e3, "runner stopped");
317182
+ }
317183
+ /** Resolves when the socket closes; `true` if it got as far as being acknowledged. */
317184
+ connectOnce() {
317185
+ return new Promise((resolve) => {
317186
+ let acknowledged = false;
317187
+ const createSocket = this.options.createSocket ?? ((url2, protocol) => {
317188
+ if (typeof WebSocket === "undefined") {
317189
+ throw new Error("gcli runner requires Node.js 22 or newer");
317190
+ }
317191
+ return new WebSocket(url2, protocol);
317192
+ });
317193
+ let socket;
317194
+ try {
317195
+ socket = createSocket(this.options.wsUrl, "graphql-ws");
317196
+ } catch (e2) {
317197
+ this.options.logger.error(describeError(e2));
317198
+ resolve(false);
317199
+ return;
317200
+ }
317201
+ this.socket = socket;
317202
+ socket.onopen = () => this.send({
317203
+ type: "connection_init",
317204
+ payload: { runnerToken: this.options.token }
317205
+ });
317206
+ socket.onmessage = (event) => {
317207
+ let message;
317208
+ try {
317209
+ message = JSON.parse(String(event.data));
317210
+ } catch {
317211
+ return;
317212
+ }
317213
+ if (message.type === "connection_ack") {
317214
+ acknowledged = true;
317215
+ void this.onConnected();
317216
+ } else if (message.type === "connection_error") {
317217
+ const reason = message.payload?.message || "connection refused";
317218
+ this.fatal = new RunnerAuthError(
317219
+ `Lambforge refused this runner (${reason}). The runner may have been deleted - re-register it with \`gcli runner:start --reset\`.`
317220
+ );
317221
+ socket.close();
317222
+ } else if (message.id === SUBSCRIPTION_ID) {
317223
+ if (message.type === "data") {
317224
+ const request = message.payload?.data?.subscribeToRunnerRequests;
317225
+ if (request) {
317226
+ void this.onRequest(request);
317227
+ }
317228
+ } else if (message.type === "error" || message.type === "complete") {
317229
+ this.options.logger.error(
317230
+ `Request subscription ended: ${JSON.stringify(message.payload ?? {})}`
317231
+ );
317232
+ socket.close();
317233
+ }
317234
+ } else if (message.id && this.operations.has(message.id)) {
317235
+ this.onOperationMessage(message.id, message.type, message.payload);
317236
+ }
317237
+ };
317238
+ socket.onerror = () => void 0;
317239
+ socket.onclose = () => {
317240
+ this.onDisconnected();
317241
+ resolve(acknowledged);
317242
+ };
317243
+ });
317244
+ }
317245
+ async onConnected() {
317246
+ this.send({
317247
+ id: SUBSCRIPTION_ID,
317248
+ type: "start",
317249
+ payload: { query: REQUESTS_SUBSCRIPTION }
317250
+ });
317251
+ const runner = await this.heartbeat(true).catch((e2) => {
317252
+ this.options.logger.error(`Heartbeat failed: ${describeError(e2)}`);
317253
+ return null;
317254
+ });
317255
+ if (runner) {
317256
+ this.options.logger.log(
317257
+ `Connected as "${runner.name}" (${runner.id}). Your local models are now available in the Lambforge chat.`
317258
+ );
317259
+ }
317260
+ clearInterval(this.heartbeatTimer);
317261
+ this.heartbeatTimer = setInterval(
317262
+ () => void this.heartbeat(false).catch((e2) => {
317263
+ this.options.logger.warn(`Heartbeat failed: ${describeError(e2)}`);
317264
+ this.socket?.close();
317265
+ }),
317266
+ this.options.heartbeatMs ?? 3e4
317267
+ );
317268
+ }
317269
+ onDisconnected() {
317270
+ clearInterval(this.heartbeatTimer);
317271
+ for (const [id, op] of this.operations) {
317272
+ clearTimeout(op.timer);
317273
+ op.reject(new Error("connection closed"));
317274
+ this.operations.delete(id);
317275
+ }
317276
+ for (const controller of this.activeRequests.values()) {
317277
+ controller.abort();
317278
+ }
317279
+ this.activeRequests.clear();
317280
+ }
317281
+ async heartbeat(announce) {
317282
+ let models = [];
317283
+ try {
317284
+ models = await this.ollama.list();
317285
+ if (this.ollamaReachable === false || announce) {
317286
+ this.options.logger.info(
317287
+ `Ollama at ${this.options.ollamaUrl}: ${models.length} model(s)`
317288
+ );
317289
+ }
317290
+ this.ollamaReachable = true;
317291
+ } catch (e2) {
317292
+ if (this.ollamaReachable !== false) {
317293
+ this.options.logger.warn(
317294
+ `Cannot reach Ollama at ${this.options.ollamaUrl} (${describeError(e2)}). Is it running? Retrying...`
317295
+ );
317296
+ }
317297
+ this.ollamaReachable = false;
317298
+ }
317299
+ const names = JSON.stringify(
317300
+ models.map((m2) => m2.name)
317301
+ );
317302
+ if (!announce && names !== this.announcedModels && this.ollamaReachable) {
317303
+ this.options.logger.info(
317304
+ `Models: ${models.map((m2) => m2.name).join(", ") || "(none)"}`
317305
+ );
317306
+ }
317307
+ this.announcedModels = names;
317308
+ const data = await this.operation(HEARTBEAT_MUTATION, {
317309
+ models,
317310
+ runnerVersion: this.options.version
317311
+ });
317312
+ return data?.runnerHeartbeat;
317313
+ }
317314
+ async onRequest(request) {
317315
+ if (request.type === "cancel") {
317316
+ this.activeRequests.get(request.requestId)?.abort();
317317
+ return;
317318
+ }
317319
+ const sender = new FrameSender(
317320
+ request.requestId,
317321
+ (frames) => this.operation(RESPOND_MUTATION, { frames }),
317322
+ this.options.flushMs ?? 50
317323
+ );
317324
+ if (!isAllowedRequest(request.method, request.path)) {
317325
+ sender.push({
317326
+ type: "error",
317327
+ error: `${request.method} ${request.path} is not allowed by this runner`
317328
+ });
317329
+ await sender.flush();
317330
+ return;
317331
+ }
317332
+ const controller = new AbortController();
317333
+ this.activeRequests.set(request.requestId, controller);
317334
+ sender.push({ type: "ack" });
317335
+ void sender.flush();
317336
+ const pingMs = this.options.pingMs ?? 3e4;
317337
+ const ping = setInterval(() => {
317338
+ if (Date.now() - sender.lastPushAt >= pingMs) {
317339
+ sender.push({ type: "ping" });
317340
+ void sender.flush();
317341
+ }
317342
+ }, pingMs);
317343
+ const started = Date.now();
317344
+ const model = this.modelOf(request.body);
317345
+ this.options.logger.info(`-> chat request (${model})`);
317346
+ try {
317347
+ const response = await this.fetchFn(
317348
+ `${this.options.ollamaUrl}${request.path}`,
317349
+ {
317350
+ method: request.method,
317351
+ headers: { "Content-Type": "application/json" },
317352
+ body: request.body,
317353
+ signal: controller.signal
317354
+ }
317355
+ );
317356
+ sender.push({
317357
+ type: "head",
317358
+ status: response.status,
317359
+ data: response.headers.get("content-type") ?? void 0
317360
+ });
317361
+ const reader = response.body?.getReader();
317362
+ const decoder = new TextDecoder();
317363
+ while (reader) {
317364
+ const { done, value } = await reader.read();
317365
+ if (done) {
317366
+ break;
317367
+ }
317368
+ const text = decoder.decode(value, { stream: true });
317369
+ if (text) {
317370
+ sender.push({ type: "chunk", data: text });
317371
+ }
317372
+ }
317373
+ const tail = decoder.decode();
317374
+ if (tail) {
317375
+ sender.push({ type: "chunk", data: tail });
317376
+ }
317377
+ sender.push({ type: "end" });
317378
+ this.options.logger.info(
317379
+ `<- ${response.status} (${model}) in ${((Date.now() - started) / 1e3).toFixed(1)}s`
317380
+ );
317381
+ } catch (e2) {
317382
+ if (controller.signal.aborted) {
317383
+ this.options.logger.info(`x cancelled (${model})`);
317384
+ } else {
317385
+ const reason = describeError(e2);
317386
+ this.options.logger.error(`x ${reason}`);
317387
+ sender.push({
317388
+ type: "error",
317389
+ error: /fetch failed|ECONNREFUSED/.test(reason) ? `Could not reach Ollama at ${this.options.ollamaUrl} on the runner machine - is it running?` : reason
317390
+ });
317391
+ }
317392
+ } finally {
317393
+ clearInterval(ping);
317394
+ this.activeRequests.delete(request.requestId);
317395
+ await sender.flush();
317396
+ }
317397
+ }
317398
+ modelOf(body) {
317399
+ try {
317400
+ return JSON.parse(body ?? "{}").model ?? "unknown model";
317401
+ } catch {
317402
+ return "unknown model";
317403
+ }
317404
+ }
317405
+ operation(query, variables) {
317406
+ const id = String(this.nextOperationId++);
317407
+ return new Promise((resolve, reject) => {
317408
+ if (this.socket?.readyState !== OPEN) {
317409
+ reject(new Error("not connected"));
317410
+ return;
317411
+ }
317412
+ const timer2 = setTimeout(() => {
317413
+ this.operations.delete(id);
317414
+ reject(new Error("timed out waiting for Lambforge"));
317415
+ }, this.options.operationTimeoutMs ?? 2e4);
317416
+ this.operations.set(id, { resolve, reject, timer: timer2 });
317417
+ this.send({ id, type: "start", payload: { query, variables } });
317418
+ });
317419
+ }
317420
+ onOperationMessage(id, type, payload) {
317421
+ const op = this.operations.get(id);
317422
+ this.operations.delete(id);
317423
+ clearTimeout(op.timer);
317424
+ if (type === "data" && !payload?.errors?.length) {
317425
+ op.resolve(payload?.data);
317426
+ } else if (type === "complete") {
317427
+ op.resolve(void 0);
317428
+ } else {
317429
+ op.reject(
317430
+ new Error(
317431
+ payload?.errors?.map((e2) => e2.message).join("; ") || payload?.message || "operation failed"
317432
+ )
317433
+ );
317434
+ }
317435
+ }
317436
+ send(message) {
317437
+ if (this.socket?.readyState === OPEN) {
317438
+ this.socket.send(JSON.stringify(message));
317439
+ }
317440
+ }
317441
+ };
317442
+ }
317443
+ });
317444
+
317445
+ // src/commands/runner/start.ts
316867
317446
  var start_exports2 = {};
316868
317447
  __export(start_exports2, {
317448
+ RUNNER_VERSION: () => RUNNER_VERSION,
317449
+ default: () => start_default
317450
+ });
317451
+ var import_os2, import_rxjs35, RUNNER_VERSION, resolveRunner, start_default;
317452
+ var init_start2 = __esm({
317453
+ "src/commands/runner/start.ts"() {
317454
+ import_os2 = require("os");
317455
+ import_rxjs35 = __toESM(require_cjs());
317456
+ init_gql_client();
317457
+ init_log();
317458
+ init_config();
317459
+ init_connection();
317460
+ init_ollama();
317461
+ RUNNER_VERSION = "gcli-runner/1";
317462
+ resolveRunner = async (cmd) => {
317463
+ if (cmd.token) {
317464
+ return { id: "(from --token)", name: cmd.name ?? "", token: cmd.token };
317465
+ }
317466
+ if (cmd.reset) {
317467
+ await forgetRunner();
317468
+ }
317469
+ const saved = await readSavedRunner();
317470
+ if (saved) {
317471
+ return saved;
317472
+ }
317473
+ const name2 = cmd.name || (0, import_os2.hostname)();
317474
+ Logger.info(`Registering this machine as local runner "${name2}"...`);
317475
+ const { runner, token } = await (0, import_rxjs35.lastValueFrom)(
317476
+ GraphqlClienAPI.createLocalRunner(name2)
317477
+ ).catch((e2) => {
317478
+ throw new Error(
317479
+ `Could not register the runner (${e2?.message ?? e2}). Run \`gcli login\` first, or pass --token from Profile -> Local AI runners.`
317480
+ );
317481
+ });
317482
+ const created = { id: runner.id, name: runner.name, token };
317483
+ await saveRunner(created);
317484
+ return created;
317485
+ };
317486
+ start_default = async (cmd) => {
317487
+ const runner = await resolveRunner(cmd);
317488
+ const ollamaUrl = resolveOllamaUrl(cmd.ollama);
317489
+ const wsUrl = cmd.wsUrl || runner.wsUrl || deriveSubscriptionsUrl(await readLoginApiUrl());
317490
+ Logger.log("-------------------");
317491
+ Logger.log("[Lambforge local AI runner]");
317492
+ Logger.info(`Lambforge: ${wsUrl}`);
317493
+ Logger.info(`Ollama: ${ollamaUrl}`);
317494
+ Logger.info(
317495
+ "Tip: agent mode sends large prompts (instructions + tool list). Give Ollama a big context window, e.g. start it with OLLAMA_CONTEXT_LENGTH=32768."
317496
+ );
317497
+ Logger.log("-------------------");
317498
+ const connection = new RunnerConnection({
317499
+ wsUrl,
317500
+ token: runner.token,
317501
+ ollamaUrl,
317502
+ version: RUNNER_VERSION,
317503
+ logger: Logger
317504
+ });
317505
+ const shutdown = () => {
317506
+ Logger.info("Stopping runner...");
317507
+ connection.stop();
317508
+ };
317509
+ process.once("SIGINT", shutdown);
317510
+ process.once("SIGTERM", shutdown);
317511
+ try {
317512
+ await connection.run();
317513
+ } catch (e2) {
317514
+ if (e2 instanceof RunnerAuthError) {
317515
+ Logger.error(e2.message);
317516
+ process.exit(1);
317517
+ }
317518
+ throw e2;
317519
+ }
317520
+ };
317521
+ }
317522
+ });
317523
+
317524
+ // src/commands/runner/list.ts
317525
+ var list_exports6 = {};
317526
+ __export(list_exports6, {
317527
+ default: () => list_default6
317528
+ });
317529
+ var import_rxjs36, import_operators34, list_default6;
317530
+ var init_list6 = __esm({
317531
+ "src/commands/runner/list.ts"() {
317532
+ import_rxjs36 = __toESM(require_cjs());
317533
+ import_operators34 = __toESM(require_operators());
317534
+ init_gql_client();
317535
+ init_log();
317536
+ list_default6 = () => (0, import_rxjs36.lastValueFrom)(
317537
+ GraphqlClienAPI.listLocalRunners().pipe(
317538
+ (0, import_operators34.tap)((runners) => {
317539
+ Logger.log("-------------------");
317540
+ Logger.log("[Action][listLocalRunners]");
317541
+ if (!runners?.length) {
317542
+ Logger.info(
317543
+ "No local runners yet. Run `gcli runner:start` on the machine that runs Ollama."
317544
+ );
317545
+ } else {
317546
+ Logger.table(
317547
+ runners.map((r2) => ({
317548
+ id: r2.id,
317549
+ name: r2.name,
317550
+ online: r2.online,
317551
+ lastSeenAt: r2.lastSeenAt,
317552
+ models: (r2.models ?? []).map((m2) => m2.name).join(", ")
317553
+ }))
317554
+ );
317555
+ }
317556
+ Logger.log("-------------------");
317557
+ })
317558
+ )
317559
+ );
317560
+ }
317561
+ });
317562
+
317563
+ // src/commands/runner/models.ts
317564
+ var models_exports = {};
317565
+ __export(models_exports, {
317566
+ default: () => models_default,
317567
+ parseSelection: () => parseSelection
317568
+ });
317569
+ var import_rxjs37, isShown, parseSelection, models_default;
317570
+ var init_models = __esm({
317571
+ "src/commands/runner/models.ts"() {
317572
+ import_rxjs37 = __toESM(require_cjs());
317573
+ init_gql_client();
317574
+ init_log();
317575
+ init_config();
317576
+ isShown = (runner, name2) => !Array.isArray(runner.enabledModels) || runner.enabledModels.includes(name2);
317577
+ parseSelection = (cmd) => {
317578
+ if ([cmd.show !== void 0, !!cmd.all, !!cmd.none].filter(Boolean).length > 1) {
317579
+ throw new Error("Use only one of --show, --all, --none.");
317580
+ }
317581
+ if (cmd.all) {
317582
+ return { models: null };
317583
+ }
317584
+ if (cmd.none) {
317585
+ return { models: [] };
317586
+ }
317587
+ if (cmd.show !== void 0) {
317588
+ return {
317589
+ models: cmd.show.split(",").map((m2) => m2.trim()).filter(Boolean)
317590
+ };
317591
+ }
317592
+ return null;
317593
+ };
317594
+ models_default = async (cmd) => {
317595
+ const selection = parseSelection(cmd);
317596
+ const runnerId = cmd.id || (await readSavedRunner())?.id;
317597
+ if (!runnerId) {
317598
+ throw new Error("Specify the runner with --id (see `gcli runner:list`).");
317599
+ }
317600
+ let runner;
317601
+ if (selection) {
317602
+ runner = await (0, import_rxjs37.lastValueFrom)(
317603
+ GraphqlClienAPI.setLocalRunnerModels(runnerId, selection.models)
317604
+ );
317605
+ } else {
317606
+ const runners = await (0, import_rxjs37.lastValueFrom)(GraphqlClienAPI.listLocalRunners());
317607
+ runner = runners.find((r2) => r2.id === runnerId);
317608
+ }
317609
+ if (!runner) {
317610
+ throw new Error(`Runner ${runnerId} not found.`);
317611
+ }
317612
+ const models = runner.models ?? [];
317613
+ const unknown2 = (selection?.models ?? []).filter(
317614
+ (m2) => !models.some((x2) => x2.name === m2)
317615
+ );
317616
+ if (unknown2.length) {
317617
+ Logger.warn(
317618
+ `Not reported by this runner (kept anyway, shown once Ollama has them): ${unknown2.join(", ")}`
317619
+ );
317620
+ }
317621
+ Logger.log(
317622
+ `[${runner.name}] shown in chat: ${models.filter((m2) => isShown(runner, m2.name)).length} of ${models.length}`
317623
+ );
317624
+ Logger.table(
317625
+ models.map((m2) => ({
317626
+ model: m2.name,
317627
+ shown: isShown(runner, m2.name),
317628
+ size: m2.parameterSize,
317629
+ tools: m2.capabilities?.includes("tools")
317630
+ }))
317631
+ );
317632
+ };
317633
+ }
317634
+ });
317635
+
317636
+ // src/commands/runner/delete.ts
317637
+ var delete_exports3 = {};
317638
+ __export(delete_exports3, {
317639
+ default: () => delete_default3
317640
+ });
317641
+ var import_rxjs38, delete_default3;
317642
+ var init_delete3 = __esm({
317643
+ "src/commands/runner/delete.ts"() {
317644
+ import_rxjs38 = __toESM(require_cjs());
317645
+ init_gql_client();
317646
+ init_log();
317647
+ init_config();
317648
+ delete_default3 = async (cmd) => {
317649
+ const saved = await readSavedRunner();
317650
+ const runnerId = cmd.id || saved?.id;
317651
+ if (!runnerId) {
317652
+ throw new Error("Specify the runner with --id (see `gcli runner:list`).");
317653
+ }
317654
+ await (0, import_rxjs38.lastValueFrom)(GraphqlClienAPI.deleteLocalRunner(runnerId));
317655
+ if (saved?.id === runnerId) {
317656
+ await forgetRunner();
317657
+ }
317658
+ Logger.log(`Local runner ${runnerId} deleted; its token no longer works.`);
317659
+ };
317660
+ }
317661
+ });
317662
+
317663
+ // src/commands/start/start.ts
317664
+ var start_exports3 = {};
317665
+ __export(start_exports3, {
316869
317666
  default: () => start
316870
317667
  });
316871
317668
  async function start(args) {
316872
317669
  Logger.log("---------------------------------");
316873
- return (0, import_rxjs35.lastValueFrom)(
317670
+ return (0, import_rxjs39.lastValueFrom)(
316874
317671
  loadSpec().pipe(
316875
- (0, import_operators34.switchMap)(
316876
- (config2) => (0, import_rxjs35.of)({
317672
+ (0, import_operators35.switchMap)(
317673
+ (config2) => (0, import_rxjs39.of)({
316877
317674
  watcher: (0, import_node_fs2.watch)(process.cwd(), {
316878
317675
  recursive: true
316879
317676
  }),
@@ -316894,7 +317691,7 @@ async function start(args) {
316894
317691
  outfile: args.outfile ?? config2?.options?.bundler?.outfile ?? "index.js",
316895
317692
  startCommand: "node"
316896
317693
  }).pipe(
316897
- (0, import_operators34.switchMap)(
317694
+ (0, import_operators35.switchMap)(
316898
317695
  ({
316899
317696
  child,
316900
317697
  watcher,
@@ -316902,14 +317699,14 @@ async function start(args) {
316902
317699
  outfile,
316903
317700
  startCommand,
316904
317701
  ignorelist
316905
- }) => (0, import_rxjs35.from)(build_default(args)).pipe(
316906
- (0, import_operators34.tap)(() => {
317702
+ }) => (0, import_rxjs39.from)(build_default(args)).pipe(
317703
+ (0, import_operators35.tap)(() => {
316907
317704
  Logger.warn(
316908
317705
  `\u{1F4E2} Starting script "${startCommand} ${outfile}"`
316909
317706
  );
316910
317707
  Logger.log("---------------------------------\n");
316911
317708
  }),
316912
- (0, import_operators34.tap)(() => {
317709
+ (0, import_operators35.tap)(() => {
316913
317710
  child = (0, import_node_child_process.spawn)(
316914
317711
  startCommand,
316915
317712
  ["--disable-warning=DEP0040", outfile],
@@ -316919,14 +317716,14 @@ async function start(args) {
316919
317716
  }
316920
317717
  );
316921
317718
  }),
316922
- (0, import_operators34.tap)(
316923
- () => (0, import_rxjs35.merge)(
316924
- (0, import_rxjs35.fromEvent)(process, "SIGINT"),
316925
- (0, import_rxjs35.fromEvent)(process, "SIGTERM"),
316926
- (0, import_rxjs35.fromEvent)(process, "exit")
317719
+ (0, import_operators35.tap)(
317720
+ () => (0, import_rxjs39.merge)(
317721
+ (0, import_rxjs39.fromEvent)(process, "SIGINT"),
317722
+ (0, import_rxjs39.fromEvent)(process, "SIGTERM"),
317723
+ (0, import_rxjs39.fromEvent)(process, "exit")
316927
317724
  ).pipe(
316928
- (0, import_operators34.debounceTime)(100),
316929
- (0, import_operators34.tap)(() => {
317725
+ (0, import_operators35.debounceTime)(100),
317726
+ (0, import_operators35.tap)(() => {
316930
317727
  Logger.warn("\u26A0\uFE0F Main process shutting down");
316931
317728
  watcher.close();
316932
317729
  child.kill("SIGTERM");
@@ -316934,13 +317731,13 @@ async function start(args) {
316934
317731
  })
316935
317732
  ).subscribe()
316936
317733
  ),
316937
- (0, import_operators34.switchMap)(
316938
- () => (0, import_rxjs35.fromEvent)(watcher, "change").pipe(
316939
- (0, import_operators34.map)(([event, filename]) => ({
317734
+ (0, import_operators35.switchMap)(
317735
+ () => (0, import_rxjs39.fromEvent)(watcher, "change").pipe(
317736
+ (0, import_operators35.map)(([event, filename]) => ({
316940
317737
  event,
316941
317738
  filename
316942
317739
  })),
316943
- (0, import_operators34.filter)(({ filename }) => {
317740
+ (0, import_operators35.filter)(({ filename }) => {
316944
317741
  if (!filename) {
316945
317742
  return false;
316946
317743
  }
@@ -316952,18 +317749,18 @@ async function start(args) {
316952
317749
  const rootDir = filename.split(/[/\\]/)[0];
316953
317750
  return whitelist.has(rootDir);
316954
317751
  }),
316955
- (0, import_operators34.debounceTime)(100)
317752
+ (0, import_operators35.debounceTime)(100)
316956
317753
  )
316957
317754
  ),
316958
- (0, import_operators34.tap)((data) => {
317755
+ (0, import_operators35.tap)((data) => {
316959
317756
  Logger.log("\n---------------------------------");
316960
317757
  Logger.log(
316961
317758
  `\u27F3 Restarting due to change in: ${data.filename}`
316962
317759
  );
316963
317760
  child?.kill("SIGTERM");
316964
317761
  }),
316965
- (0, import_operators34.switchMap)(() => build_default(args)),
316966
- (0, import_operators34.tap)(() => {
317762
+ (0, import_operators35.switchMap)(() => build_default(args)),
317763
+ (0, import_operators35.tap)(() => {
316967
317764
  Logger.warn(
316968
317765
  `\u{1F4E2} Starting script "${startCommand} ${outfile}"`
316969
317766
  );
@@ -316984,13 +317781,13 @@ async function start(args) {
316984
317781
  )
316985
317782
  );
316986
317783
  }
316987
- var import_node_child_process, import_node_fs2, import_rxjs35, import_operators34;
316988
- var init_start2 = __esm({
317784
+ var import_node_child_process, import_node_fs2, import_rxjs39, import_operators35;
317785
+ var init_start3 = __esm({
316989
317786
  "src/commands/start/start.ts"() {
316990
317787
  import_node_child_process = require("node:child_process");
316991
317788
  import_node_fs2 = require("node:fs");
316992
- import_rxjs35 = __toESM(require_cjs());
316993
- import_operators34 = __toESM(require_operators());
317789
+ import_rxjs39 = __toESM(require_cjs());
317790
+ import_operators35 = __toESM(require_operators());
316994
317791
  init_log();
316995
317792
  init_build();
316996
317793
  init_load_spec();
@@ -317002,25 +317799,25 @@ var create_cron_exports = {};
317002
317799
  __export(create_cron_exports, {
317003
317800
  default: () => create_cron_default
317004
317801
  });
317005
- var import_rxjs36, import_operators35, create_cron_default;
317802
+ var import_rxjs40, import_operators36, create_cron_default;
317006
317803
  var init_create_cron = __esm({
317007
317804
  "src/commands/triggers/cron/create-cron.ts"() {
317008
- import_rxjs36 = __toESM(require_cjs());
317009
- import_operators35 = __toESM(require_operators());
317805
+ import_rxjs40 = __toESM(require_cjs());
317806
+ import_operators36 = __toESM(require_operators());
317010
317807
  init_helpers();
317011
317808
  init_gql_client();
317012
317809
  init_log();
317013
317810
  init_load_spec();
317014
- create_cron_default = (cmd) => (0, import_rxjs36.lastValueFrom)(
317811
+ create_cron_default = (cmd) => (0, import_rxjs40.lastValueFrom)(
317015
317812
  parseProjectId(cmd.project).pipe(
317016
- (0, import_operators35.switchMap)(
317813
+ (0, import_operators36.switchMap)(
317017
317814
  (projectId) => loadSpec(cmd.spec ?? "cron.yaml").pipe(
317018
- (0, import_operators35.switchMap)(
317815
+ (0, import_operators36.switchMap)(
317019
317816
  (data) => GraphqlClienAPI.getLambdaByName(
317020
317817
  cmd?.lambdaName ?? data?.function?.name ?? data?.name,
317021
317818
  projectId
317022
317819
  ).pipe(
317023
- (0, import_operators35.map)((lambda) => ({
317820
+ (0, import_operators36.map)((lambda) => ({
317024
317821
  lambdaName: lambda.name,
317025
317822
  lambdaId: lambda.id,
317026
317823
  ...data?.triggers?.time ?? data
@@ -317029,12 +317826,12 @@ var init_create_cron = __esm({
317029
317826
  )
317030
317827
  )
317031
317828
  ),
317032
- (0, import_operators35.switchMap)(
317829
+ (0, import_operators36.switchMap)(
317033
317830
  ({ lambdaId, cron, triggerName, lambdaName }) => GraphqlClienAPI.createTimeTrigger({ lambdaId, cron, triggerName }).pipe(
317034
- (0, import_operators35.map)((data) => ({ ...data, lambdaName }))
317831
+ (0, import_operators36.map)((data) => ({ ...data, lambdaName }))
317035
317832
  )
317036
317833
  ),
317037
- (0, import_operators35.tap)((data) => {
317834
+ (0, import_operators36.tap)((data) => {
317038
317835
  const columns = [
317039
317836
  "id",
317040
317837
  "lambdaName",
@@ -317057,25 +317854,25 @@ var delete_cron_exports = {};
317057
317854
  __export(delete_cron_exports, {
317058
317855
  default: () => delete_cron_default
317059
317856
  });
317060
- var import_rxjs37, import_operators36, delete_cron_default;
317857
+ var import_rxjs41, import_operators37, delete_cron_default;
317061
317858
  var init_delete_cron = __esm({
317062
317859
  "src/commands/triggers/cron/delete-cron.ts"() {
317063
- import_rxjs37 = __toESM(require_cjs());
317064
- import_operators36 = __toESM(require_operators());
317860
+ import_rxjs41 = __toESM(require_cjs());
317861
+ import_operators37 = __toESM(require_operators());
317065
317862
  init_helpers();
317066
317863
  init_gql_client();
317067
317864
  init_log();
317068
317865
  init_load_spec();
317069
- delete_cron_default = (cmd) => (0, import_rxjs37.lastValueFrom)(
317866
+ delete_cron_default = (cmd) => (0, import_rxjs41.lastValueFrom)(
317070
317867
  parseProjectId(cmd.project).pipe(
317071
- (0, import_operators36.switchMap)(
317868
+ (0, import_operators37.switchMap)(
317072
317869
  (projectId) => loadSpec(cmd.spec ?? "cron.yaml").pipe(
317073
- (0, import_operators36.switchMap)(
317870
+ (0, import_operators37.switchMap)(
317074
317871
  (data) => GraphqlClienAPI.getLambdaByName(
317075
317872
  cmd?.lambdaName ?? data?.function?.name ?? data?.name,
317076
317873
  projectId
317077
317874
  ).pipe(
317078
- (0, import_operators36.map)((lambda) => ({
317875
+ (0, import_operators37.map)((lambda) => ({
317079
317876
  lambdaName: lambda.name,
317080
317877
  lambdaId: lambda.id
317081
317878
  }))
@@ -317083,12 +317880,12 @@ var init_delete_cron = __esm({
317083
317880
  )
317084
317881
  )
317085
317882
  ),
317086
- (0, import_operators36.switchMap)(
317883
+ (0, import_operators37.switchMap)(
317087
317884
  ({ lambdaId, lambdaName }) => GraphqlClienAPI.deleteLambdaTimeTrigger(lambdaId).pipe(
317088
- (0, import_operators36.map)((data) => ({ ...data, lambdaName }))
317885
+ (0, import_operators37.map)((data) => ({ ...data, lambdaName }))
317089
317886
  )
317090
317887
  ),
317091
- (0, import_operators36.tap)((data) => {
317888
+ (0, import_operators37.tap)((data) => {
317092
317889
  const columns = [
317093
317890
  "id",
317094
317891
  "lambdaName",
@@ -317110,29 +317907,29 @@ var list_crons_exports = {};
317110
317907
  __export(list_crons_exports, {
317111
317908
  default: () => list_crons_default
317112
317909
  });
317113
- var import_rxjs38, import_operators37, list_crons_default;
317910
+ var import_rxjs42, import_operators38, list_crons_default;
317114
317911
  var init_list_crons = __esm({
317115
317912
  "src/commands/triggers/cron/list-crons.ts"() {
317116
- import_rxjs38 = __toESM(require_cjs());
317117
- import_operators37 = __toESM(require_operators());
317913
+ import_rxjs42 = __toESM(require_cjs());
317914
+ import_operators38 = __toESM(require_operators());
317118
317915
  init_helpers();
317119
317916
  init_gql_client();
317120
317917
  init_log();
317121
- list_crons_default = (cmd) => (0, import_rxjs38.lastValueFrom)(
317918
+ list_crons_default = (cmd) => (0, import_rxjs42.lastValueFrom)(
317122
317919
  parseProjectId(cmd.project).pipe(
317123
- (0, import_operators37.switchMap)(
317124
- (projectId) => (0, import_rxjs38.combineLatest)([
317920
+ (0, import_operators38.switchMap)(
317921
+ (projectId) => (0, import_rxjs42.combineLatest)([
317125
317922
  GraphqlClienAPI.listProjectTimeTriggers(projectId),
317126
317923
  GraphqlClienAPI.listLambdas(projectId)
317127
317924
  ])
317128
317925
  ),
317129
- (0, import_operators37.map)(
317926
+ (0, import_operators38.map)(
317130
317927
  ([triggers, lambdas]) => triggers.map((v) => ({
317131
317928
  lambdaName: lambdas.find((l) => l.id === v.lambdaId)?.name,
317132
317929
  ...v
317133
317930
  }))
317134
317931
  ),
317135
- (0, import_operators37.tap)((data) => {
317932
+ (0, import_operators38.tap)((data) => {
317136
317933
  const columns = [
317137
317934
  "id",
317138
317935
  "triggerName",
@@ -317447,6 +318244,37 @@ function registerRabbitMqCommands(program2) {
317447
318244
  program2.command("rabbitmq:delete").description("Delete a RabbitMQ broker").option("-p, --project <project>").option("--id <id>", "Broker id (see rabbitmq:list)").action(lazy(() => Promise.resolve().then(() => (init_delete2(), delete_exports2)).then((m2) => m2.default)));
317448
318245
  }
317449
318246
 
318247
+ // src/commands/runner/index.ts
318248
+ init_helpers();
318249
+ function registerRunnerCommands(program2) {
318250
+ program2.command("runner:start").description(
318251
+ "Connect this machine's Ollama to the Lambforge chat as a local AI runner (outbound connection only - works behind NAT, Ollama is never exposed)"
318252
+ ).option(
318253
+ "-n, --name <name>",
318254
+ "Runner name shown in the chat model picker (default: hostname)"
318255
+ ).option(
318256
+ "-t, --token <token>",
318257
+ "Runner token from Profile -> Local AI runners (instead of `gcli login`)"
318258
+ ).option(
318259
+ "--ollama <url>",
318260
+ "Ollama URL (default: $OLLAMA_HOST or http://127.0.0.1:11434)"
318261
+ ).option("--wsUrl <url>", "Lambforge subscriptions endpoint override").option("--reset", "Forget the saved runner and register a new one").action(lazy(() => Promise.resolve().then(() => (init_start2(), start_exports2)).then((m2) => m2.default)));
318262
+ program2.command("runner:list").description("List your local AI runners and the models they serve").action(lazy(() => Promise.resolve().then(() => (init_list6(), list_exports6)).then((m2) => m2.default)));
318263
+ program2.command("runner:models").description(
318264
+ "Choose which of a runner's models appear in the chat model picker (no flags: list them)"
318265
+ ).option(
318266
+ "--id <id>",
318267
+ "Runner id (default: the runner saved on this machine)"
318268
+ ).option(
318269
+ "--show <models>",
318270
+ "Comma-separated models to show (hides the rest)"
318271
+ ).option("--all", "Show every model again").option("--none", "Hide all models of this runner from the chat").action(lazy(() => Promise.resolve().then(() => (init_models(), models_exports)).then((m2) => m2.default)));
318272
+ program2.command("runner:delete").description("Delete a local AI runner and revoke its token").option(
318273
+ "--id <id>",
318274
+ "Runner id (default: the runner saved on this machine)"
318275
+ ).action(lazy(() => Promise.resolve().then(() => (init_delete3(), delete_exports3)).then((m2) => m2.default)));
318276
+ }
318277
+
317450
318278
  // src/commands/start/index.ts
317451
318279
  init_helpers();
317452
318280
  function startCommands(program2) {
@@ -317456,7 +318284,7 @@ function startCommands(program2) {
317456
318284
  ).option("-b, --bundle", "Bundle code", true).option("-m, --minify", "Minify code", false).option("-p, --platform <char>", "Platform ", "node").option("-t, --target <char>", "Target ", "node14.4").option("-o, --outfile <char>", "Outfile name").option(
317457
318285
  "-i, --ignore <ignore...>",
317458
318286
  "Ignore folders from triggering restarts"
317459
- ).option("-e, --external <external...>", "External libraries").action(lazy(() => Promise.resolve().then(() => (init_start2(), start_exports2)).then((m2) => m2.default)));
318287
+ ).option("-e, --external <external...>", "External libraries").action(lazy(() => Promise.resolve().then(() => (init_start3(), start_exports3)).then((m2) => m2.default)));
317460
318288
  }
317461
318289
 
317462
318290
  // src/commands/triggers/cron/index.ts
@@ -317479,7 +318307,8 @@ var commands = [
317479
318307
  registerCronTriggerCommands,
317480
318308
  registerClusterCommands,
317481
318309
  registerRabbitMqCommands,
317482
- registerPluginCommands
318310
+ registerPluginCommands,
318311
+ registerRunnerCommands
317483
318312
  ];
317484
318313
 
317485
318314
  // src/main.ts