@larkup/cli 0.2.15 → 0.2.17
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/README.md +1 -1
- package/dist/{chunk-UCYL66UI.js → chunk-7HVIRRTX.js} +2 -3
- package/dist/{chunk-C37WLM2M.js → chunk-STUKQORW.js} +9 -6
- package/dist/index.js +67 -21
- package/dist/{tool-loader-KJILSS2J.js → tool-loader-K33ISDZP.js} +2 -2
- package/dist/{tool-registry-ED45DB5F.js → tool-registry-XQVQ6KQF.js} +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -40,4 +40,4 @@ larkup media ./demo.mp4
|
|
|
40
40
|
- `larkup open [target]` opens the Web UI or API reference.
|
|
41
41
|
- `larkup update` checks for and installs CLI releases.
|
|
42
42
|
|
|
43
|
-
Generated servers use `http://localhost:8080` by default. Run `larkup --help` or see the [CLI documentation](https://larkup.de/docs/developer/cli) for all options.
|
|
43
|
+
Generated servers use `http://localhost:8080` by default. Run `larkup --help` or see the [CLI documentation](https://www.larkup.de/docs/developer/cli) for all options.
|
|
@@ -90,13 +90,12 @@ var FALLBACK_REGISTRY = {
|
|
|
90
90
|
name: "Video & Audio",
|
|
91
91
|
description: "Index video and audio files with transcription and frame analysis.",
|
|
92
92
|
category: "media",
|
|
93
|
-
version: "0.
|
|
93
|
+
version: "0.3.1",
|
|
94
94
|
pricing: "free",
|
|
95
95
|
emoji: "\u{1F3AC}",
|
|
96
96
|
icon: "Film",
|
|
97
97
|
packageName: "@larkup/tool-video-audio",
|
|
98
98
|
installSize: "~15 MB",
|
|
99
|
-
systemDeps: ["ffmpeg"],
|
|
100
99
|
author: "Larkup",
|
|
101
100
|
capabilities: [
|
|
102
101
|
"video-indexing",
|
|
@@ -136,7 +135,7 @@ var FALLBACK_REGISTRY = {
|
|
|
136
135
|
label: "Transcription language",
|
|
137
136
|
type: "text",
|
|
138
137
|
defaultValue: "auto",
|
|
139
|
-
help: "Use auto
|
|
138
|
+
help: "Use auto for provider language detection, or enter a language code such as ar, ar-EG, en, or de to override it."
|
|
140
139
|
},
|
|
141
140
|
{
|
|
142
141
|
key: "audioApiKey",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getToolById,
|
|
3
3
|
invalidateRegistryCache
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7HVIRRTX.js";
|
|
5
5
|
import {
|
|
6
6
|
__require
|
|
7
7
|
} from "./chunk-3RG5ZIWI.js";
|
|
@@ -112,10 +112,13 @@ async function tryAutoInstallDep(dep, onProgress) {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
if (!installCmd) return false;
|
|
115
|
-
onProgress?.(`Auto-installing ${dep}\u2026`);
|
|
115
|
+
onProgress?.(`Auto-installing ${dep} via "${installCmd}"\u2026`);
|
|
116
116
|
try {
|
|
117
|
-
await execAsync(installCmd, { timeout:
|
|
118
|
-
|
|
117
|
+
await execAsync(installCmd, { timeout: 3e5 });
|
|
118
|
+
onProgress?.(`${dep} installation command finished.`);
|
|
119
|
+
} catch (err) {
|
|
120
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
121
|
+
onProgress?.(`Auto-install of ${dep} failed: ${message}`);
|
|
119
122
|
return false;
|
|
120
123
|
}
|
|
121
124
|
try {
|
|
@@ -411,7 +414,7 @@ async function uninstallTool(toolId) {
|
|
|
411
414
|
}
|
|
412
415
|
}
|
|
413
416
|
invalidateRegistryCache();
|
|
414
|
-
const { unloadTool: unloadTool2 } = await import("./tool-loader-
|
|
417
|
+
const { unloadTool: unloadTool2 } = await import("./tool-loader-K33ISDZP.js");
|
|
415
418
|
unloadTool2(toolId);
|
|
416
419
|
}
|
|
417
420
|
async function notifyHubInstall(toolId) {
|
|
@@ -482,7 +485,7 @@ function unloadTool(toolId) {
|
|
|
482
485
|
moduleCache.delete(toolId);
|
|
483
486
|
}
|
|
484
487
|
async function hasCapability(capability) {
|
|
485
|
-
const { getToolsWithCapability } = await import("./tool-registry-
|
|
488
|
+
const { getToolsWithCapability } = await import("./tool-registry-XQVQ6KQF.js");
|
|
486
489
|
const tools = await getToolsWithCapability(capability);
|
|
487
490
|
for (const t of tools) {
|
|
488
491
|
const installed = await getInstalledTool(t.id);
|
package/dist/index.js
CHANGED
|
@@ -19,11 +19,11 @@ import {
|
|
|
19
19
|
isToolInstalled,
|
|
20
20
|
loadTool,
|
|
21
21
|
uninstallTool
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-STUKQORW.js";
|
|
23
23
|
import {
|
|
24
24
|
getAllTools,
|
|
25
25
|
getToolById
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-7HVIRRTX.js";
|
|
27
27
|
import {
|
|
28
28
|
__require
|
|
29
29
|
} from "./chunk-3RG5ZIWI.js";
|
|
@@ -34,7 +34,7 @@ import { Command } from "commander";
|
|
|
34
34
|
// package.json
|
|
35
35
|
var package_default = {
|
|
36
36
|
name: "@larkup/cli",
|
|
37
|
-
version: "0.2.
|
|
37
|
+
version: "0.2.17",
|
|
38
38
|
publishConfig: {
|
|
39
39
|
access: "public"
|
|
40
40
|
},
|
|
@@ -141,7 +141,7 @@ var prompts = {
|
|
|
141
141
|
};
|
|
142
142
|
|
|
143
143
|
// src/updater.ts
|
|
144
|
-
var VERSION_CHECK_URL = "https://larkup.de/api/version";
|
|
144
|
+
var VERSION_CHECK_URL = "https://www.larkup.de/api/version";
|
|
145
145
|
function compareVersions(a, b) {
|
|
146
146
|
const pa = a.replace(/^v/, "").split(".").map(Number);
|
|
147
147
|
const pb = b.replace(/^v/, "").split(".").map(Number);
|
|
@@ -4341,6 +4341,24 @@ async function createAdapter(config, onRateLimit) {
|
|
|
4341
4341
|
|
|
4342
4342
|
// ../../packages/core/src/indexing/indexer.ts
|
|
4343
4343
|
var EMBED_BATCH = 64;
|
|
4344
|
+
var MAX_RATE_LIMIT_RETRIES = 5;
|
|
4345
|
+
function isRateLimitError(error) {
|
|
4346
|
+
const candidate = error;
|
|
4347
|
+
const message = String(candidate?.message ?? error ?? "").toLowerCase();
|
|
4348
|
+
return candidate?.status === 429 || candidate?.statusCode === 429 || /\b429\b|rate[ -]?limit|too many requests|resource_exhausted|quota exceeded|quota.*exceed/.test(
|
|
4349
|
+
message
|
|
4350
|
+
);
|
|
4351
|
+
}
|
|
4352
|
+
function rateLimitDelayMs(error, attempt) {
|
|
4353
|
+
const message = String(error?.message ?? error ?? "");
|
|
4354
|
+
const retryMatch = message.match(
|
|
4355
|
+
/(?:retry(?:\s+after|\s+in)?|try again(?:\s+in)?)\s*(\d+(?:\.\d+)?)\s*(?:s|sec(?:ond)?s?)/i
|
|
4356
|
+
);
|
|
4357
|
+
if (retryMatch) {
|
|
4358
|
+
return Math.min(12e4, Math.max(2e3, Math.ceil(Number(retryMatch[1]) * 1e3)));
|
|
4359
|
+
}
|
|
4360
|
+
return Math.min(6e4, 5e3 * 2 ** (attempt - 1));
|
|
4361
|
+
}
|
|
4344
4362
|
async function createRun(config) {
|
|
4345
4363
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4346
4364
|
const run = {
|
|
@@ -4367,7 +4385,7 @@ async function runIndexer(runId, config, previousRun = null) {
|
|
|
4367
4385
|
};
|
|
4368
4386
|
try {
|
|
4369
4387
|
let docs = await readDocuments();
|
|
4370
|
-
if (previousRun
|
|
4388
|
+
if (previousRun) {
|
|
4371
4389
|
docs = docs.filter((document) => document.status !== "indexed");
|
|
4372
4390
|
}
|
|
4373
4391
|
if (docs.length === 0) {
|
|
@@ -4406,6 +4424,12 @@ async function runIndexer(runId, config, previousRun = null) {
|
|
|
4406
4424
|
return;
|
|
4407
4425
|
}
|
|
4408
4426
|
await patchRun2({ totalChunks: chunks.length, status: "embedding" });
|
|
4427
|
+
const chunksPerDocument = /* @__PURE__ */ new Map();
|
|
4428
|
+
const processedPerDocument = /* @__PURE__ */ new Map();
|
|
4429
|
+
const indexedDocumentIds = /* @__PURE__ */ new Set();
|
|
4430
|
+
for (const chunk of chunks) {
|
|
4431
|
+
chunksPerDocument.set(chunk.documentId, (chunksPerDocument.get(chunk.documentId) ?? 0) + 1);
|
|
4432
|
+
}
|
|
4409
4433
|
const adapter = await createAdapter(config, async (waitSecs, attempt) => {
|
|
4410
4434
|
await patchRun2({
|
|
4411
4435
|
warning: `Sparse model rate-limited \u2014 pausing ${waitSecs}s (retry ${attempt}/${3})\u2026`
|
|
@@ -4434,13 +4458,13 @@ async function runIndexer(runId, config, previousRun = null) {
|
|
|
4434
4458
|
if (dim) batchDimensions = dim;
|
|
4435
4459
|
break;
|
|
4436
4460
|
} catch (err) {
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
const waitSecs =
|
|
4461
|
+
if (isRateLimitError(err) && attempt <= MAX_RATE_LIMIT_RETRIES) {
|
|
4462
|
+
const waitMs = rateLimitDelayMs(err, attempt);
|
|
4463
|
+
const waitSecs = Math.ceil(waitMs / 1e3);
|
|
4440
4464
|
await patchRun2({
|
|
4441
|
-
warning: `
|
|
4465
|
+
warning: `Embedding provider quota reached \u2014 pausing ${waitSecs}s (retry ${attempt}/${MAX_RATE_LIMIT_RETRIES})\u2026`
|
|
4442
4466
|
});
|
|
4443
|
-
await new Promise((r) => setTimeout(r,
|
|
4467
|
+
await new Promise((r) => setTimeout(r, waitMs));
|
|
4444
4468
|
currentDelayMs = Math.max(currentDelayMs, 2e3);
|
|
4445
4469
|
attempt++;
|
|
4446
4470
|
} else {
|
|
@@ -4453,6 +4477,10 @@ async function runIndexer(runId, config, previousRun = null) {
|
|
|
4453
4477
|
await adapter.init(dimensions);
|
|
4454
4478
|
if (!previousRun) {
|
|
4455
4479
|
await adapter.reset();
|
|
4480
|
+
await updateDocumentsStatus(
|
|
4481
|
+
docs.map((document) => document.id),
|
|
4482
|
+
"unindexed"
|
|
4483
|
+
);
|
|
4456
4484
|
}
|
|
4457
4485
|
initialized = true;
|
|
4458
4486
|
await patchRun2({ dimensions });
|
|
@@ -4475,13 +4503,13 @@ async function runIndexer(runId, config, previousRun = null) {
|
|
|
4475
4503
|
await adapter.upsert(records);
|
|
4476
4504
|
break;
|
|
4477
4505
|
} catch (err) {
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
const waitSecs =
|
|
4506
|
+
if (isRateLimitError(err) && upsertAttempt <= MAX_RATE_LIMIT_RETRIES) {
|
|
4507
|
+
const waitMs = rateLimitDelayMs(err, upsertAttempt);
|
|
4508
|
+
const waitSecs = Math.ceil(waitMs / 1e3);
|
|
4481
4509
|
await patchRun2({
|
|
4482
|
-
warning: `Vector store rate-limited \u2014 pausing ${waitSecs}s (retry ${upsertAttempt}/${
|
|
4510
|
+
warning: `Vector store rate-limited \u2014 pausing ${waitSecs}s (retry ${upsertAttempt}/${MAX_RATE_LIMIT_RETRIES})\u2026`
|
|
4483
4511
|
});
|
|
4484
|
-
await new Promise((r) => setTimeout(r,
|
|
4512
|
+
await new Promise((r) => setTimeout(r, waitMs));
|
|
4485
4513
|
currentDelayMs = Math.max(currentDelayMs, 2e3);
|
|
4486
4514
|
upsertAttempt++;
|
|
4487
4515
|
} else {
|
|
@@ -4490,7 +4518,24 @@ async function runIndexer(runId, config, previousRun = null) {
|
|
|
4490
4518
|
}
|
|
4491
4519
|
}
|
|
4492
4520
|
processed += batch.length;
|
|
4493
|
-
|
|
4521
|
+
const completedDocumentIds = [];
|
|
4522
|
+
for (const chunk of batch) {
|
|
4523
|
+
const completed = (processedPerDocument.get(chunk.documentId) ?? 0) + 1;
|
|
4524
|
+
processedPerDocument.set(chunk.documentId, completed);
|
|
4525
|
+
if (completed === chunksPerDocument.get(chunk.documentId) && !indexedDocumentIds.has(chunk.documentId)) {
|
|
4526
|
+
indexedDocumentIds.add(chunk.documentId);
|
|
4527
|
+
completedDocumentIds.push(chunk.documentId);
|
|
4528
|
+
}
|
|
4529
|
+
}
|
|
4530
|
+
if (completedDocumentIds.length > 0) {
|
|
4531
|
+
await updateDocumentsStatus(completedDocumentIds, "indexed");
|
|
4532
|
+
}
|
|
4533
|
+
await patchRun2({
|
|
4534
|
+
processedChunks: processed,
|
|
4535
|
+
indexedDocumentCount: indexedDocumentIds.size,
|
|
4536
|
+
status: "embedding",
|
|
4537
|
+
warning: void 0
|
|
4538
|
+
});
|
|
4494
4539
|
}
|
|
4495
4540
|
await patchRun2({
|
|
4496
4541
|
status: "completed",
|
|
@@ -4499,16 +4544,17 @@ async function runIndexer(runId, config, previousRun = null) {
|
|
|
4499
4544
|
finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4500
4545
|
durationMs: Date.now() - started
|
|
4501
4546
|
});
|
|
4502
|
-
await updateDocumentsStatus(
|
|
4503
|
-
docs.map((d) => d.id),
|
|
4504
|
-
"indexed"
|
|
4505
|
-
);
|
|
4506
4547
|
} catch (err) {
|
|
4507
|
-
const
|
|
4548
|
+
const rawMessage = err instanceof Error ? err.message : "Indexing failed unexpectedly.";
|
|
4549
|
+
const completed = await readDocuments().then(
|
|
4550
|
+
(documents) => documents.filter((document) => document.status === "indexed").length
|
|
4551
|
+
);
|
|
4552
|
+
const message = isRateLimitError(err) ? `Embedding quota is still unavailable. ${completed} document${completed === 1 ? "" : "s"} remain indexed; retry the unindexed files when your provider quota resets. ${rawMessage}` : rawMessage;
|
|
4508
4553
|
await patchRun(
|
|
4509
4554
|
{
|
|
4510
4555
|
status: "failed",
|
|
4511
4556
|
error: message,
|
|
4557
|
+
indexedDocumentCount: completed,
|
|
4512
4558
|
finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4513
4559
|
durationMs: Date.now() - started
|
|
4514
4560
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@larkup/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.17",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
"cli-table3": "^0.6.5",
|
|
30
30
|
"commander": "^15.0.0",
|
|
31
31
|
"zod": "^4.4.3",
|
|
32
|
-
"@larkup/
|
|
33
|
-
"@larkup/
|
|
34
|
-
"@larkup/
|
|
32
|
+
"@larkup/core": "0.3.2",
|
|
33
|
+
"@larkup/vector-stores": "0.1.24",
|
|
34
|
+
"@larkup/marketplace": "0.1.17"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"tsup": "^8.0.0",
|