chainlesschain 0.81.0 → 0.132.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/agent-network.js +254 -1
- package/src/commands/audit.js +302 -0
- package/src/commands/automation.js +271 -1
- package/src/commands/codegen.js +224 -0
- package/src/commands/collab.js +341 -0
- package/src/commands/compliance.js +1035 -0
- package/src/commands/cowork.js +221 -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/encrypt.js +341 -0
- package/src/commands/export.js +256 -1
- package/src/commands/fusion.js +258 -0
- package/src/commands/governance.js +325 -0
- package/src/commands/hardening.js +411 -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/infra.js +244 -0
- package/src/commands/instinct.js +260 -0
- package/src/commands/ipfs.js +318 -0
- package/src/commands/kg.js +387 -0
- package/src/commands/llm.js +263 -0
- package/src/commands/mcp.js +221 -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/note.js +244 -0
- package/src/commands/ops.js +354 -0
- package/src/commands/orchestrate.js +166 -0
- package/src/commands/org.js +277 -0
- package/src/commands/p2p.js +390 -0
- package/src/commands/perception.js +290 -0
- package/src/commands/permmem.js +251 -0
- package/src/commands/plugin-ecosystem.js +273 -0
- package/src/commands/pqc.js +393 -0
- package/src/commands/quantization.js +351 -0
- package/src/commands/rcache.js +271 -0
- package/src/commands/recommend.js +340 -0
- package/src/commands/runtime.js +307 -0
- package/src/commands/scim.js +262 -0
- package/src/commands/session.js +258 -0
- package/src/commands/skill.js +267 -1
- package/src/commands/social.js +256 -0
- package/src/commands/sso.js +186 -1
- package/src/commands/sync.js +256 -0
- package/src/commands/tech.js +338 -0
- package/src/commands/tenant.js +351 -0
- package/src/commands/tokens.js +269 -0
- package/src/commands/trust.js +249 -0
- package/src/commands/wallet.js +277 -0
- package/src/commands/workflow.js +171 -0
- package/src/index.js +4 -0
- package/src/lib/agent-coordinator.js +325 -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/audit-logger.js +379 -0
- package/src/lib/automation-engine.js +330 -0
- package/src/lib/autonomous-developer.js +350 -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-manager.js +434 -0
- package/src/lib/content-recommendation.js +469 -0
- package/src/lib/crypto-manager.js +350 -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/hardening-manager.js +348 -0
- package/src/lib/hook-manager.js +380 -0
- package/src/lib/instinct-manager.js +332 -0
- package/src/lib/ipfs-storage.js +334 -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/mcp-registry.js +333 -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/note-versioning.js +327 -0
- package/src/lib/org-manager.js +323 -0
- package/src/lib/p2p-manager.js +387 -0
- package/src/lib/perception.js +346 -0
- package/src/lib/perf-tuning.js +4 -1
- package/src/lib/permanent-memory.js +320 -0
- package/src/lib/plugin-ecosystem.js +377 -0
- package/src/lib/pqc-manager.js +368 -0
- 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/session-manager.js +329 -0
- package/src/lib/skill-loader.js +377 -0
- package/src/lib/social-manager.js +326 -0
- package/src/lib/sso-manager.js +332 -0
- package/src/lib/sync-manager.js +326 -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/token-incentive.js +293 -0
- package/src/lib/token-tracker.js +329 -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/wallet-manager.js +326 -0
- package/src/lib/workflow-engine.js +322 -0
|
@@ -522,3 +522,353 @@ export function _resetState() {
|
|
|
522
522
|
_adrs.clear();
|
|
523
523
|
_seq = 0;
|
|
524
524
|
}
|
|
525
|
+
|
|
526
|
+
/* ── V2 Surface (Autonomous Developer) ─────────────────────
|
|
527
|
+
* Strictly additive. Two parallel state machines:
|
|
528
|
+
* - ADR maturity (4 states, superseded terminal)
|
|
529
|
+
* - Dev session V2 lifecycle (5 states, 3 terminals)
|
|
530
|
+
* Per-author active-ADR cap + per-developer running-session cap.
|
|
531
|
+
* Auto-flip: stale draft ADRs → superseded; stuck running sessions → failed.
|
|
532
|
+
*/
|
|
533
|
+
|
|
534
|
+
export const ADR_MATURITY_V2 = Object.freeze({
|
|
535
|
+
DRAFT: "draft",
|
|
536
|
+
ACCEPTED: "accepted",
|
|
537
|
+
DEPRECATED: "deprecated",
|
|
538
|
+
SUPERSEDED: "superseded",
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
export const DEV_SESSION_V2 = Object.freeze({
|
|
542
|
+
QUEUED: "queued",
|
|
543
|
+
RUNNING: "running",
|
|
544
|
+
COMPLETED: "completed",
|
|
545
|
+
FAILED: "failed",
|
|
546
|
+
CANCELED: "canceled",
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
const _ADR_TRANSITIONS_V2 = new Map([
|
|
550
|
+
[
|
|
551
|
+
ADR_MATURITY_V2.DRAFT,
|
|
552
|
+
new Set([ADR_MATURITY_V2.ACCEPTED, ADR_MATURITY_V2.SUPERSEDED]),
|
|
553
|
+
],
|
|
554
|
+
[
|
|
555
|
+
ADR_MATURITY_V2.ACCEPTED,
|
|
556
|
+
new Set([ADR_MATURITY_V2.DEPRECATED, ADR_MATURITY_V2.SUPERSEDED]),
|
|
557
|
+
],
|
|
558
|
+
[
|
|
559
|
+
ADR_MATURITY_V2.DEPRECATED,
|
|
560
|
+
new Set([ADR_MATURITY_V2.ACCEPTED, ADR_MATURITY_V2.SUPERSEDED]),
|
|
561
|
+
],
|
|
562
|
+
]);
|
|
563
|
+
const _ADR_TERMINAL_V2 = new Set([ADR_MATURITY_V2.SUPERSEDED]);
|
|
564
|
+
|
|
565
|
+
const _SESSION_TRANSITIONS_V2 = new Map([
|
|
566
|
+
[
|
|
567
|
+
DEV_SESSION_V2.QUEUED,
|
|
568
|
+
new Set([
|
|
569
|
+
DEV_SESSION_V2.RUNNING,
|
|
570
|
+
DEV_SESSION_V2.CANCELED,
|
|
571
|
+
DEV_SESSION_V2.FAILED,
|
|
572
|
+
]),
|
|
573
|
+
],
|
|
574
|
+
[
|
|
575
|
+
DEV_SESSION_V2.RUNNING,
|
|
576
|
+
new Set([
|
|
577
|
+
DEV_SESSION_V2.COMPLETED,
|
|
578
|
+
DEV_SESSION_V2.FAILED,
|
|
579
|
+
DEV_SESSION_V2.CANCELED,
|
|
580
|
+
]),
|
|
581
|
+
],
|
|
582
|
+
]);
|
|
583
|
+
const _SESSION_TERMINAL_V2 = new Set([
|
|
584
|
+
DEV_SESSION_V2.COMPLETED,
|
|
585
|
+
DEV_SESSION_V2.FAILED,
|
|
586
|
+
DEV_SESSION_V2.CANCELED,
|
|
587
|
+
]);
|
|
588
|
+
|
|
589
|
+
export const AD_DEFAULT_MAX_ACTIVE_ADRS_PER_AUTHOR = 20;
|
|
590
|
+
export const AD_DEFAULT_MAX_RUNNING_SESSIONS_PER_DEVELOPER = 3;
|
|
591
|
+
export const AD_DEFAULT_ADR_STALE_MS = 90 * 86400000;
|
|
592
|
+
export const AD_DEFAULT_SESSION_STUCK_MS = 2 * 3600000;
|
|
593
|
+
|
|
594
|
+
let _adMaxActiveAdrsPerAuthor = AD_DEFAULT_MAX_ACTIVE_ADRS_PER_AUTHOR;
|
|
595
|
+
let _adMaxRunningSessionsPerDeveloper =
|
|
596
|
+
AD_DEFAULT_MAX_RUNNING_SESSIONS_PER_DEVELOPER;
|
|
597
|
+
let _adAdrStaleMs = AD_DEFAULT_ADR_STALE_MS;
|
|
598
|
+
let _adSessionStuckMs = AD_DEFAULT_SESSION_STUCK_MS;
|
|
599
|
+
|
|
600
|
+
const _adrsV2 = new Map();
|
|
601
|
+
const _sessionsV2 = new Map();
|
|
602
|
+
|
|
603
|
+
function _positiveIntV2(n, label) {
|
|
604
|
+
const f = Math.floor(n);
|
|
605
|
+
if (!Number.isFinite(f) || f <= 0)
|
|
606
|
+
throw new Error(`${label} must be a positive integer`);
|
|
607
|
+
return f;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
function _now() {
|
|
611
|
+
return Date.now();
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
export function getMaxActiveAdrsPerAuthor() {
|
|
615
|
+
return _adMaxActiveAdrsPerAuthor;
|
|
616
|
+
}
|
|
617
|
+
export function setMaxActiveAdrsPerAuthor(n) {
|
|
618
|
+
_adMaxActiveAdrsPerAuthor = _positiveIntV2(n, "maxActiveAdrsPerAuthor");
|
|
619
|
+
return _adMaxActiveAdrsPerAuthor;
|
|
620
|
+
}
|
|
621
|
+
export function getMaxRunningSessionsPerDeveloper() {
|
|
622
|
+
return _adMaxRunningSessionsPerDeveloper;
|
|
623
|
+
}
|
|
624
|
+
export function setMaxRunningSessionsPerDeveloper(n) {
|
|
625
|
+
_adMaxRunningSessionsPerDeveloper = _positiveIntV2(
|
|
626
|
+
n,
|
|
627
|
+
"maxRunningSessionsPerDeveloper",
|
|
628
|
+
);
|
|
629
|
+
return _adMaxRunningSessionsPerDeveloper;
|
|
630
|
+
}
|
|
631
|
+
export function getAdrStaleMs() {
|
|
632
|
+
return _adAdrStaleMs;
|
|
633
|
+
}
|
|
634
|
+
export function setAdrStaleMs(n) {
|
|
635
|
+
_adAdrStaleMs = _positiveIntV2(n, "adrStaleMs");
|
|
636
|
+
return _adAdrStaleMs;
|
|
637
|
+
}
|
|
638
|
+
export function getSessionStuckMs() {
|
|
639
|
+
return _adSessionStuckMs;
|
|
640
|
+
}
|
|
641
|
+
export function setSessionStuckMs(n) {
|
|
642
|
+
_adSessionStuckMs = _positiveIntV2(n, "sessionStuckMs");
|
|
643
|
+
return _adSessionStuckMs;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
export function getActiveAdrCount(author) {
|
|
647
|
+
let c = 0;
|
|
648
|
+
for (const a of _adrsV2.values()) {
|
|
649
|
+
if (_ADR_TERMINAL_V2.has(a.status)) continue;
|
|
650
|
+
if (author !== undefined && a.author !== author) continue;
|
|
651
|
+
c++;
|
|
652
|
+
}
|
|
653
|
+
return c;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
export function getRunningSessionCount(developer) {
|
|
657
|
+
let c = 0;
|
|
658
|
+
for (const s of _sessionsV2.values()) {
|
|
659
|
+
if (s.status !== DEV_SESSION_V2.RUNNING) continue;
|
|
660
|
+
if (developer !== undefined && s.developer !== developer) continue;
|
|
661
|
+
c++;
|
|
662
|
+
}
|
|
663
|
+
return c;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
export function createAdrV2({
|
|
667
|
+
id,
|
|
668
|
+
author,
|
|
669
|
+
title,
|
|
670
|
+
initialStatus,
|
|
671
|
+
metadata,
|
|
672
|
+
} = {}) {
|
|
673
|
+
if (!id) throw new Error("id required");
|
|
674
|
+
if (!author) throw new Error("author required");
|
|
675
|
+
if (!title) throw new Error("title required");
|
|
676
|
+
if (_adrsV2.has(id)) throw new Error(`ADR ${id} already exists`);
|
|
677
|
+
const status = initialStatus ?? ADR_MATURITY_V2.DRAFT;
|
|
678
|
+
if (!Object.values(ADR_MATURITY_V2).includes(status))
|
|
679
|
+
throw new Error(`invalid initial status ${status}`);
|
|
680
|
+
if (
|
|
681
|
+
!_ADR_TERMINAL_V2.has(status) &&
|
|
682
|
+
getActiveAdrCount(author) >= _adMaxActiveAdrsPerAuthor
|
|
683
|
+
)
|
|
684
|
+
throw new Error(`author ${author} active ADR cap reached`);
|
|
685
|
+
const now = _now();
|
|
686
|
+
const a = {
|
|
687
|
+
id,
|
|
688
|
+
author,
|
|
689
|
+
title,
|
|
690
|
+
status,
|
|
691
|
+
metadata: metadata ? { ...metadata } : {},
|
|
692
|
+
createdAt: now,
|
|
693
|
+
updatedAt: now,
|
|
694
|
+
acceptedAt: status === ADR_MATURITY_V2.ACCEPTED ? now : null,
|
|
695
|
+
};
|
|
696
|
+
_adrsV2.set(id, a);
|
|
697
|
+
return { ...a, metadata: { ...a.metadata } };
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
export function getAdrV2(id) {
|
|
701
|
+
const a = _adrsV2.get(id);
|
|
702
|
+
return a ? { ...a, metadata: { ...a.metadata } } : null;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
export function listAdrsV2({ author, status } = {}) {
|
|
706
|
+
const out = [];
|
|
707
|
+
for (const a of _adrsV2.values()) {
|
|
708
|
+
if (author !== undefined && a.author !== author) continue;
|
|
709
|
+
if (status !== undefined && a.status !== status) continue;
|
|
710
|
+
out.push({ ...a, metadata: { ...a.metadata } });
|
|
711
|
+
}
|
|
712
|
+
return out;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
export function setAdrMaturityV2(id, nextStatus, { reason, metadata } = {}) {
|
|
716
|
+
const a = _adrsV2.get(id);
|
|
717
|
+
if (!a) throw new Error(`ADR ${id} not found`);
|
|
718
|
+
if (_ADR_TERMINAL_V2.has(a.status))
|
|
719
|
+
throw new Error(`ADR ${id} is terminal (${a.status})`);
|
|
720
|
+
const allowed = _ADR_TRANSITIONS_V2.get(a.status);
|
|
721
|
+
if (!allowed || !allowed.has(nextStatus))
|
|
722
|
+
throw new Error(`illegal transition ${a.status} → ${nextStatus}`);
|
|
723
|
+
a.status = nextStatus;
|
|
724
|
+
a.updatedAt = _now();
|
|
725
|
+
if (reason !== undefined) a.reason = reason;
|
|
726
|
+
if (metadata) a.metadata = { ...a.metadata, ...metadata };
|
|
727
|
+
if (nextStatus === ADR_MATURITY_V2.ACCEPTED && !a.acceptedAt)
|
|
728
|
+
a.acceptedAt = a.updatedAt;
|
|
729
|
+
return { ...a, metadata: { ...a.metadata } };
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
export function acceptAdr(id, opts) {
|
|
733
|
+
return setAdrMaturityV2(id, ADR_MATURITY_V2.ACCEPTED, opts);
|
|
734
|
+
}
|
|
735
|
+
export function deprecateAdr(id, opts) {
|
|
736
|
+
return setAdrMaturityV2(id, ADR_MATURITY_V2.DEPRECATED, opts);
|
|
737
|
+
}
|
|
738
|
+
export function supersedeAdr(id, opts) {
|
|
739
|
+
return setAdrMaturityV2(id, ADR_MATURITY_V2.SUPERSEDED, opts);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
export function enqueueSessionV2({ id, developer, goal, metadata } = {}) {
|
|
743
|
+
if (!id) throw new Error("id required");
|
|
744
|
+
if (!developer) throw new Error("developer required");
|
|
745
|
+
if (!goal) throw new Error("goal required");
|
|
746
|
+
if (_sessionsV2.has(id)) throw new Error(`session ${id} already exists`);
|
|
747
|
+
const now = _now();
|
|
748
|
+
const s = {
|
|
749
|
+
id,
|
|
750
|
+
developer,
|
|
751
|
+
goal,
|
|
752
|
+
status: DEV_SESSION_V2.QUEUED,
|
|
753
|
+
metadata: metadata ? { ...metadata } : {},
|
|
754
|
+
createdAt: now,
|
|
755
|
+
updatedAt: now,
|
|
756
|
+
startedAt: null,
|
|
757
|
+
};
|
|
758
|
+
_sessionsV2.set(id, s);
|
|
759
|
+
return { ...s, metadata: { ...s.metadata } };
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
export function getSessionV2(id) {
|
|
763
|
+
const s = _sessionsV2.get(id);
|
|
764
|
+
return s ? { ...s, metadata: { ...s.metadata } } : null;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
export function listSessionsV2({ developer, status } = {}) {
|
|
768
|
+
const out = [];
|
|
769
|
+
for (const s of _sessionsV2.values()) {
|
|
770
|
+
if (developer !== undefined && s.developer !== developer) continue;
|
|
771
|
+
if (status !== undefined && s.status !== status) continue;
|
|
772
|
+
out.push({ ...s, metadata: { ...s.metadata } });
|
|
773
|
+
}
|
|
774
|
+
return out;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
export function setSessionStatusV2(id, nextStatus, { reason, metadata } = {}) {
|
|
778
|
+
const s = _sessionsV2.get(id);
|
|
779
|
+
if (!s) throw new Error(`session ${id} not found`);
|
|
780
|
+
if (_SESSION_TERMINAL_V2.has(s.status))
|
|
781
|
+
throw new Error(`session ${id} is terminal (${s.status})`);
|
|
782
|
+
const allowed = _SESSION_TRANSITIONS_V2.get(s.status);
|
|
783
|
+
if (!allowed || !allowed.has(nextStatus))
|
|
784
|
+
throw new Error(`illegal transition ${s.status} → ${nextStatus}`);
|
|
785
|
+
if (nextStatus === DEV_SESSION_V2.RUNNING) {
|
|
786
|
+
if (
|
|
787
|
+
getRunningSessionCount(s.developer) >= _adMaxRunningSessionsPerDeveloper
|
|
788
|
+
)
|
|
789
|
+
throw new Error(`developer ${s.developer} running session cap reached`);
|
|
790
|
+
}
|
|
791
|
+
s.status = nextStatus;
|
|
792
|
+
s.updatedAt = _now();
|
|
793
|
+
if (reason !== undefined) s.reason = reason;
|
|
794
|
+
if (metadata) s.metadata = { ...s.metadata, ...metadata };
|
|
795
|
+
if (nextStatus === DEV_SESSION_V2.RUNNING && !s.startedAt)
|
|
796
|
+
s.startedAt = s.updatedAt;
|
|
797
|
+
return { ...s, metadata: { ...s.metadata } };
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
export function startSessionV2(id, opts) {
|
|
801
|
+
return setSessionStatusV2(id, DEV_SESSION_V2.RUNNING, opts);
|
|
802
|
+
}
|
|
803
|
+
export function completeSessionV2(id, opts) {
|
|
804
|
+
return setSessionStatusV2(id, DEV_SESSION_V2.COMPLETED, opts);
|
|
805
|
+
}
|
|
806
|
+
export function failSessionV2(id, opts) {
|
|
807
|
+
return setSessionStatusV2(id, DEV_SESSION_V2.FAILED, opts);
|
|
808
|
+
}
|
|
809
|
+
export function cancelSessionV2(id, opts) {
|
|
810
|
+
return setSessionStatusV2(id, DEV_SESSION_V2.CANCELED, opts);
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
export function autoSupersedeStaleDrafts({ now } = {}) {
|
|
814
|
+
const cutoff = (now ?? _now()) - _adAdrStaleMs;
|
|
815
|
+
const flipped = [];
|
|
816
|
+
for (const a of _adrsV2.values()) {
|
|
817
|
+
if (a.status !== ADR_MATURITY_V2.DRAFT) continue;
|
|
818
|
+
if ((a.updatedAt ?? a.createdAt) > cutoff) continue;
|
|
819
|
+
a.status = ADR_MATURITY_V2.SUPERSEDED;
|
|
820
|
+
a.updatedAt = now ?? _now();
|
|
821
|
+
a.reason = "auto_supersede_stale_draft";
|
|
822
|
+
flipped.push(a.id);
|
|
823
|
+
}
|
|
824
|
+
return flipped;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
export function autoFailStuckSessions({ now } = {}) {
|
|
828
|
+
const cutoff = (now ?? _now()) - _adSessionStuckMs;
|
|
829
|
+
const flipped = [];
|
|
830
|
+
for (const s of _sessionsV2.values()) {
|
|
831
|
+
if (s.status !== DEV_SESSION_V2.RUNNING) continue;
|
|
832
|
+
if (!s.startedAt || s.startedAt > cutoff) continue;
|
|
833
|
+
s.status = DEV_SESSION_V2.FAILED;
|
|
834
|
+
s.updatedAt = now ?? _now();
|
|
835
|
+
s.reason = "auto_fail_stuck";
|
|
836
|
+
flipped.push(s.id);
|
|
837
|
+
}
|
|
838
|
+
return flipped;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
function _zeroByEnum(enumObj) {
|
|
842
|
+
const out = {};
|
|
843
|
+
for (const v of Object.values(enumObj)) out[v] = 0;
|
|
844
|
+
return out;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
export function getAutonomousDeveloperStatsV2() {
|
|
848
|
+
const adrs = [..._adrsV2.values()];
|
|
849
|
+
const sessions = [..._sessionsV2.values()];
|
|
850
|
+
const adrsByStatus = _zeroByEnum(ADR_MATURITY_V2);
|
|
851
|
+
for (const a of adrs) adrsByStatus[a.status]++;
|
|
852
|
+
const sessionsByStatus = _zeroByEnum(DEV_SESSION_V2);
|
|
853
|
+
for (const s of sessions) sessionsByStatus[s.status]++;
|
|
854
|
+
return {
|
|
855
|
+
totalAdrsV2: adrs.length,
|
|
856
|
+
totalSessionsV2: sessions.length,
|
|
857
|
+
maxActiveAdrsPerAuthor: _adMaxActiveAdrsPerAuthor,
|
|
858
|
+
maxRunningSessionsPerDeveloper: _adMaxRunningSessionsPerDeveloper,
|
|
859
|
+
adrStaleMs: _adAdrStaleMs,
|
|
860
|
+
sessionStuckMs: _adSessionStuckMs,
|
|
861
|
+
adrsByStatus,
|
|
862
|
+
sessionsByStatus,
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
export function _resetStateV2() {
|
|
867
|
+
_adrsV2.clear();
|
|
868
|
+
_sessionsV2.clear();
|
|
869
|
+
_adMaxActiveAdrsPerAuthor = AD_DEFAULT_MAX_ACTIVE_ADRS_PER_AUTHOR;
|
|
870
|
+
_adMaxRunningSessionsPerDeveloper =
|
|
871
|
+
AD_DEFAULT_MAX_RUNNING_SESSIONS_PER_DEVELOPER;
|
|
872
|
+
_adAdrStaleMs = AD_DEFAULT_ADR_STALE_MS;
|
|
873
|
+
_adSessionStuckMs = AD_DEFAULT_SESSION_STUCK_MS;
|
|
874
|
+
}
|
package/src/lib/code-agent.js
CHANGED
|
@@ -440,3 +440,326 @@ export function _resetState() {
|
|
|
440
440
|
_reviews.clear();
|
|
441
441
|
_scaffolds.clear();
|
|
442
442
|
}
|
|
443
|
+
|
|
444
|
+
/* ═════════════════════════════════════════════════════════ *
|
|
445
|
+
* Phase 86 V2 — Code Agent Maturity + Generation Job
|
|
446
|
+
* ═════════════════════════════════════════════════════════ */
|
|
447
|
+
|
|
448
|
+
export const AGENT_MATURITY_V2 = Object.freeze({
|
|
449
|
+
DRAFT: "draft",
|
|
450
|
+
ACTIVE: "active",
|
|
451
|
+
DEPRECATED: "deprecated",
|
|
452
|
+
RETIRED: "retired",
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
export const GEN_JOB_V2 = Object.freeze({
|
|
456
|
+
QUEUED: "queued",
|
|
457
|
+
RUNNING: "running",
|
|
458
|
+
SUCCEEDED: "succeeded",
|
|
459
|
+
FAILED: "failed",
|
|
460
|
+
CANCELED: "canceled",
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
const AGENT_TRANSITIONS_V2 = new Map([
|
|
464
|
+
["draft", new Set(["active", "retired"])],
|
|
465
|
+
["active", new Set(["deprecated", "retired"])],
|
|
466
|
+
["deprecated", new Set(["active", "retired"])],
|
|
467
|
+
]);
|
|
468
|
+
const AGENT_TERMINALS_V2 = new Set(["retired"]);
|
|
469
|
+
|
|
470
|
+
const JOB_TRANSITIONS_V2 = new Map([
|
|
471
|
+
["queued", new Set(["running", "canceled", "failed"])],
|
|
472
|
+
["running", new Set(["succeeded", "failed", "canceled"])],
|
|
473
|
+
]);
|
|
474
|
+
const JOB_TERMINALS_V2 = new Set(["succeeded", "failed", "canceled"]);
|
|
475
|
+
|
|
476
|
+
export const CGA_DEFAULT_MAX_ACTIVE_AGENTS_PER_OWNER = 15;
|
|
477
|
+
export const CGA_DEFAULT_MAX_RUNNING_JOBS_PER_OWNER = 3;
|
|
478
|
+
export const CGA_DEFAULT_AGENT_IDLE_MS = 60 * 86400000; // 60 days
|
|
479
|
+
export const CGA_DEFAULT_JOB_STUCK_MS = 15 * 60000; // 15 minutes
|
|
480
|
+
|
|
481
|
+
let _maxActiveAgentsPerOwnerV2 = CGA_DEFAULT_MAX_ACTIVE_AGENTS_PER_OWNER;
|
|
482
|
+
let _maxRunningJobsPerOwnerV2 = CGA_DEFAULT_MAX_RUNNING_JOBS_PER_OWNER;
|
|
483
|
+
let _agentIdleMsV2 = CGA_DEFAULT_AGENT_IDLE_MS;
|
|
484
|
+
let _jobStuckMsV2 = CGA_DEFAULT_JOB_STUCK_MS;
|
|
485
|
+
|
|
486
|
+
function _positiveIntV2(n, label) {
|
|
487
|
+
const v = Math.floor(Number(n));
|
|
488
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
489
|
+
throw new Error(`${label} must be a positive integer`);
|
|
490
|
+
return v;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
export function getDefaultMaxActiveAgentsPerOwnerV2() {
|
|
494
|
+
return CGA_DEFAULT_MAX_ACTIVE_AGENTS_PER_OWNER;
|
|
495
|
+
}
|
|
496
|
+
export function getMaxActiveAgentsPerOwnerV2() {
|
|
497
|
+
return _maxActiveAgentsPerOwnerV2;
|
|
498
|
+
}
|
|
499
|
+
export function setMaxActiveAgentsPerOwnerV2(n) {
|
|
500
|
+
return (_maxActiveAgentsPerOwnerV2 = _positiveIntV2(
|
|
501
|
+
n,
|
|
502
|
+
"maxActiveAgentsPerOwner",
|
|
503
|
+
));
|
|
504
|
+
}
|
|
505
|
+
export function getDefaultMaxRunningJobsPerOwnerV2() {
|
|
506
|
+
return CGA_DEFAULT_MAX_RUNNING_JOBS_PER_OWNER;
|
|
507
|
+
}
|
|
508
|
+
export function getMaxRunningJobsPerOwnerV2() {
|
|
509
|
+
return _maxRunningJobsPerOwnerV2;
|
|
510
|
+
}
|
|
511
|
+
export function setMaxRunningJobsPerOwnerV2(n) {
|
|
512
|
+
return (_maxRunningJobsPerOwnerV2 = _positiveIntV2(
|
|
513
|
+
n,
|
|
514
|
+
"maxRunningJobsPerOwner",
|
|
515
|
+
));
|
|
516
|
+
}
|
|
517
|
+
export function getDefaultAgentIdleMsV2() {
|
|
518
|
+
return CGA_DEFAULT_AGENT_IDLE_MS;
|
|
519
|
+
}
|
|
520
|
+
export function getAgentIdleMsV2() {
|
|
521
|
+
return _agentIdleMsV2;
|
|
522
|
+
}
|
|
523
|
+
export function setAgentIdleMsV2(ms) {
|
|
524
|
+
return (_agentIdleMsV2 = _positiveIntV2(ms, "agentIdleMs"));
|
|
525
|
+
}
|
|
526
|
+
export function getDefaultJobStuckMsV2() {
|
|
527
|
+
return CGA_DEFAULT_JOB_STUCK_MS;
|
|
528
|
+
}
|
|
529
|
+
export function getJobStuckMsV2() {
|
|
530
|
+
return _jobStuckMsV2;
|
|
531
|
+
}
|
|
532
|
+
export function setJobStuckMsV2(ms) {
|
|
533
|
+
return (_jobStuckMsV2 = _positiveIntV2(ms, "jobStuckMs"));
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
const _agentsV2 = new Map();
|
|
537
|
+
const _jobsV2 = new Map();
|
|
538
|
+
|
|
539
|
+
export function registerAgentV2(
|
|
540
|
+
_db,
|
|
541
|
+
{ agentId, ownerId, name, initialStatus, metadata } = {},
|
|
542
|
+
) {
|
|
543
|
+
if (!agentId) throw new Error("agentId is required");
|
|
544
|
+
if (!ownerId) throw new Error("ownerId is required");
|
|
545
|
+
if (_agentsV2.has(agentId))
|
|
546
|
+
throw new Error(`Agent ${agentId} already exists`);
|
|
547
|
+
const status = initialStatus || AGENT_MATURITY_V2.DRAFT;
|
|
548
|
+
if (!Object.values(AGENT_MATURITY_V2).includes(status))
|
|
549
|
+
throw new Error(`Invalid initial status: ${status}`);
|
|
550
|
+
if (AGENT_TERMINALS_V2.has(status))
|
|
551
|
+
throw new Error(`Cannot register in terminal status: ${status}`);
|
|
552
|
+
if (status === AGENT_MATURITY_V2.ACTIVE) {
|
|
553
|
+
if (getActiveAgentCount(ownerId) >= _maxActiveAgentsPerOwnerV2)
|
|
554
|
+
throw new Error(
|
|
555
|
+
`Owner ${ownerId} reached active-agent cap (${_maxActiveAgentsPerOwnerV2})`,
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
const now = Date.now();
|
|
559
|
+
const record = {
|
|
560
|
+
agentId,
|
|
561
|
+
ownerId,
|
|
562
|
+
name: name || agentId,
|
|
563
|
+
status,
|
|
564
|
+
metadata: metadata || {},
|
|
565
|
+
createdAt: now,
|
|
566
|
+
updatedAt: now,
|
|
567
|
+
lastInvokedAt: now,
|
|
568
|
+
};
|
|
569
|
+
_agentsV2.set(agentId, record);
|
|
570
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
export function getAgentV2(agentId) {
|
|
574
|
+
const r = _agentsV2.get(agentId);
|
|
575
|
+
return r ? { ...r, metadata: { ...r.metadata } } : null;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
export function setAgentMaturityV2(_db, agentId, newStatus, patch = {}) {
|
|
579
|
+
const record = _agentsV2.get(agentId);
|
|
580
|
+
if (!record) throw new Error(`Unknown agent: ${agentId}`);
|
|
581
|
+
if (!Object.values(AGENT_MATURITY_V2).includes(newStatus))
|
|
582
|
+
throw new Error(`Invalid status: ${newStatus}`);
|
|
583
|
+
const allowed = AGENT_TRANSITIONS_V2.get(record.status) || new Set();
|
|
584
|
+
if (!allowed.has(newStatus))
|
|
585
|
+
throw new Error(`Invalid transition: ${record.status} -> ${newStatus}`);
|
|
586
|
+
if (newStatus === AGENT_MATURITY_V2.ACTIVE) {
|
|
587
|
+
if (getActiveAgentCount(record.ownerId) >= _maxActiveAgentsPerOwnerV2)
|
|
588
|
+
throw new Error(
|
|
589
|
+
`Owner ${record.ownerId} reached active-agent cap (${_maxActiveAgentsPerOwnerV2})`,
|
|
590
|
+
);
|
|
591
|
+
}
|
|
592
|
+
record.status = newStatus;
|
|
593
|
+
record.updatedAt = Date.now();
|
|
594
|
+
if (patch.reason !== undefined) record.lastReason = patch.reason;
|
|
595
|
+
if (patch.metadata)
|
|
596
|
+
record.metadata = { ...record.metadata, ...patch.metadata };
|
|
597
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
export function activateAgent(db, id, reason) {
|
|
601
|
+
return setAgentMaturityV2(db, id, AGENT_MATURITY_V2.ACTIVE, { reason });
|
|
602
|
+
}
|
|
603
|
+
export function deprecateAgent(db, id, reason) {
|
|
604
|
+
return setAgentMaturityV2(db, id, AGENT_MATURITY_V2.DEPRECATED, { reason });
|
|
605
|
+
}
|
|
606
|
+
export function retireAgent(db, id, reason) {
|
|
607
|
+
return setAgentMaturityV2(db, id, AGENT_MATURITY_V2.RETIRED, { reason });
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
export function touchAgentInvocation(agentId) {
|
|
611
|
+
const record = _agentsV2.get(agentId);
|
|
612
|
+
if (!record) throw new Error(`Unknown agent: ${agentId}`);
|
|
613
|
+
record.lastInvokedAt = Date.now();
|
|
614
|
+
record.updatedAt = record.lastInvokedAt;
|
|
615
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
export function enqueueGenJobV2(
|
|
619
|
+
_db,
|
|
620
|
+
{ jobId, ownerId, agentId, prompt, metadata } = {},
|
|
621
|
+
) {
|
|
622
|
+
if (!jobId) throw new Error("jobId is required");
|
|
623
|
+
if (!ownerId) throw new Error("ownerId is required");
|
|
624
|
+
if (!agentId) throw new Error("agentId is required");
|
|
625
|
+
if (!prompt) throw new Error("prompt is required");
|
|
626
|
+
if (_jobsV2.has(jobId)) throw new Error(`Job ${jobId} already exists`);
|
|
627
|
+
const now = Date.now();
|
|
628
|
+
const record = {
|
|
629
|
+
jobId,
|
|
630
|
+
ownerId,
|
|
631
|
+
agentId,
|
|
632
|
+
prompt,
|
|
633
|
+
status: GEN_JOB_V2.QUEUED,
|
|
634
|
+
metadata: metadata || {},
|
|
635
|
+
createdAt: now,
|
|
636
|
+
updatedAt: now,
|
|
637
|
+
};
|
|
638
|
+
_jobsV2.set(jobId, record);
|
|
639
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
export function getGenJobV2(jobId) {
|
|
643
|
+
const r = _jobsV2.get(jobId);
|
|
644
|
+
return r ? { ...r, metadata: { ...r.metadata } } : null;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
export function setGenJobStatusV2(_db, jobId, newStatus, patch = {}) {
|
|
648
|
+
const record = _jobsV2.get(jobId);
|
|
649
|
+
if (!record) throw new Error(`Unknown job: ${jobId}`);
|
|
650
|
+
if (!Object.values(GEN_JOB_V2).includes(newStatus))
|
|
651
|
+
throw new Error(`Invalid status: ${newStatus}`);
|
|
652
|
+
const allowed = JOB_TRANSITIONS_V2.get(record.status) || new Set();
|
|
653
|
+
if (!allowed.has(newStatus))
|
|
654
|
+
throw new Error(`Invalid transition: ${record.status} -> ${newStatus}`);
|
|
655
|
+
if (newStatus === GEN_JOB_V2.RUNNING) {
|
|
656
|
+
if (getRunningJobCount(record.ownerId) >= _maxRunningJobsPerOwnerV2)
|
|
657
|
+
throw new Error(
|
|
658
|
+
`Owner ${record.ownerId} reached running-job cap (${_maxRunningJobsPerOwnerV2})`,
|
|
659
|
+
);
|
|
660
|
+
if (!record.startedAt) record.startedAt = Date.now();
|
|
661
|
+
}
|
|
662
|
+
record.status = newStatus;
|
|
663
|
+
record.updatedAt = Date.now();
|
|
664
|
+
if (patch.reason !== undefined) record.lastReason = patch.reason;
|
|
665
|
+
if (patch.metadata)
|
|
666
|
+
record.metadata = { ...record.metadata, ...patch.metadata };
|
|
667
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
export function startGenJob(db, id, reason) {
|
|
671
|
+
return setGenJobStatusV2(db, id, GEN_JOB_V2.RUNNING, { reason });
|
|
672
|
+
}
|
|
673
|
+
export function succeedGenJob(db, id, reason) {
|
|
674
|
+
return setGenJobStatusV2(db, id, GEN_JOB_V2.SUCCEEDED, { reason });
|
|
675
|
+
}
|
|
676
|
+
export function failGenJob(db, id, reason) {
|
|
677
|
+
return setGenJobStatusV2(db, id, GEN_JOB_V2.FAILED, { reason });
|
|
678
|
+
}
|
|
679
|
+
export function cancelGenJob(db, id, reason) {
|
|
680
|
+
return setGenJobStatusV2(db, id, GEN_JOB_V2.CANCELED, { reason });
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
export function getActiveAgentCount(ownerId) {
|
|
684
|
+
let n = 0;
|
|
685
|
+
for (const r of _agentsV2.values()) {
|
|
686
|
+
if (r.status !== AGENT_MATURITY_V2.ACTIVE) continue;
|
|
687
|
+
if (ownerId && r.ownerId !== ownerId) continue;
|
|
688
|
+
n++;
|
|
689
|
+
}
|
|
690
|
+
return n;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
export function getRunningJobCount(ownerId) {
|
|
694
|
+
let n = 0;
|
|
695
|
+
for (const r of _jobsV2.values()) {
|
|
696
|
+
if (r.status !== GEN_JOB_V2.RUNNING) continue;
|
|
697
|
+
if (ownerId && r.ownerId !== ownerId) continue;
|
|
698
|
+
n++;
|
|
699
|
+
}
|
|
700
|
+
return n;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
export function autoRetireIdleAgents(_db, nowMs) {
|
|
704
|
+
const now = nowMs ?? Date.now();
|
|
705
|
+
const flipped = [];
|
|
706
|
+
for (const r of _agentsV2.values()) {
|
|
707
|
+
if (
|
|
708
|
+
r.status === AGENT_MATURITY_V2.ACTIVE ||
|
|
709
|
+
r.status === AGENT_MATURITY_V2.DEPRECATED
|
|
710
|
+
) {
|
|
711
|
+
if (now - r.lastInvokedAt > _agentIdleMsV2) {
|
|
712
|
+
r.status = AGENT_MATURITY_V2.RETIRED;
|
|
713
|
+
r.updatedAt = now;
|
|
714
|
+
r.lastReason = "idle_timeout";
|
|
715
|
+
flipped.push(r.agentId);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
return { flipped, count: flipped.length };
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
export function autoFailStuckGenJobs(_db, nowMs) {
|
|
723
|
+
const now = nowMs ?? Date.now();
|
|
724
|
+
const flipped = [];
|
|
725
|
+
for (const r of _jobsV2.values()) {
|
|
726
|
+
if (r.status === GEN_JOB_V2.RUNNING) {
|
|
727
|
+
const anchor = r.startedAt || r.createdAt;
|
|
728
|
+
if (now - anchor > _jobStuckMsV2) {
|
|
729
|
+
r.status = GEN_JOB_V2.FAILED;
|
|
730
|
+
r.updatedAt = now;
|
|
731
|
+
r.lastReason = "job_timeout";
|
|
732
|
+
flipped.push(r.jobId);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
return { flipped, count: flipped.length };
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
export function getCodeAgentStatsV2() {
|
|
740
|
+
const agentsByStatus = {};
|
|
741
|
+
for (const s of Object.values(AGENT_MATURITY_V2)) agentsByStatus[s] = 0;
|
|
742
|
+
const jobsByStatus = {};
|
|
743
|
+
for (const s of Object.values(GEN_JOB_V2)) jobsByStatus[s] = 0;
|
|
744
|
+
for (const r of _agentsV2.values()) agentsByStatus[r.status]++;
|
|
745
|
+
for (const r of _jobsV2.values()) jobsByStatus[r.status]++;
|
|
746
|
+
return {
|
|
747
|
+
totalAgentsV2: _agentsV2.size,
|
|
748
|
+
totalJobsV2: _jobsV2.size,
|
|
749
|
+
maxActiveAgentsPerOwner: _maxActiveAgentsPerOwnerV2,
|
|
750
|
+
maxRunningJobsPerOwner: _maxRunningJobsPerOwnerV2,
|
|
751
|
+
agentIdleMs: _agentIdleMsV2,
|
|
752
|
+
jobStuckMs: _jobStuckMsV2,
|
|
753
|
+
agentsByStatus,
|
|
754
|
+
jobsByStatus,
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
export function _resetStateV2() {
|
|
759
|
+
_maxActiveAgentsPerOwnerV2 = CGA_DEFAULT_MAX_ACTIVE_AGENTS_PER_OWNER;
|
|
760
|
+
_maxRunningJobsPerOwnerV2 = CGA_DEFAULT_MAX_RUNNING_JOBS_PER_OWNER;
|
|
761
|
+
_agentIdleMsV2 = CGA_DEFAULT_AGENT_IDLE_MS;
|
|
762
|
+
_jobStuckMsV2 = CGA_DEFAULT_JOB_STUCK_MS;
|
|
763
|
+
_agentsV2.clear();
|
|
764
|
+
_jobsV2.clear();
|
|
765
|
+
}
|