chainlesschain 0.81.0 → 0.143.0
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/bin/chainlesschain.js +0 -0
- package/package.json +1 -1
- package/src/commands/a2a.js +62 -0
- package/src/commands/activitypub.js +61 -0
- package/src/commands/agent-network.js +254 -1
- package/src/commands/agent.js +117 -0
- package/src/commands/audit.js +302 -0
- package/src/commands/automation.js +271 -1
- package/src/commands/bi.js +61 -0
- package/src/commands/bm25.js +78 -0
- package/src/commands/browse.js +64 -0
- package/src/commands/ccron.js +78 -0
- package/src/commands/codegen.js +224 -0
- package/src/commands/collab.js +341 -0
- package/src/commands/compliance.js +1075 -0
- package/src/commands/compt.js +78 -0
- package/src/commands/consol.js +231 -0
- package/src/commands/cowork.js +263 -0
- package/src/commands/crosschain.js +62 -0
- package/src/commands/dao.js +62 -0
- package/src/commands/dbevo.js +284 -0
- package/src/commands/dev.js +252 -0
- package/src/commands/did.js +358 -0
- package/src/commands/dlp.js +61 -0
- package/src/commands/economy.js +56 -0
- package/src/commands/encrypt.js +341 -0
- package/src/commands/evolution.js +56 -0
- package/src/commands/evomap.js +61 -0
- package/src/commands/export.js +256 -1
- package/src/commands/fflag.js +178 -0
- package/src/commands/fusion.js +258 -0
- package/src/commands/git.js +45 -0
- package/src/commands/governance.js +325 -0
- package/src/commands/hardening.js +411 -0
- package/src/commands/hmemory.js +56 -0
- package/src/commands/hook.js +148 -0
- package/src/commands/import.js +252 -0
- package/src/commands/incentive.js +322 -0
- package/src/commands/inference.js +42 -0
- package/src/commands/infra.js +244 -0
- package/src/commands/instinct.js +260 -0
- package/src/commands/ipfs.js +318 -0
- package/src/commands/itbudget.js +45 -0
- package/src/commands/kg.js +387 -0
- package/src/commands/llm.js +263 -0
- package/src/commands/lowcode.js +44 -0
- package/src/commands/matrix.js +62 -0
- package/src/commands/mcp.js +221 -0
- package/src/commands/mcpscaf.js +41 -0
- package/src/commands/meminj.js +41 -0
- package/src/commands/memory.js +248 -0
- package/src/commands/multimodal.js +296 -0
- package/src/commands/nlprog.js +356 -0
- package/src/commands/nostr.js +62 -0
- package/src/commands/note.js +244 -0
- package/src/commands/ops.js +354 -0
- package/src/commands/orchestrate.js +166 -0
- package/src/commands/orchgov.js +45 -0
- package/src/commands/org.js +277 -0
- package/src/commands/p2p.js +390 -0
- package/src/commands/pdfp.js +78 -0
- package/src/commands/perception.js +290 -0
- package/src/commands/perf.js +39 -0
- package/src/commands/perm.js +45 -0
- package/src/commands/permmem.js +251 -0
- package/src/commands/pipeline.js +57 -1
- package/src/commands/planmode.js +45 -0
- package/src/commands/plugin-ecosystem.js +273 -0
- package/src/commands/pqc.js +393 -0
- package/src/commands/promcomp.js +82 -0
- package/src/commands/quantization.js +351 -0
- package/src/commands/rcache.js +271 -0
- package/src/commands/recommend.js +382 -0
- package/src/commands/runtime.js +307 -0
- package/src/commands/scim.js +262 -0
- package/src/commands/seshhook.js +41 -0
- package/src/commands/seshsearch.js +41 -0
- package/src/commands/seshtail.js +41 -0
- package/src/commands/seshu.js +41 -0
- package/src/commands/session.js +258 -0
- package/src/commands/sganal.js +78 -0
- package/src/commands/siem.js +40 -0
- package/src/commands/skill.js +267 -1
- package/src/commands/slotfill.js +41 -0
- package/src/commands/social.js +290 -0
- package/src/commands/sso.js +186 -1
- package/src/commands/svccont.js +45 -0
- package/src/commands/sync.js +256 -0
- package/src/commands/tech.js +338 -0
- package/src/commands/tenant.js +351 -0
- package/src/commands/tms.js +45 -0
- package/src/commands/tokens.js +269 -0
- package/src/commands/topiccls.js +45 -0
- package/src/commands/trust.js +249 -0
- package/src/commands/uprof.js +45 -0
- package/src/commands/vcheck.js +78 -0
- package/src/commands/wallet.js +277 -0
- package/src/commands/webfetch.js +41 -0
- package/src/commands/workflow.js +171 -0
- package/src/commands/zkp.js +62 -0
- package/src/harness/prompt-compressor.js +331 -0
- package/src/index.js +65 -1
- package/src/lib/a2a-protocol.js +105 -0
- package/src/lib/activitypub-bridge.js +105 -0
- package/src/lib/agent-coordinator.js +325 -0
- package/src/lib/agent-economy.js +105 -0
- package/src/lib/agent-network.js +387 -0
- package/src/lib/agent-router.js +395 -0
- package/src/lib/aiops.js +478 -0
- package/src/lib/app-builder.js +105 -0
- package/src/lib/audit-logger.js +379 -0
- package/src/lib/automation-engine.js +330 -0
- package/src/lib/autonomous-agent.js +105 -0
- package/src/lib/autonomous-developer.js +350 -0
- package/src/lib/bi-engine.js +105 -0
- package/src/lib/bm25-search.js +81 -0
- package/src/lib/browser-automation.js +105 -0
- package/src/lib/code-agent.js +323 -0
- package/src/lib/collaboration-governance.js +364 -0
- package/src/lib/community-governance.js +436 -0
- package/src/lib/compliance-framework-reporter.js +105 -0
- package/src/lib/compliance-manager.js +434 -0
- package/src/lib/compression-telemetry.js +81 -0
- package/src/lib/content-recommendation.js +469 -0
- package/src/lib/content-recommender.js +105 -0
- package/src/lib/cowork-cron.js +81 -0
- package/src/lib/cowork-task-runner.js +105 -0
- package/src/lib/cross-chain.js +105 -0
- package/src/lib/crypto-manager.js +350 -0
- package/src/lib/dao-governance.js +105 -0
- package/src/lib/dbevo.js +338 -0
- package/src/lib/decentral-infra.js +340 -0
- package/src/lib/did-manager.js +367 -0
- package/src/lib/dlp-engine.js +105 -0
- package/src/lib/evolution-system.js +105 -0
- package/src/lib/evomap-manager.js +105 -0
- package/src/lib/execution-backend.js +105 -0
- package/src/lib/feature-flags.js +85 -0
- package/src/lib/git-integration.js +105 -0
- package/src/lib/hardening-manager.js +348 -0
- package/src/lib/hierarchical-memory.js +105 -0
- package/src/lib/hook-manager.js +380 -0
- package/src/lib/inference-network.js +105 -0
- package/src/lib/instinct-manager.js +332 -0
- package/src/lib/ipfs-storage.js +334 -0
- package/src/lib/iteration-budget.js +105 -0
- package/src/lib/knowledge-exporter.js +381 -0
- package/src/lib/knowledge-graph.js +432 -0
- package/src/lib/knowledge-importer.js +379 -0
- package/src/lib/llm-providers.js +391 -0
- package/src/lib/matrix-bridge.js +105 -0
- package/src/lib/mcp-registry.js +333 -0
- package/src/lib/mcp-scaffold.js +81 -0
- package/src/lib/memory-injection.js +81 -0
- package/src/lib/memory-manager.js +330 -0
- package/src/lib/multimodal.js +346 -0
- package/src/lib/nl-programming.js +343 -0
- package/src/lib/nostr-bridge.js +105 -0
- package/src/lib/note-versioning.js +327 -0
- package/src/lib/orchestrator.js +105 -0
- package/src/lib/org-manager.js +323 -0
- package/src/lib/p2p-manager.js +387 -0
- package/src/lib/pdf-parser.js +81 -0
- package/src/lib/perception.js +346 -0
- package/src/lib/perf-tuning.js +109 -1
- package/src/lib/permanent-memory.js +320 -0
- package/src/lib/permission-engine.js +81 -0
- package/src/lib/pipeline-orchestrator.js +105 -0
- package/src/lib/plan-mode.js +81 -0
- package/src/lib/plugin-ecosystem.js +377 -0
- package/src/lib/pqc-manager.js +368 -0
- package/src/lib/prompt-compressor.js +1 -10
- package/src/lib/protocol-fusion.js +417 -0
- package/src/lib/quantization.js +325 -0
- package/src/lib/response-cache.js +327 -0
- package/src/lib/scim-manager.js +329 -0
- package/src/lib/service-container.js +81 -0
- package/src/lib/session-consolidator.js +105 -0
- package/src/lib/session-hooks.js +81 -0
- package/src/lib/session-manager.js +329 -0
- package/src/lib/session-search.js +81 -0
- package/src/lib/session-tail.js +81 -0
- package/src/lib/session-usage.js +83 -0
- package/src/lib/siem-exporter.js +105 -0
- package/src/lib/skill-loader.js +377 -0
- package/src/lib/slot-filler.js +81 -0
- package/src/lib/social-graph-analytics.js +81 -0
- package/src/lib/social-graph.js +81 -0
- package/src/lib/social-manager.js +326 -0
- package/src/lib/sso-manager.js +332 -0
- package/src/lib/sub-agent-registry.js +110 -0
- package/src/lib/sync-manager.js +326 -0
- package/src/lib/task-model-selector.js +81 -0
- package/src/lib/tech-learning-engine.js +369 -0
- package/src/lib/tenant-saas.js +460 -0
- package/src/lib/threat-intel.js +335 -0
- package/src/lib/todo-manager.js +105 -0
- package/src/lib/token-incentive.js +293 -0
- package/src/lib/token-tracker.js +329 -0
- package/src/lib/topic-classifier.js +105 -0
- package/src/lib/trust-security.js +390 -0
- package/src/lib/ueba.js +389 -0
- package/src/lib/universal-runtime.js +325 -0
- package/src/lib/user-profile.js +81 -0
- package/src/lib/version-checker.js +81 -0
- package/src/lib/wallet-manager.js +326 -0
- package/src/lib/web-fetch.js +81 -0
- package/src/lib/workflow-engine.js +322 -0
- package/src/lib/zkp-engine.js +105 -0
package/src/lib/quantization.js
CHANGED
|
@@ -360,3 +360,328 @@ export function getQuantizationStats(db) {
|
|
|
360
360
|
export function _resetState() {
|
|
361
361
|
_jobs.clear();
|
|
362
362
|
}
|
|
363
|
+
|
|
364
|
+
/* ═════════════════════════════════════════════════════════ *
|
|
365
|
+
* Phase 20 V2 — Model Maturity + Job Ticket Lifecycle
|
|
366
|
+
* ═════════════════════════════════════════════════════════ */
|
|
367
|
+
|
|
368
|
+
export const MODEL_MATURITY_V2 = Object.freeze({
|
|
369
|
+
ONBOARDING: "onboarding",
|
|
370
|
+
ACTIVE: "active",
|
|
371
|
+
DEPRECATED: "deprecated",
|
|
372
|
+
RETIRED: "retired",
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
export const JOB_TICKET_V2 = Object.freeze({
|
|
376
|
+
QUEUED: "queued",
|
|
377
|
+
RUNNING: "running",
|
|
378
|
+
COMPLETED: "completed",
|
|
379
|
+
FAILED: "failed",
|
|
380
|
+
CANCELED: "canceled",
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
const MODEL_TRANSITIONS_V2 = new Map([
|
|
384
|
+
["onboarding", new Set(["active", "retired"])],
|
|
385
|
+
["active", new Set(["deprecated", "retired"])],
|
|
386
|
+
["deprecated", new Set(["active", "retired"])],
|
|
387
|
+
]);
|
|
388
|
+
const MODEL_TERMINALS_V2 = new Set(["retired"]);
|
|
389
|
+
|
|
390
|
+
const JOB_TRANSITIONS_V2 = new Map([
|
|
391
|
+
["queued", new Set(["running", "canceled", "failed"])],
|
|
392
|
+
["running", new Set(["completed", "failed", "canceled"])],
|
|
393
|
+
]);
|
|
394
|
+
const JOB_TERMINALS_V2 = new Set(["completed", "failed", "canceled"]);
|
|
395
|
+
|
|
396
|
+
export const QUANT_DEFAULT_MAX_ACTIVE_MODELS_PER_OWNER = 50;
|
|
397
|
+
export const QUANT_DEFAULT_MAX_RUNNING_JOBS_PER_OWNER = 3;
|
|
398
|
+
export const QUANT_DEFAULT_MODEL_IDLE_MS = 120 * 86400000; // 120d
|
|
399
|
+
export const QUANT_DEFAULT_JOB_STUCK_MS = 6 * 3600000; // 6h
|
|
400
|
+
|
|
401
|
+
let _maxActiveModelsPerOwnerV2 = QUANT_DEFAULT_MAX_ACTIVE_MODELS_PER_OWNER;
|
|
402
|
+
let _maxRunningJobsPerOwnerV2 = QUANT_DEFAULT_MAX_RUNNING_JOBS_PER_OWNER;
|
|
403
|
+
let _modelIdleMsV2 = QUANT_DEFAULT_MODEL_IDLE_MS;
|
|
404
|
+
let _jobStuckMsV2 = QUANT_DEFAULT_JOB_STUCK_MS;
|
|
405
|
+
|
|
406
|
+
function _positiveIntV2(n, label) {
|
|
407
|
+
const v = Math.floor(Number(n));
|
|
408
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
409
|
+
throw new Error(`${label} must be a positive integer`);
|
|
410
|
+
return v;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export function getDefaultMaxActiveModelsPerOwnerV2() {
|
|
414
|
+
return QUANT_DEFAULT_MAX_ACTIVE_MODELS_PER_OWNER;
|
|
415
|
+
}
|
|
416
|
+
export function getMaxActiveModelsPerOwnerV2() {
|
|
417
|
+
return _maxActiveModelsPerOwnerV2;
|
|
418
|
+
}
|
|
419
|
+
export function setMaxActiveModelsPerOwnerV2(n) {
|
|
420
|
+
return (_maxActiveModelsPerOwnerV2 = _positiveIntV2(
|
|
421
|
+
n,
|
|
422
|
+
"maxActiveModelsPerOwner",
|
|
423
|
+
));
|
|
424
|
+
}
|
|
425
|
+
export function getDefaultMaxRunningJobsPerOwnerV2() {
|
|
426
|
+
return QUANT_DEFAULT_MAX_RUNNING_JOBS_PER_OWNER;
|
|
427
|
+
}
|
|
428
|
+
export function getMaxRunningJobsPerOwnerV2() {
|
|
429
|
+
return _maxRunningJobsPerOwnerV2;
|
|
430
|
+
}
|
|
431
|
+
export function setMaxRunningJobsPerOwnerV2(n) {
|
|
432
|
+
return (_maxRunningJobsPerOwnerV2 = _positiveIntV2(
|
|
433
|
+
n,
|
|
434
|
+
"maxRunningJobsPerOwner",
|
|
435
|
+
));
|
|
436
|
+
}
|
|
437
|
+
export function getDefaultModelIdleMsV2() {
|
|
438
|
+
return QUANT_DEFAULT_MODEL_IDLE_MS;
|
|
439
|
+
}
|
|
440
|
+
export function getModelIdleMsV2() {
|
|
441
|
+
return _modelIdleMsV2;
|
|
442
|
+
}
|
|
443
|
+
export function setModelIdleMsV2(ms) {
|
|
444
|
+
return (_modelIdleMsV2 = _positiveIntV2(ms, "modelIdleMs"));
|
|
445
|
+
}
|
|
446
|
+
export function getDefaultJobStuckMsV2() {
|
|
447
|
+
return QUANT_DEFAULT_JOB_STUCK_MS;
|
|
448
|
+
}
|
|
449
|
+
export function getJobStuckMsV2() {
|
|
450
|
+
return _jobStuckMsV2;
|
|
451
|
+
}
|
|
452
|
+
export function setJobStuckMsV2(ms) {
|
|
453
|
+
return (_jobStuckMsV2 = _positiveIntV2(ms, "jobStuckMs"));
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
const _modelsV2 = new Map();
|
|
457
|
+
const _jobTicketsV2 = new Map();
|
|
458
|
+
|
|
459
|
+
export function registerModelV2(
|
|
460
|
+
_db,
|
|
461
|
+
{ modelId, ownerId, family, initialStatus, metadata } = {},
|
|
462
|
+
) {
|
|
463
|
+
if (!modelId) throw new Error("modelId is required");
|
|
464
|
+
if (!ownerId) throw new Error("ownerId is required");
|
|
465
|
+
if (_modelsV2.has(modelId))
|
|
466
|
+
throw new Error(`Model ${modelId} already exists`);
|
|
467
|
+
const status = initialStatus || MODEL_MATURITY_V2.ONBOARDING;
|
|
468
|
+
if (!Object.values(MODEL_MATURITY_V2).includes(status))
|
|
469
|
+
throw new Error(`Invalid initial status: ${status}`);
|
|
470
|
+
if (MODEL_TERMINALS_V2.has(status))
|
|
471
|
+
throw new Error(`Cannot register in terminal status: ${status}`);
|
|
472
|
+
if (status === MODEL_MATURITY_V2.ACTIVE) {
|
|
473
|
+
if (getActiveModelCount(ownerId) >= _maxActiveModelsPerOwnerV2)
|
|
474
|
+
throw new Error(
|
|
475
|
+
`Owner ${ownerId} reached active-model cap (${_maxActiveModelsPerOwnerV2})`,
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
const now = Date.now();
|
|
479
|
+
const record = {
|
|
480
|
+
modelId,
|
|
481
|
+
ownerId,
|
|
482
|
+
family: family || "",
|
|
483
|
+
status,
|
|
484
|
+
metadata: metadata || {},
|
|
485
|
+
createdAt: now,
|
|
486
|
+
updatedAt: now,
|
|
487
|
+
lastUsedAt: now,
|
|
488
|
+
};
|
|
489
|
+
_modelsV2.set(modelId, record);
|
|
490
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
export function getModelV2(modelId) {
|
|
494
|
+
const r = _modelsV2.get(modelId);
|
|
495
|
+
return r ? { ...r, metadata: { ...r.metadata } } : null;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
export function setModelMaturityV2(_db, modelId, newStatus, patch = {}) {
|
|
499
|
+
const record = _modelsV2.get(modelId);
|
|
500
|
+
if (!record) throw new Error(`Unknown model: ${modelId}`);
|
|
501
|
+
if (!Object.values(MODEL_MATURITY_V2).includes(newStatus))
|
|
502
|
+
throw new Error(`Invalid status: ${newStatus}`);
|
|
503
|
+
const allowed = MODEL_TRANSITIONS_V2.get(record.status) || new Set();
|
|
504
|
+
if (!allowed.has(newStatus))
|
|
505
|
+
throw new Error(`Invalid transition: ${record.status} -> ${newStatus}`);
|
|
506
|
+
if (newStatus === MODEL_MATURITY_V2.ACTIVE) {
|
|
507
|
+
if (getActiveModelCount(record.ownerId) >= _maxActiveModelsPerOwnerV2)
|
|
508
|
+
throw new Error(
|
|
509
|
+
`Owner ${record.ownerId} reached active-model cap (${_maxActiveModelsPerOwnerV2})`,
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
record.status = newStatus;
|
|
513
|
+
record.updatedAt = Date.now();
|
|
514
|
+
if (patch.reason !== undefined) record.lastReason = patch.reason;
|
|
515
|
+
if (patch.metadata)
|
|
516
|
+
record.metadata = { ...record.metadata, ...patch.metadata };
|
|
517
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
export function activateModel(db, id, reason) {
|
|
521
|
+
return setModelMaturityV2(db, id, MODEL_MATURITY_V2.ACTIVE, { reason });
|
|
522
|
+
}
|
|
523
|
+
export function deprecateModel(db, id, reason) {
|
|
524
|
+
return setModelMaturityV2(db, id, MODEL_MATURITY_V2.DEPRECATED, { reason });
|
|
525
|
+
}
|
|
526
|
+
export function retireModel(db, id, reason) {
|
|
527
|
+
return setModelMaturityV2(db, id, MODEL_MATURITY_V2.RETIRED, { reason });
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
export function touchModelUsage(modelId) {
|
|
531
|
+
const record = _modelsV2.get(modelId);
|
|
532
|
+
if (!record) throw new Error(`Unknown model: ${modelId}`);
|
|
533
|
+
record.lastUsedAt = Date.now();
|
|
534
|
+
record.updatedAt = record.lastUsedAt;
|
|
535
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
export function enqueueJobTicketV2(
|
|
539
|
+
_db,
|
|
540
|
+
{ ticketId, ownerId, modelId, quantType, level, metadata } = {},
|
|
541
|
+
) {
|
|
542
|
+
if (!ticketId) throw new Error("ticketId is required");
|
|
543
|
+
if (!ownerId) throw new Error("ownerId is required");
|
|
544
|
+
if (!modelId) throw new Error("modelId is required");
|
|
545
|
+
if (!quantType) throw new Error("quantType is required");
|
|
546
|
+
if (_jobTicketsV2.has(ticketId))
|
|
547
|
+
throw new Error(`Ticket ${ticketId} already exists`);
|
|
548
|
+
const now = Date.now();
|
|
549
|
+
const record = {
|
|
550
|
+
ticketId,
|
|
551
|
+
ownerId,
|
|
552
|
+
modelId,
|
|
553
|
+
quantType,
|
|
554
|
+
level: level || null,
|
|
555
|
+
status: JOB_TICKET_V2.QUEUED,
|
|
556
|
+
metadata: metadata || {},
|
|
557
|
+
createdAt: now,
|
|
558
|
+
updatedAt: now,
|
|
559
|
+
};
|
|
560
|
+
_jobTicketsV2.set(ticketId, record);
|
|
561
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
export function getJobTicketV2(ticketId) {
|
|
565
|
+
const r = _jobTicketsV2.get(ticketId);
|
|
566
|
+
return r ? { ...r, metadata: { ...r.metadata } } : null;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
export function setJobTicketStatusV2(_db, ticketId, newStatus, patch = {}) {
|
|
570
|
+
const record = _jobTicketsV2.get(ticketId);
|
|
571
|
+
if (!record) throw new Error(`Unknown ticket: ${ticketId}`);
|
|
572
|
+
if (!Object.values(JOB_TICKET_V2).includes(newStatus))
|
|
573
|
+
throw new Error(`Invalid status: ${newStatus}`);
|
|
574
|
+
const allowed = JOB_TRANSITIONS_V2.get(record.status) || new Set();
|
|
575
|
+
if (!allowed.has(newStatus))
|
|
576
|
+
throw new Error(`Invalid transition: ${record.status} -> ${newStatus}`);
|
|
577
|
+
if (newStatus === JOB_TICKET_V2.RUNNING) {
|
|
578
|
+
if (getRunningJobCount(record.ownerId) >= _maxRunningJobsPerOwnerV2)
|
|
579
|
+
throw new Error(
|
|
580
|
+
`Owner ${record.ownerId} reached running-job cap (${_maxRunningJobsPerOwnerV2})`,
|
|
581
|
+
);
|
|
582
|
+
record.startedAt = Date.now();
|
|
583
|
+
}
|
|
584
|
+
record.status = newStatus;
|
|
585
|
+
record.updatedAt = Date.now();
|
|
586
|
+
if (patch.reason !== undefined) record.lastReason = patch.reason;
|
|
587
|
+
if (patch.metadata)
|
|
588
|
+
record.metadata = { ...record.metadata, ...patch.metadata };
|
|
589
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
export function startJobTicket(db, id, reason) {
|
|
593
|
+
return setJobTicketStatusV2(db, id, JOB_TICKET_V2.RUNNING, { reason });
|
|
594
|
+
}
|
|
595
|
+
export function completeJobTicket(db, id, reason) {
|
|
596
|
+
return setJobTicketStatusV2(db, id, JOB_TICKET_V2.COMPLETED, { reason });
|
|
597
|
+
}
|
|
598
|
+
export function failJobTicket(db, id, reason) {
|
|
599
|
+
return setJobTicketStatusV2(db, id, JOB_TICKET_V2.FAILED, { reason });
|
|
600
|
+
}
|
|
601
|
+
export function cancelJobTicket(db, id, reason) {
|
|
602
|
+
return setJobTicketStatusV2(db, id, JOB_TICKET_V2.CANCELED, { reason });
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
export function getActiveModelCount(ownerId) {
|
|
606
|
+
let n = 0;
|
|
607
|
+
for (const r of _modelsV2.values()) {
|
|
608
|
+
if (r.status !== MODEL_MATURITY_V2.ACTIVE) continue;
|
|
609
|
+
if (ownerId && r.ownerId !== ownerId) continue;
|
|
610
|
+
n++;
|
|
611
|
+
}
|
|
612
|
+
return n;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
export function getRunningJobCount(ownerId) {
|
|
616
|
+
let n = 0;
|
|
617
|
+
for (const r of _jobTicketsV2.values()) {
|
|
618
|
+
if (r.status !== JOB_TICKET_V2.RUNNING) continue;
|
|
619
|
+
if (ownerId && r.ownerId !== ownerId) continue;
|
|
620
|
+
n++;
|
|
621
|
+
}
|
|
622
|
+
return n;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
export function autoRetireIdleModels(_db, nowMs) {
|
|
626
|
+
const now = nowMs ?? Date.now();
|
|
627
|
+
const flipped = [];
|
|
628
|
+
for (const r of _modelsV2.values()) {
|
|
629
|
+
if (
|
|
630
|
+
r.status === MODEL_MATURITY_V2.ACTIVE ||
|
|
631
|
+
r.status === MODEL_MATURITY_V2.DEPRECATED
|
|
632
|
+
) {
|
|
633
|
+
if (now - r.lastUsedAt > _modelIdleMsV2) {
|
|
634
|
+
r.status = MODEL_MATURITY_V2.RETIRED;
|
|
635
|
+
r.updatedAt = now;
|
|
636
|
+
r.lastReason = "idle";
|
|
637
|
+
flipped.push(r.modelId);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return { flipped, count: flipped.length };
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
export function autoFailStuckJobTickets(_db, nowMs) {
|
|
645
|
+
const now = nowMs ?? Date.now();
|
|
646
|
+
const flipped = [];
|
|
647
|
+
for (const r of _jobTicketsV2.values()) {
|
|
648
|
+
if (r.status === JOB_TICKET_V2.RUNNING) {
|
|
649
|
+
const anchor = r.startedAt || r.createdAt;
|
|
650
|
+
if (now - anchor > _jobStuckMsV2) {
|
|
651
|
+
r.status = JOB_TICKET_V2.FAILED;
|
|
652
|
+
r.updatedAt = now;
|
|
653
|
+
r.lastReason = "stuck_timeout";
|
|
654
|
+
flipped.push(r.ticketId);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
return { flipped, count: flipped.length };
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
export function getQuantizationStatsV2() {
|
|
662
|
+
const modelsByStatus = {};
|
|
663
|
+
for (const s of Object.values(MODEL_MATURITY_V2)) modelsByStatus[s] = 0;
|
|
664
|
+
const ticketsByStatus = {};
|
|
665
|
+
for (const s of Object.values(JOB_TICKET_V2)) ticketsByStatus[s] = 0;
|
|
666
|
+
for (const r of _modelsV2.values()) modelsByStatus[r.status]++;
|
|
667
|
+
for (const r of _jobTicketsV2.values()) ticketsByStatus[r.status]++;
|
|
668
|
+
return {
|
|
669
|
+
totalModelsV2: _modelsV2.size,
|
|
670
|
+
totalTicketsV2: _jobTicketsV2.size,
|
|
671
|
+
maxActiveModelsPerOwner: _maxActiveModelsPerOwnerV2,
|
|
672
|
+
maxRunningJobsPerOwner: _maxRunningJobsPerOwnerV2,
|
|
673
|
+
modelIdleMs: _modelIdleMsV2,
|
|
674
|
+
jobStuckMs: _jobStuckMsV2,
|
|
675
|
+
modelsByStatus,
|
|
676
|
+
ticketsByStatus,
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
export function _resetStateV2() {
|
|
681
|
+
_maxActiveModelsPerOwnerV2 = QUANT_DEFAULT_MAX_ACTIVE_MODELS_PER_OWNER;
|
|
682
|
+
_maxRunningJobsPerOwnerV2 = QUANT_DEFAULT_MAX_RUNNING_JOBS_PER_OWNER;
|
|
683
|
+
_modelIdleMsV2 = QUANT_DEFAULT_MODEL_IDLE_MS;
|
|
684
|
+
_jobStuckMsV2 = QUANT_DEFAULT_JOB_STUCK_MS;
|
|
685
|
+
_modelsV2.clear();
|
|
686
|
+
_jobTicketsV2.clear();
|
|
687
|
+
}
|
|
@@ -154,3 +154,330 @@ export function getCacheStats(db) {
|
|
|
154
154
|
expired_entries: expired?.cnt || 0,
|
|
155
155
|
};
|
|
156
156
|
}
|
|
157
|
+
|
|
158
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
159
|
+
* V2 Surface — Response cache governance layer.
|
|
160
|
+
* Tracks per-owner cache-profile maturity + per-profile refresh-job
|
|
161
|
+
* lifecycle independent of SQLite llm_cache table.
|
|
162
|
+
* ═══════════════════════════════════════════════════════════════ */
|
|
163
|
+
|
|
164
|
+
export const PROFILE_MATURITY_V2 = Object.freeze({
|
|
165
|
+
PENDING: "pending",
|
|
166
|
+
ACTIVE: "active",
|
|
167
|
+
SUSPENDED: "suspended",
|
|
168
|
+
ARCHIVED: "archived",
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
export const REFRESH_JOB_LIFECYCLE_V2 = Object.freeze({
|
|
172
|
+
QUEUED: "queued",
|
|
173
|
+
RUNNING: "running",
|
|
174
|
+
COMPLETED: "completed",
|
|
175
|
+
FAILED: "failed",
|
|
176
|
+
CANCELLED: "cancelled",
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const PROFILE_TRANSITIONS_V2 = new Map([
|
|
180
|
+
["pending", new Set(["active", "archived"])],
|
|
181
|
+
["active", new Set(["suspended", "archived"])],
|
|
182
|
+
["suspended", new Set(["active", "archived"])],
|
|
183
|
+
["archived", new Set()],
|
|
184
|
+
]);
|
|
185
|
+
const PROFILE_TERMINALS_V2 = new Set(["archived"]);
|
|
186
|
+
|
|
187
|
+
const REFRESH_TRANSITIONS_V2 = new Map([
|
|
188
|
+
["queued", new Set(["running", "cancelled"])],
|
|
189
|
+
["running", new Set(["completed", "failed", "cancelled"])],
|
|
190
|
+
["completed", new Set()],
|
|
191
|
+
["failed", new Set()],
|
|
192
|
+
["cancelled", new Set()],
|
|
193
|
+
]);
|
|
194
|
+
const REFRESH_TERMINALS_V2 = new Set(["completed", "failed", "cancelled"]);
|
|
195
|
+
|
|
196
|
+
export const CACHE_DEFAULT_MAX_ACTIVE_PROFILES_PER_OWNER = 25;
|
|
197
|
+
export const CACHE_DEFAULT_MAX_PENDING_REFRESH_JOBS_PER_PROFILE = 4;
|
|
198
|
+
export const CACHE_DEFAULT_PROFILE_IDLE_MS = 1000 * 60 * 60 * 24 * 7; // 7 days
|
|
199
|
+
export const CACHE_DEFAULT_REFRESH_STUCK_MS = 1000 * 60 * 10; // 10 min
|
|
200
|
+
|
|
201
|
+
const _profilesV2 = new Map();
|
|
202
|
+
const _refreshJobsV2 = new Map();
|
|
203
|
+
let _maxActiveProfilesPerOwnerV2 = CACHE_DEFAULT_MAX_ACTIVE_PROFILES_PER_OWNER;
|
|
204
|
+
let _maxPendingRefreshJobsPerProfileV2 =
|
|
205
|
+
CACHE_DEFAULT_MAX_PENDING_REFRESH_JOBS_PER_PROFILE;
|
|
206
|
+
let _profileIdleMsV2 = CACHE_DEFAULT_PROFILE_IDLE_MS;
|
|
207
|
+
let _refreshStuckMsV2 = CACHE_DEFAULT_REFRESH_STUCK_MS;
|
|
208
|
+
|
|
209
|
+
function _posIntCacheV2(n, label) {
|
|
210
|
+
const v = Math.floor(Number(n));
|
|
211
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
212
|
+
throw new Error(`${label} must be a positive integer`);
|
|
213
|
+
return v;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export function getMaxActiveProfilesPerOwnerV2() {
|
|
217
|
+
return _maxActiveProfilesPerOwnerV2;
|
|
218
|
+
}
|
|
219
|
+
export function setMaxActiveProfilesPerOwnerV2(n) {
|
|
220
|
+
_maxActiveProfilesPerOwnerV2 = _posIntCacheV2(n, "maxActiveProfilesPerOwner");
|
|
221
|
+
}
|
|
222
|
+
export function getMaxPendingRefreshJobsPerProfileV2() {
|
|
223
|
+
return _maxPendingRefreshJobsPerProfileV2;
|
|
224
|
+
}
|
|
225
|
+
export function setMaxPendingRefreshJobsPerProfileV2(n) {
|
|
226
|
+
_maxPendingRefreshJobsPerProfileV2 = _posIntCacheV2(
|
|
227
|
+
n,
|
|
228
|
+
"maxPendingRefreshJobsPerProfile",
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
export function getProfileIdleMsV2() {
|
|
232
|
+
return _profileIdleMsV2;
|
|
233
|
+
}
|
|
234
|
+
export function setProfileIdleMsV2(n) {
|
|
235
|
+
_profileIdleMsV2 = _posIntCacheV2(n, "profileIdleMs");
|
|
236
|
+
}
|
|
237
|
+
export function getRefreshStuckMsV2() {
|
|
238
|
+
return _refreshStuckMsV2;
|
|
239
|
+
}
|
|
240
|
+
export function setRefreshStuckMsV2(n) {
|
|
241
|
+
_refreshStuckMsV2 = _posIntCacheV2(n, "refreshStuckMs");
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export function getActiveProfileCountV2(ownerId) {
|
|
245
|
+
let n = 0;
|
|
246
|
+
for (const p of _profilesV2.values()) {
|
|
247
|
+
if (p.ownerId === ownerId && p.status === "active") n += 1;
|
|
248
|
+
}
|
|
249
|
+
return n;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export function getPendingRefreshJobCountV2(profileId) {
|
|
253
|
+
let n = 0;
|
|
254
|
+
for (const j of _refreshJobsV2.values()) {
|
|
255
|
+
if (
|
|
256
|
+
j.profileId === profileId &&
|
|
257
|
+
(j.status === "queued" || j.status === "running")
|
|
258
|
+
)
|
|
259
|
+
n += 1;
|
|
260
|
+
}
|
|
261
|
+
return n;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function _copyProfileV2(p) {
|
|
265
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
266
|
+
}
|
|
267
|
+
function _copyRefreshJobV2(j) {
|
|
268
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export function registerProfileV2(
|
|
272
|
+
id,
|
|
273
|
+
{ ownerId, label, metadata = {}, now = Date.now() } = {},
|
|
274
|
+
) {
|
|
275
|
+
if (!id || typeof id !== "string") throw new Error("id must be a string");
|
|
276
|
+
if (!ownerId || typeof ownerId !== "string")
|
|
277
|
+
throw new Error("ownerId must be a string");
|
|
278
|
+
if (!label || typeof label !== "string")
|
|
279
|
+
throw new Error("label must be a string");
|
|
280
|
+
if (_profilesV2.has(id)) throw new Error(`profile ${id} already exists`);
|
|
281
|
+
const p = {
|
|
282
|
+
id,
|
|
283
|
+
ownerId,
|
|
284
|
+
label,
|
|
285
|
+
status: "pending",
|
|
286
|
+
createdAt: now,
|
|
287
|
+
lastSeenAt: now,
|
|
288
|
+
activatedAt: null,
|
|
289
|
+
archivedAt: null,
|
|
290
|
+
metadata: { ...metadata },
|
|
291
|
+
};
|
|
292
|
+
_profilesV2.set(id, p);
|
|
293
|
+
return _copyProfileV2(p);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export function getProfileV2(id) {
|
|
297
|
+
const p = _profilesV2.get(id);
|
|
298
|
+
return p ? _copyProfileV2(p) : null;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export function listProfilesV2({ ownerId, status } = {}) {
|
|
302
|
+
const out = [];
|
|
303
|
+
for (const p of _profilesV2.values()) {
|
|
304
|
+
if (ownerId && p.ownerId !== ownerId) continue;
|
|
305
|
+
if (status && p.status !== status) continue;
|
|
306
|
+
out.push(_copyProfileV2(p));
|
|
307
|
+
}
|
|
308
|
+
return out;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export function setProfileStatusV2(id, next, { now = Date.now() } = {}) {
|
|
312
|
+
const p = _profilesV2.get(id);
|
|
313
|
+
if (!p) throw new Error(`profile ${id} not found`);
|
|
314
|
+
if (!PROFILE_TRANSITIONS_V2.has(next))
|
|
315
|
+
throw new Error(`unknown profile status: ${next}`);
|
|
316
|
+
if (PROFILE_TERMINALS_V2.has(p.status))
|
|
317
|
+
throw new Error(`profile ${id} is in terminal state ${p.status}`);
|
|
318
|
+
const allowed = PROFILE_TRANSITIONS_V2.get(p.status);
|
|
319
|
+
if (!allowed.has(next))
|
|
320
|
+
throw new Error(`cannot transition profile from ${p.status} to ${next}`);
|
|
321
|
+
if (next === "active") {
|
|
322
|
+
if (p.status === "pending") {
|
|
323
|
+
const count = getActiveProfileCountV2(p.ownerId);
|
|
324
|
+
if (count >= _maxActiveProfilesPerOwnerV2)
|
|
325
|
+
throw new Error(
|
|
326
|
+
`owner ${p.ownerId} already at active-profile cap (${_maxActiveProfilesPerOwnerV2})`,
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
if (!p.activatedAt) p.activatedAt = now;
|
|
330
|
+
}
|
|
331
|
+
if (next === "archived" && !p.archivedAt) p.archivedAt = now;
|
|
332
|
+
p.status = next;
|
|
333
|
+
p.lastSeenAt = now;
|
|
334
|
+
return _copyProfileV2(p);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
export function activateProfileV2(id, opts) {
|
|
338
|
+
return setProfileStatusV2(id, "active", opts);
|
|
339
|
+
}
|
|
340
|
+
export function suspendProfileV2(id, opts) {
|
|
341
|
+
return setProfileStatusV2(id, "suspended", opts);
|
|
342
|
+
}
|
|
343
|
+
export function archiveProfileV2(id, opts) {
|
|
344
|
+
return setProfileStatusV2(id, "archived", opts);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export function touchProfileV2(id, { now = Date.now() } = {}) {
|
|
348
|
+
const p = _profilesV2.get(id);
|
|
349
|
+
if (!p) throw new Error(`profile ${id} not found`);
|
|
350
|
+
p.lastSeenAt = now;
|
|
351
|
+
return _copyProfileV2(p);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
export function createRefreshJobV2(
|
|
355
|
+
id,
|
|
356
|
+
{ profileId, kind = "warm", metadata = {}, now = Date.now() } = {},
|
|
357
|
+
) {
|
|
358
|
+
if (!id || typeof id !== "string") throw new Error("id must be a string");
|
|
359
|
+
if (!profileId || typeof profileId !== "string")
|
|
360
|
+
throw new Error("profileId must be a string");
|
|
361
|
+
if (_refreshJobsV2.has(id)) throw new Error(`job ${id} already exists`);
|
|
362
|
+
const count = getPendingRefreshJobCountV2(profileId);
|
|
363
|
+
if (count >= _maxPendingRefreshJobsPerProfileV2)
|
|
364
|
+
throw new Error(
|
|
365
|
+
`profile ${profileId} already at pending-refresh-job cap (${_maxPendingRefreshJobsPerProfileV2})`,
|
|
366
|
+
);
|
|
367
|
+
const j = {
|
|
368
|
+
id,
|
|
369
|
+
profileId,
|
|
370
|
+
kind,
|
|
371
|
+
status: "queued",
|
|
372
|
+
createdAt: now,
|
|
373
|
+
lastSeenAt: now,
|
|
374
|
+
startedAt: null,
|
|
375
|
+
settledAt: null,
|
|
376
|
+
metadata: { ...metadata },
|
|
377
|
+
};
|
|
378
|
+
_refreshJobsV2.set(id, j);
|
|
379
|
+
return _copyRefreshJobV2(j);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
export function getRefreshJobV2(id) {
|
|
383
|
+
const j = _refreshJobsV2.get(id);
|
|
384
|
+
return j ? _copyRefreshJobV2(j) : null;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export function listRefreshJobsV2({ profileId, status } = {}) {
|
|
388
|
+
const out = [];
|
|
389
|
+
for (const j of _refreshJobsV2.values()) {
|
|
390
|
+
if (profileId && j.profileId !== profileId) continue;
|
|
391
|
+
if (status && j.status !== status) continue;
|
|
392
|
+
out.push(_copyRefreshJobV2(j));
|
|
393
|
+
}
|
|
394
|
+
return out;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export function setRefreshJobStatusV2(id, next, { now = Date.now() } = {}) {
|
|
398
|
+
const j = _refreshJobsV2.get(id);
|
|
399
|
+
if (!j) throw new Error(`job ${id} not found`);
|
|
400
|
+
if (!REFRESH_TRANSITIONS_V2.has(next))
|
|
401
|
+
throw new Error(`unknown job status: ${next}`);
|
|
402
|
+
if (REFRESH_TERMINALS_V2.has(j.status))
|
|
403
|
+
throw new Error(`job ${id} is in terminal state ${j.status}`);
|
|
404
|
+
const allowed = REFRESH_TRANSITIONS_V2.get(j.status);
|
|
405
|
+
if (!allowed.has(next))
|
|
406
|
+
throw new Error(`cannot transition job from ${j.status} to ${next}`);
|
|
407
|
+
if (next === "running" && !j.startedAt) j.startedAt = now;
|
|
408
|
+
if (REFRESH_TERMINALS_V2.has(next) && !j.settledAt) j.settledAt = now;
|
|
409
|
+
j.status = next;
|
|
410
|
+
j.lastSeenAt = now;
|
|
411
|
+
return _copyRefreshJobV2(j);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export function startRefreshJobV2(id, opts) {
|
|
415
|
+
return setRefreshJobStatusV2(id, "running", opts);
|
|
416
|
+
}
|
|
417
|
+
export function completeRefreshJobV2(id, opts) {
|
|
418
|
+
return setRefreshJobStatusV2(id, "completed", opts);
|
|
419
|
+
}
|
|
420
|
+
export function failRefreshJobV2(id, opts) {
|
|
421
|
+
return setRefreshJobStatusV2(id, "failed", opts);
|
|
422
|
+
}
|
|
423
|
+
export function cancelRefreshJobV2(id, opts) {
|
|
424
|
+
return setRefreshJobStatusV2(id, "cancelled", opts);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
export function autoSuspendIdleProfilesV2({ now = Date.now() } = {}) {
|
|
428
|
+
const flipped = [];
|
|
429
|
+
for (const p of _profilesV2.values()) {
|
|
430
|
+
if (p.status !== "active") continue;
|
|
431
|
+
if (now - p.lastSeenAt > _profileIdleMsV2) {
|
|
432
|
+
p.status = "suspended";
|
|
433
|
+
p.lastSeenAt = now;
|
|
434
|
+
flipped.push(_copyProfileV2(p));
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return flipped;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
export function autoFailStuckRefreshJobsV2({ now = Date.now() } = {}) {
|
|
441
|
+
const flipped = [];
|
|
442
|
+
for (const j of _refreshJobsV2.values()) {
|
|
443
|
+
if (j.status !== "running") continue;
|
|
444
|
+
if (now - j.lastSeenAt > _refreshStuckMsV2) {
|
|
445
|
+
j.status = "failed";
|
|
446
|
+
j.lastSeenAt = now;
|
|
447
|
+
if (!j.settledAt) j.settledAt = now;
|
|
448
|
+
flipped.push(_copyRefreshJobV2(j));
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
return flipped;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
export function getResponseCacheStatsV2() {
|
|
455
|
+
const profilesByStatus = {};
|
|
456
|
+
for (const v of Object.values(PROFILE_MATURITY_V2)) profilesByStatus[v] = 0;
|
|
457
|
+
for (const p of _profilesV2.values()) profilesByStatus[p.status] += 1;
|
|
458
|
+
|
|
459
|
+
const jobsByStatus = {};
|
|
460
|
+
for (const v of Object.values(REFRESH_JOB_LIFECYCLE_V2)) jobsByStatus[v] = 0;
|
|
461
|
+
for (const j of _refreshJobsV2.values()) jobsByStatus[j.status] += 1;
|
|
462
|
+
|
|
463
|
+
return {
|
|
464
|
+
totalProfilesV2: _profilesV2.size,
|
|
465
|
+
totalRefreshJobsV2: _refreshJobsV2.size,
|
|
466
|
+
maxActiveProfilesPerOwner: _maxActiveProfilesPerOwnerV2,
|
|
467
|
+
maxPendingRefreshJobsPerProfile: _maxPendingRefreshJobsPerProfileV2,
|
|
468
|
+
profileIdleMs: _profileIdleMsV2,
|
|
469
|
+
refreshStuckMs: _refreshStuckMsV2,
|
|
470
|
+
profilesByStatus,
|
|
471
|
+
jobsByStatus,
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
export function _resetStateResponseCacheV2() {
|
|
476
|
+
_profilesV2.clear();
|
|
477
|
+
_refreshJobsV2.clear();
|
|
478
|
+
_maxActiveProfilesPerOwnerV2 = CACHE_DEFAULT_MAX_ACTIVE_PROFILES_PER_OWNER;
|
|
479
|
+
_maxPendingRefreshJobsPerProfileV2 =
|
|
480
|
+
CACHE_DEFAULT_MAX_PENDING_REFRESH_JOBS_PER_PROFILE;
|
|
481
|
+
_profileIdleMsV2 = CACHE_DEFAULT_PROFILE_IDLE_MS;
|
|
482
|
+
_refreshStuckMsV2 = CACHE_DEFAULT_REFRESH_STUCK_MS;
|
|
483
|
+
}
|