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/llm-providers.js
CHANGED
|
@@ -365,3 +365,394 @@ export class LLMProviderRegistry {
|
|
|
365
365
|
return { ok: true, elapsed: Date.now() - start, response: text.trim() };
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
|
+
|
|
369
|
+
/* ─────────────────────────────────────────────────────────────────
|
|
370
|
+
* V2 Governance Layer (in-memory, independent of SQLite llm_providers)
|
|
371
|
+
*
|
|
372
|
+
* Provider profile maturity: pending → active → suspended → retired
|
|
373
|
+
* - retired terminal
|
|
374
|
+
* - suspended → active recovery (cap-exempt)
|
|
375
|
+
*
|
|
376
|
+
* Request lifecycle: queued → running → completed | failed | cancelled
|
|
377
|
+
* - 3 terminals
|
|
378
|
+
* - per-profile pending-request cap counts queued+running
|
|
379
|
+
*
|
|
380
|
+
* Per-owner active-profile cap on pending→active only (recovery exempt).
|
|
381
|
+
* Per-profile pending-request cap enforced at createRequestV2.
|
|
382
|
+
*
|
|
383
|
+
* Auto-flip:
|
|
384
|
+
* - autoSuspendIdleProfilesV2 active w/ lastSeenAt past idle threshold → suspended
|
|
385
|
+
* - autoFailStuckRequestsV2 running w/ startedAt past stuck threshold → failed
|
|
386
|
+
* ───────────────────────────────────────────────────────────────── */
|
|
387
|
+
|
|
388
|
+
export const PROVIDER_MATURITY_V2 = Object.freeze({
|
|
389
|
+
PENDING: "pending",
|
|
390
|
+
ACTIVE: "active",
|
|
391
|
+
SUSPENDED: "suspended",
|
|
392
|
+
RETIRED: "retired",
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
export const REQUEST_LIFECYCLE_V2 = Object.freeze({
|
|
396
|
+
QUEUED: "queued",
|
|
397
|
+
RUNNING: "running",
|
|
398
|
+
COMPLETED: "completed",
|
|
399
|
+
FAILED: "failed",
|
|
400
|
+
CANCELLED: "cancelled",
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
const _PROVIDER_TRANSITIONS_V2 = new Map([
|
|
404
|
+
[
|
|
405
|
+
PROVIDER_MATURITY_V2.PENDING,
|
|
406
|
+
new Set([PROVIDER_MATURITY_V2.ACTIVE, PROVIDER_MATURITY_V2.RETIRED]),
|
|
407
|
+
],
|
|
408
|
+
[
|
|
409
|
+
PROVIDER_MATURITY_V2.ACTIVE,
|
|
410
|
+
new Set([PROVIDER_MATURITY_V2.SUSPENDED, PROVIDER_MATURITY_V2.RETIRED]),
|
|
411
|
+
],
|
|
412
|
+
[
|
|
413
|
+
PROVIDER_MATURITY_V2.SUSPENDED,
|
|
414
|
+
new Set([PROVIDER_MATURITY_V2.ACTIVE, PROVIDER_MATURITY_V2.RETIRED]),
|
|
415
|
+
],
|
|
416
|
+
[PROVIDER_MATURITY_V2.RETIRED, new Set()],
|
|
417
|
+
]);
|
|
418
|
+
const _PROVIDER_TERMINALS_V2 = new Set([PROVIDER_MATURITY_V2.RETIRED]);
|
|
419
|
+
|
|
420
|
+
const _REQUEST_TRANSITIONS_V2 = new Map([
|
|
421
|
+
[
|
|
422
|
+
REQUEST_LIFECYCLE_V2.QUEUED,
|
|
423
|
+
new Set([REQUEST_LIFECYCLE_V2.RUNNING, REQUEST_LIFECYCLE_V2.CANCELLED]),
|
|
424
|
+
],
|
|
425
|
+
[
|
|
426
|
+
REQUEST_LIFECYCLE_V2.RUNNING,
|
|
427
|
+
new Set([
|
|
428
|
+
REQUEST_LIFECYCLE_V2.COMPLETED,
|
|
429
|
+
REQUEST_LIFECYCLE_V2.FAILED,
|
|
430
|
+
REQUEST_LIFECYCLE_V2.CANCELLED,
|
|
431
|
+
]),
|
|
432
|
+
],
|
|
433
|
+
[REQUEST_LIFECYCLE_V2.COMPLETED, new Set()],
|
|
434
|
+
[REQUEST_LIFECYCLE_V2.FAILED, new Set()],
|
|
435
|
+
[REQUEST_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
436
|
+
]);
|
|
437
|
+
const _REQUEST_TERMINALS_V2 = new Set([
|
|
438
|
+
REQUEST_LIFECYCLE_V2.COMPLETED,
|
|
439
|
+
REQUEST_LIFECYCLE_V2.FAILED,
|
|
440
|
+
REQUEST_LIFECYCLE_V2.CANCELLED,
|
|
441
|
+
]);
|
|
442
|
+
|
|
443
|
+
export const PROVIDER_DEFAULT_MAX_ACTIVE_PER_OWNER = 8;
|
|
444
|
+
export const PROVIDER_DEFAULT_MAX_PENDING_REQUESTS_PER_PROFILE = 16;
|
|
445
|
+
export const PROVIDER_DEFAULT_PROFILE_IDLE_MS = 14 * 24 * 60 * 60 * 1000;
|
|
446
|
+
export const PROVIDER_DEFAULT_REQUEST_STUCK_MS = 5 * 60 * 1000;
|
|
447
|
+
|
|
448
|
+
const _stateLlmV2 = {
|
|
449
|
+
profiles: new Map(),
|
|
450
|
+
requests: new Map(),
|
|
451
|
+
maxActiveProfilesPerOwner: PROVIDER_DEFAULT_MAX_ACTIVE_PER_OWNER,
|
|
452
|
+
maxPendingRequestsPerProfile:
|
|
453
|
+
PROVIDER_DEFAULT_MAX_PENDING_REQUESTS_PER_PROFILE,
|
|
454
|
+
profileIdleMs: PROVIDER_DEFAULT_PROFILE_IDLE_MS,
|
|
455
|
+
requestStuckMs: PROVIDER_DEFAULT_REQUEST_STUCK_MS,
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
function _posIntLlmV2(n, label) {
|
|
459
|
+
const v = Math.floor(n);
|
|
460
|
+
if (!Number.isFinite(v) || v <= 0) {
|
|
461
|
+
throw new Error(`${label} must be a positive integer`);
|
|
462
|
+
}
|
|
463
|
+
return v;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
function _copyProfileV2(p) {
|
|
467
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function _copyRequestV2(r) {
|
|
471
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
export function getMaxActiveProfilesPerOwnerV2() {
|
|
475
|
+
return _stateLlmV2.maxActiveProfilesPerOwner;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
export function setMaxActiveProfilesPerOwnerV2(n) {
|
|
479
|
+
_stateLlmV2.maxActiveProfilesPerOwner = _posIntLlmV2(
|
|
480
|
+
n,
|
|
481
|
+
"maxActiveProfilesPerOwner",
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
export function getMaxPendingRequestsPerProfileV2() {
|
|
486
|
+
return _stateLlmV2.maxPendingRequestsPerProfile;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
export function setMaxPendingRequestsPerProfileV2(n) {
|
|
490
|
+
_stateLlmV2.maxPendingRequestsPerProfile = _posIntLlmV2(
|
|
491
|
+
n,
|
|
492
|
+
"maxPendingRequestsPerProfile",
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
export function getProfileIdleMsV2() {
|
|
497
|
+
return _stateLlmV2.profileIdleMs;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
export function setProfileIdleMsV2(ms) {
|
|
501
|
+
_stateLlmV2.profileIdleMs = _posIntLlmV2(ms, "profileIdleMs");
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
export function getRequestStuckMsV2() {
|
|
505
|
+
return _stateLlmV2.requestStuckMs;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
export function setRequestStuckMsV2(ms) {
|
|
509
|
+
_stateLlmV2.requestStuckMs = _posIntLlmV2(ms, "requestStuckMs");
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
export function getActiveProfileCountV2(ownerId) {
|
|
513
|
+
let count = 0;
|
|
514
|
+
for (const p of _stateLlmV2.profiles.values()) {
|
|
515
|
+
if (p.ownerId === ownerId && p.status === PROVIDER_MATURITY_V2.ACTIVE) {
|
|
516
|
+
count++;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return count;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
export function getPendingRequestCountV2(profileId) {
|
|
523
|
+
let count = 0;
|
|
524
|
+
for (const r of _stateLlmV2.requests.values()) {
|
|
525
|
+
if (
|
|
526
|
+
r.profileId === profileId &&
|
|
527
|
+
(r.status === REQUEST_LIFECYCLE_V2.QUEUED ||
|
|
528
|
+
r.status === REQUEST_LIFECYCLE_V2.RUNNING)
|
|
529
|
+
) {
|
|
530
|
+
count++;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return count;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
export function registerProfileV2(
|
|
537
|
+
id,
|
|
538
|
+
{ ownerId, provider, model, metadata } = {},
|
|
539
|
+
) {
|
|
540
|
+
if (!id) throw new Error("profile id is required");
|
|
541
|
+
if (!ownerId) throw new Error("ownerId is required");
|
|
542
|
+
if (!provider) throw new Error("provider is required");
|
|
543
|
+
if (_stateLlmV2.profiles.has(id))
|
|
544
|
+
throw new Error(`profile ${id} already exists`);
|
|
545
|
+
const now = Date.now();
|
|
546
|
+
const profile = {
|
|
547
|
+
id,
|
|
548
|
+
ownerId,
|
|
549
|
+
provider,
|
|
550
|
+
model: model || "default",
|
|
551
|
+
status: PROVIDER_MATURITY_V2.PENDING,
|
|
552
|
+
createdAt: now,
|
|
553
|
+
lastSeenAt: now,
|
|
554
|
+
activatedAt: null,
|
|
555
|
+
retiredAt: null,
|
|
556
|
+
metadata: metadata ? { ...metadata } : {},
|
|
557
|
+
};
|
|
558
|
+
_stateLlmV2.profiles.set(id, profile);
|
|
559
|
+
return _copyProfileV2(profile);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
export function getProfileV2(id) {
|
|
563
|
+
const p = _stateLlmV2.profiles.get(id);
|
|
564
|
+
return p ? _copyProfileV2(p) : null;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
export function listProfilesV2({ ownerId, status, provider } = {}) {
|
|
568
|
+
const out = [];
|
|
569
|
+
for (const p of _stateLlmV2.profiles.values()) {
|
|
570
|
+
if (ownerId && p.ownerId !== ownerId) continue;
|
|
571
|
+
if (status && p.status !== status) continue;
|
|
572
|
+
if (provider && p.provider !== provider) continue;
|
|
573
|
+
out.push(_copyProfileV2(p));
|
|
574
|
+
}
|
|
575
|
+
return out;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
export function setProfileStatusV2(id, next) {
|
|
579
|
+
const p = _stateLlmV2.profiles.get(id);
|
|
580
|
+
if (!p) throw new Error(`profile ${id} not found`);
|
|
581
|
+
const allowed = _PROVIDER_TRANSITIONS_V2.get(p.status);
|
|
582
|
+
if (!allowed || !allowed.has(next)) {
|
|
583
|
+
throw new Error(`invalid profile transition: ${p.status} → ${next}`);
|
|
584
|
+
}
|
|
585
|
+
if (
|
|
586
|
+
p.status === PROVIDER_MATURITY_V2.PENDING &&
|
|
587
|
+
next === PROVIDER_MATURITY_V2.ACTIVE
|
|
588
|
+
) {
|
|
589
|
+
const count = getActiveProfileCountV2(p.ownerId);
|
|
590
|
+
if (count >= _stateLlmV2.maxActiveProfilesPerOwner) {
|
|
591
|
+
throw new Error(
|
|
592
|
+
`owner ${p.ownerId} active-profile cap reached (${count}/${_stateLlmV2.maxActiveProfilesPerOwner})`,
|
|
593
|
+
);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
const now = Date.now();
|
|
597
|
+
p.status = next;
|
|
598
|
+
p.lastSeenAt = now;
|
|
599
|
+
if (next === PROVIDER_MATURITY_V2.ACTIVE && !p.activatedAt)
|
|
600
|
+
p.activatedAt = now;
|
|
601
|
+
if (_PROVIDER_TERMINALS_V2.has(next) && !p.retiredAt) p.retiredAt = now;
|
|
602
|
+
return _copyProfileV2(p);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
export function activateProfileV2(id) {
|
|
606
|
+
return setProfileStatusV2(id, PROVIDER_MATURITY_V2.ACTIVE);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
export function suspendProfileV2(id) {
|
|
610
|
+
return setProfileStatusV2(id, PROVIDER_MATURITY_V2.SUSPENDED);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
export function retireProfileV2(id) {
|
|
614
|
+
return setProfileStatusV2(id, PROVIDER_MATURITY_V2.RETIRED);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
export function touchProfileV2(id) {
|
|
618
|
+
const p = _stateLlmV2.profiles.get(id);
|
|
619
|
+
if (!p) throw new Error(`profile ${id} not found`);
|
|
620
|
+
p.lastSeenAt = Date.now();
|
|
621
|
+
return _copyProfileV2(p);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export function createRequestV2(id, { profileId, kind, metadata } = {}) {
|
|
625
|
+
if (!id) throw new Error("request id is required");
|
|
626
|
+
if (!profileId) throw new Error("profileId is required");
|
|
627
|
+
if (_stateLlmV2.requests.has(id))
|
|
628
|
+
throw new Error(`request ${id} already exists`);
|
|
629
|
+
const profile = _stateLlmV2.profiles.get(profileId);
|
|
630
|
+
if (!profile) throw new Error(`profile ${profileId} not found`);
|
|
631
|
+
const pending = getPendingRequestCountV2(profileId);
|
|
632
|
+
if (pending >= _stateLlmV2.maxPendingRequestsPerProfile) {
|
|
633
|
+
throw new Error(
|
|
634
|
+
`profile ${profileId} pending-request cap reached (${pending}/${_stateLlmV2.maxPendingRequestsPerProfile})`,
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
const now = Date.now();
|
|
638
|
+
const req = {
|
|
639
|
+
id,
|
|
640
|
+
profileId,
|
|
641
|
+
kind: kind || "completion",
|
|
642
|
+
status: REQUEST_LIFECYCLE_V2.QUEUED,
|
|
643
|
+
createdAt: now,
|
|
644
|
+
lastSeenAt: now,
|
|
645
|
+
startedAt: null,
|
|
646
|
+
settledAt: null,
|
|
647
|
+
metadata: metadata ? { ...metadata } : {},
|
|
648
|
+
};
|
|
649
|
+
_stateLlmV2.requests.set(id, req);
|
|
650
|
+
return _copyRequestV2(req);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
export function getRequestV2(id) {
|
|
654
|
+
const r = _stateLlmV2.requests.get(id);
|
|
655
|
+
return r ? _copyRequestV2(r) : null;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
export function listRequestsV2({ profileId, status } = {}) {
|
|
659
|
+
const out = [];
|
|
660
|
+
for (const r of _stateLlmV2.requests.values()) {
|
|
661
|
+
if (profileId && r.profileId !== profileId) continue;
|
|
662
|
+
if (status && r.status !== status) continue;
|
|
663
|
+
out.push(_copyRequestV2(r));
|
|
664
|
+
}
|
|
665
|
+
return out;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
export function setRequestStatusV2(id, next) {
|
|
669
|
+
const r = _stateLlmV2.requests.get(id);
|
|
670
|
+
if (!r) throw new Error(`request ${id} not found`);
|
|
671
|
+
const allowed = _REQUEST_TRANSITIONS_V2.get(r.status);
|
|
672
|
+
if (!allowed || !allowed.has(next)) {
|
|
673
|
+
throw new Error(`invalid request transition: ${r.status} → ${next}`);
|
|
674
|
+
}
|
|
675
|
+
const now = Date.now();
|
|
676
|
+
r.status = next;
|
|
677
|
+
r.lastSeenAt = now;
|
|
678
|
+
if (next === REQUEST_LIFECYCLE_V2.RUNNING && !r.startedAt) r.startedAt = now;
|
|
679
|
+
if (_REQUEST_TERMINALS_V2.has(next) && !r.settledAt) r.settledAt = now;
|
|
680
|
+
return _copyRequestV2(r);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
export function startRequestV2(id) {
|
|
684
|
+
return setRequestStatusV2(id, REQUEST_LIFECYCLE_V2.RUNNING);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
export function completeRequestV2(id) {
|
|
688
|
+
return setRequestStatusV2(id, REQUEST_LIFECYCLE_V2.COMPLETED);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
export function failRequestV2(id) {
|
|
692
|
+
return setRequestStatusV2(id, REQUEST_LIFECYCLE_V2.FAILED);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
export function cancelRequestV2(id) {
|
|
696
|
+
return setRequestStatusV2(id, REQUEST_LIFECYCLE_V2.CANCELLED);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
export function autoSuspendIdleProfilesV2({ now = Date.now() } = {}) {
|
|
700
|
+
const flipped = [];
|
|
701
|
+
for (const p of _stateLlmV2.profiles.values()) {
|
|
702
|
+
if (
|
|
703
|
+
p.status === PROVIDER_MATURITY_V2.ACTIVE &&
|
|
704
|
+
now - p.lastSeenAt >= _stateLlmV2.profileIdleMs
|
|
705
|
+
) {
|
|
706
|
+
p.status = PROVIDER_MATURITY_V2.SUSPENDED;
|
|
707
|
+
p.lastSeenAt = now;
|
|
708
|
+
flipped.push(p.id);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
return { flipped, count: flipped.length };
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
export function autoFailStuckRequestsV2({ now = Date.now() } = {}) {
|
|
715
|
+
const flipped = [];
|
|
716
|
+
for (const r of _stateLlmV2.requests.values()) {
|
|
717
|
+
if (
|
|
718
|
+
r.status === REQUEST_LIFECYCLE_V2.RUNNING &&
|
|
719
|
+
r.startedAt &&
|
|
720
|
+
now - r.startedAt >= _stateLlmV2.requestStuckMs
|
|
721
|
+
) {
|
|
722
|
+
r.status = REQUEST_LIFECYCLE_V2.FAILED;
|
|
723
|
+
r.lastSeenAt = now;
|
|
724
|
+
if (!r.settledAt) r.settledAt = now;
|
|
725
|
+
flipped.push(r.id);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
return { flipped, count: flipped.length };
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
export function getLlmProvidersStatsV2() {
|
|
732
|
+
const profilesByStatus = {};
|
|
733
|
+
for (const s of Object.values(PROVIDER_MATURITY_V2)) profilesByStatus[s] = 0;
|
|
734
|
+
for (const p of _stateLlmV2.profiles.values()) profilesByStatus[p.status]++;
|
|
735
|
+
const requestsByStatus = {};
|
|
736
|
+
for (const s of Object.values(REQUEST_LIFECYCLE_V2)) requestsByStatus[s] = 0;
|
|
737
|
+
for (const r of _stateLlmV2.requests.values()) requestsByStatus[r.status]++;
|
|
738
|
+
return {
|
|
739
|
+
totalProfilesV2: _stateLlmV2.profiles.size,
|
|
740
|
+
totalRequestsV2: _stateLlmV2.requests.size,
|
|
741
|
+
maxActiveProfilesPerOwner: _stateLlmV2.maxActiveProfilesPerOwner,
|
|
742
|
+
maxPendingRequestsPerProfile: _stateLlmV2.maxPendingRequestsPerProfile,
|
|
743
|
+
profileIdleMs: _stateLlmV2.profileIdleMs,
|
|
744
|
+
requestStuckMs: _stateLlmV2.requestStuckMs,
|
|
745
|
+
profilesByStatus,
|
|
746
|
+
requestsByStatus,
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
export function _resetStateLlmProvidersV2() {
|
|
751
|
+
_stateLlmV2.profiles.clear();
|
|
752
|
+
_stateLlmV2.requests.clear();
|
|
753
|
+
_stateLlmV2.maxActiveProfilesPerOwner = PROVIDER_DEFAULT_MAX_ACTIVE_PER_OWNER;
|
|
754
|
+
_stateLlmV2.maxPendingRequestsPerProfile =
|
|
755
|
+
PROVIDER_DEFAULT_MAX_PENDING_REQUESTS_PER_PROFILE;
|
|
756
|
+
_stateLlmV2.profileIdleMs = PROVIDER_DEFAULT_PROFILE_IDLE_MS;
|
|
757
|
+
_stateLlmV2.requestStuckMs = PROVIDER_DEFAULT_REQUEST_STUCK_MS;
|
|
758
|
+
}
|
package/src/lib/matrix-bridge.js
CHANGED
|
@@ -446,3 +446,108 @@ export function _resetState() {
|
|
|
446
446
|
e2eeEnabled: true,
|
|
447
447
|
};
|
|
448
448
|
}
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
// ===== V2 Surface: Matrix Bridge governance overlay (CLI v0.134.0) =====
|
|
452
|
+
export const MX_ROOM_MATURITY_V2 = Object.freeze({
|
|
453
|
+
PENDING: "pending", ACTIVE: "active", MUTED: "muted", ARCHIVED: "archived",
|
|
454
|
+
});
|
|
455
|
+
export const MX_MESSAGE_LIFECYCLE_V2 = Object.freeze({
|
|
456
|
+
QUEUED: "queued", SENDING: "sending", DELIVERED: "delivered", FAILED: "failed", CANCELLED: "cancelled",
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
const _mxRoomTrans = new Map([
|
|
460
|
+
[MX_ROOM_MATURITY_V2.PENDING, new Set([MX_ROOM_MATURITY_V2.ACTIVE, MX_ROOM_MATURITY_V2.ARCHIVED])],
|
|
461
|
+
[MX_ROOM_MATURITY_V2.ACTIVE, new Set([MX_ROOM_MATURITY_V2.MUTED, MX_ROOM_MATURITY_V2.ARCHIVED])],
|
|
462
|
+
[MX_ROOM_MATURITY_V2.MUTED, new Set([MX_ROOM_MATURITY_V2.ACTIVE, MX_ROOM_MATURITY_V2.ARCHIVED])],
|
|
463
|
+
[MX_ROOM_MATURITY_V2.ARCHIVED, new Set()],
|
|
464
|
+
]);
|
|
465
|
+
const _mxRoomTerminal = new Set([MX_ROOM_MATURITY_V2.ARCHIVED]);
|
|
466
|
+
const _mxMsgTrans = new Map([
|
|
467
|
+
[MX_MESSAGE_LIFECYCLE_V2.QUEUED, new Set([MX_MESSAGE_LIFECYCLE_V2.SENDING, MX_MESSAGE_LIFECYCLE_V2.CANCELLED])],
|
|
468
|
+
[MX_MESSAGE_LIFECYCLE_V2.SENDING, new Set([MX_MESSAGE_LIFECYCLE_V2.DELIVERED, MX_MESSAGE_LIFECYCLE_V2.FAILED, MX_MESSAGE_LIFECYCLE_V2.CANCELLED])],
|
|
469
|
+
[MX_MESSAGE_LIFECYCLE_V2.DELIVERED, new Set()],
|
|
470
|
+
[MX_MESSAGE_LIFECYCLE_V2.FAILED, new Set()],
|
|
471
|
+
[MX_MESSAGE_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
472
|
+
]);
|
|
473
|
+
|
|
474
|
+
const _mxRooms = new Map();
|
|
475
|
+
const _mxMsgs = new Map();
|
|
476
|
+
let _mxMaxActivePerOwner = 20;
|
|
477
|
+
let _mxMaxPendingPerRoom = 40;
|
|
478
|
+
let _mxRoomIdleMs = 24 * 60 * 60 * 1000;
|
|
479
|
+
let _mxMsgStuckMs = 3 * 60 * 1000;
|
|
480
|
+
|
|
481
|
+
function _mxPos(n, lbl) { const v = Math.floor(Number(n)); if (!Number.isFinite(v) || v <= 0) throw new Error(`${lbl} must be positive integer`); return v; }
|
|
482
|
+
|
|
483
|
+
export function setMaxActiveMatrixRoomsPerOwnerV2(n) { _mxMaxActivePerOwner = _mxPos(n, "maxActiveMatrixRoomsPerOwner"); }
|
|
484
|
+
export function getMaxActiveMatrixRoomsPerOwnerV2() { return _mxMaxActivePerOwner; }
|
|
485
|
+
export function setMaxPendingMatrixMessagesPerRoomV2(n) { _mxMaxPendingPerRoom = _mxPos(n, "maxPendingMatrixMessagesPerRoom"); }
|
|
486
|
+
export function getMaxPendingMatrixMessagesPerRoomV2() { return _mxMaxPendingPerRoom; }
|
|
487
|
+
export function setMatrixRoomIdleMsV2(n) { _mxRoomIdleMs = _mxPos(n, "matrixRoomIdleMs"); }
|
|
488
|
+
export function getMatrixRoomIdleMsV2() { return _mxRoomIdleMs; }
|
|
489
|
+
export function setMatrixMessageStuckMsV2(n) { _mxMsgStuckMs = _mxPos(n, "matrixMessageStuckMs"); }
|
|
490
|
+
export function getMatrixMessageStuckMsV2() { return _mxMsgStuckMs; }
|
|
491
|
+
|
|
492
|
+
export function _resetStateMatrixBridgeV2() {
|
|
493
|
+
_mxRooms.clear(); _mxMsgs.clear();
|
|
494
|
+
_mxMaxActivePerOwner = 20; _mxMaxPendingPerRoom = 40;
|
|
495
|
+
_mxRoomIdleMs = 24 * 60 * 60 * 1000; _mxMsgStuckMs = 3 * 60 * 1000;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
export function registerMatrixRoomV2({ id, owner, alias, metadata } = {}) {
|
|
499
|
+
if (!id || typeof id !== "string") throw new Error("id is required");
|
|
500
|
+
if (!owner || typeof owner !== "string") throw new Error("owner is required");
|
|
501
|
+
if (_mxRooms.has(id)) throw new Error(`matrix room ${id} already registered`);
|
|
502
|
+
const now = Date.now();
|
|
503
|
+
const r = { id, owner, alias: alias || id, status: MX_ROOM_MATURITY_V2.PENDING, createdAt: now, updatedAt: now, activatedAt: null, archivedAt: null, lastTouchedAt: now, metadata: { ...(metadata || {}) } };
|
|
504
|
+
_mxRooms.set(id, r);
|
|
505
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
506
|
+
}
|
|
507
|
+
function _mxCheckR(from, to) { const a = _mxRoomTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid matrix room transition ${from} → ${to}`); }
|
|
508
|
+
function _mxCountActive(owner) { let n = 0; for (const r of _mxRooms.values()) if (r.owner === owner && r.status === MX_ROOM_MATURITY_V2.ACTIVE) n++; return n; }
|
|
509
|
+
|
|
510
|
+
export function activateMatrixRoomV2(id) {
|
|
511
|
+
const r = _mxRooms.get(id); if (!r) throw new Error(`matrix room ${id} not found`);
|
|
512
|
+
_mxCheckR(r.status, MX_ROOM_MATURITY_V2.ACTIVE);
|
|
513
|
+
const recovery = r.status === MX_ROOM_MATURITY_V2.MUTED;
|
|
514
|
+
if (!recovery) { const a = _mxCountActive(r.owner); if (a >= _mxMaxActivePerOwner) throw new Error(`max active matrix rooms per owner (${_mxMaxActivePerOwner}) reached for ${r.owner}`); }
|
|
515
|
+
const now = Date.now(); r.status = MX_ROOM_MATURITY_V2.ACTIVE; r.updatedAt = now; r.lastTouchedAt = now; if (!r.activatedAt) r.activatedAt = now;
|
|
516
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
517
|
+
}
|
|
518
|
+
export function muteMatrixRoomV2(id) { const r = _mxRooms.get(id); if (!r) throw new Error(`matrix room ${id} not found`); _mxCheckR(r.status, MX_ROOM_MATURITY_V2.MUTED); r.status = MX_ROOM_MATURITY_V2.MUTED; r.updatedAt = Date.now(); return { ...r, metadata: { ...r.metadata } }; }
|
|
519
|
+
export function archiveMatrixRoomV2(id) { const r = _mxRooms.get(id); if (!r) throw new Error(`matrix room ${id} not found`); _mxCheckR(r.status, MX_ROOM_MATURITY_V2.ARCHIVED); const now = Date.now(); r.status = MX_ROOM_MATURITY_V2.ARCHIVED; r.updatedAt = now; if (!r.archivedAt) r.archivedAt = now; return { ...r, metadata: { ...r.metadata } }; }
|
|
520
|
+
export function touchMatrixRoomV2(id) { const r = _mxRooms.get(id); if (!r) throw new Error(`matrix room ${id} not found`); if (_mxRoomTerminal.has(r.status)) throw new Error(`cannot touch terminal matrix room ${id}`); const now = Date.now(); r.lastTouchedAt = now; r.updatedAt = now; return { ...r, metadata: { ...r.metadata } }; }
|
|
521
|
+
export function getMatrixRoomV2(id) { const r = _mxRooms.get(id); if (!r) return null; return { ...r, metadata: { ...r.metadata } }; }
|
|
522
|
+
export function listMatrixRoomsV2() { return [..._mxRooms.values()].map((r) => ({ ...r, metadata: { ...r.metadata } })); }
|
|
523
|
+
|
|
524
|
+
function _mxCountPending(rid) { let n = 0; for (const m of _mxMsgs.values()) if (m.roomId === rid && (m.status === MX_MESSAGE_LIFECYCLE_V2.QUEUED || m.status === MX_MESSAGE_LIFECYCLE_V2.SENDING)) n++; return n; }
|
|
525
|
+
|
|
526
|
+
export function createMatrixMessageV2({ id, roomId, body, metadata } = {}) {
|
|
527
|
+
if (!id || typeof id !== "string") throw new Error("id is required");
|
|
528
|
+
if (!roomId || typeof roomId !== "string") throw new Error("roomId is required");
|
|
529
|
+
if (_mxMsgs.has(id)) throw new Error(`matrix message ${id} already exists`);
|
|
530
|
+
if (!_mxRooms.has(roomId)) throw new Error(`matrix room ${roomId} not found`);
|
|
531
|
+
const pending = _mxCountPending(roomId);
|
|
532
|
+
if (pending >= _mxMaxPendingPerRoom) throw new Error(`max pending matrix messages per room (${_mxMaxPendingPerRoom}) reached for ${roomId}`);
|
|
533
|
+
const now = Date.now();
|
|
534
|
+
const m = { id, roomId, body: body || "", status: MX_MESSAGE_LIFECYCLE_V2.QUEUED, createdAt: now, updatedAt: now, startedAt: null, settledAt: null, metadata: { ...(metadata || {}) } };
|
|
535
|
+
_mxMsgs.set(id, m);
|
|
536
|
+
return { ...m, metadata: { ...m.metadata } };
|
|
537
|
+
}
|
|
538
|
+
function _mxCheckM(from, to) { const a = _mxMsgTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid matrix message transition ${from} → ${to}`); }
|
|
539
|
+
export function startMatrixMessageV2(id) { const m = _mxMsgs.get(id); if (!m) throw new Error(`matrix message ${id} not found`); _mxCheckM(m.status, MX_MESSAGE_LIFECYCLE_V2.SENDING); const now = Date.now(); m.status = MX_MESSAGE_LIFECYCLE_V2.SENDING; m.updatedAt = now; if (!m.startedAt) m.startedAt = now; return { ...m, metadata: { ...m.metadata } }; }
|
|
540
|
+
export function deliverMatrixMessageV2(id) { const m = _mxMsgs.get(id); if (!m) throw new Error(`matrix message ${id} not found`); _mxCheckM(m.status, MX_MESSAGE_LIFECYCLE_V2.DELIVERED); const now = Date.now(); m.status = MX_MESSAGE_LIFECYCLE_V2.DELIVERED; m.updatedAt = now; if (!m.settledAt) m.settledAt = now; return { ...m, metadata: { ...m.metadata } }; }
|
|
541
|
+
export function failMatrixMessageV2(id, reason) { const m = _mxMsgs.get(id); if (!m) throw new Error(`matrix message ${id} not found`); _mxCheckM(m.status, MX_MESSAGE_LIFECYCLE_V2.FAILED); const now = Date.now(); m.status = MX_MESSAGE_LIFECYCLE_V2.FAILED; m.updatedAt = now; if (!m.settledAt) m.settledAt = now; if (reason) m.metadata.failReason = String(reason); return { ...m, metadata: { ...m.metadata } }; }
|
|
542
|
+
export function cancelMatrixMessageV2(id, reason) { const m = _mxMsgs.get(id); if (!m) throw new Error(`matrix message ${id} not found`); _mxCheckM(m.status, MX_MESSAGE_LIFECYCLE_V2.CANCELLED); const now = Date.now(); m.status = MX_MESSAGE_LIFECYCLE_V2.CANCELLED; m.updatedAt = now; if (!m.settledAt) m.settledAt = now; if (reason) m.metadata.cancelReason = String(reason); return { ...m, metadata: { ...m.metadata } }; }
|
|
543
|
+
export function getMatrixMessageV2(id) { const m = _mxMsgs.get(id); if (!m) return null; return { ...m, metadata: { ...m.metadata } }; }
|
|
544
|
+
export function listMatrixMessagesV2() { return [..._mxMsgs.values()].map((m) => ({ ...m, metadata: { ...m.metadata } })); }
|
|
545
|
+
|
|
546
|
+
export function autoMuteIdleMatrixRoomsV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const r of _mxRooms.values()) if (r.status === MX_ROOM_MATURITY_V2.ACTIVE && (t - r.lastTouchedAt) >= _mxRoomIdleMs) { r.status = MX_ROOM_MATURITY_V2.MUTED; r.updatedAt = t; flipped.push(r.id); } return { flipped, count: flipped.length }; }
|
|
547
|
+
export function autoFailStuckMatrixMessagesV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const m of _mxMsgs.values()) if (m.status === MX_MESSAGE_LIFECYCLE_V2.SENDING && m.startedAt != null && (t - m.startedAt) >= _mxMsgStuckMs) { m.status = MX_MESSAGE_LIFECYCLE_V2.FAILED; m.updatedAt = t; if (!m.settledAt) m.settledAt = t; m.metadata.failReason = "auto-fail-stuck"; flipped.push(m.id); } return { flipped, count: flipped.length }; }
|
|
548
|
+
|
|
549
|
+
export function getMatrixBridgeStatsV2() {
|
|
550
|
+
const roomsByStatus = {}; for (const s of Object.values(MX_ROOM_MATURITY_V2)) roomsByStatus[s] = 0; for (const r of _mxRooms.values()) roomsByStatus[r.status]++;
|
|
551
|
+
const msgsByStatus = {}; for (const s of Object.values(MX_MESSAGE_LIFECYCLE_V2)) msgsByStatus[s] = 0; for (const m of _mxMsgs.values()) msgsByStatus[m.status]++;
|
|
552
|
+
return { totalRoomsV2: _mxRooms.size, totalMessagesV2: _mxMsgs.size, maxActiveMatrixRoomsPerOwner: _mxMaxActivePerOwner, maxPendingMatrixMessagesPerRoom: _mxMaxPendingPerRoom, matrixRoomIdleMs: _mxRoomIdleMs, matrixMessageStuckMs: _mxMsgStuckMs, roomsByStatus, msgsByStatus };
|
|
553
|
+
}
|