@haaaiawd/second-nature 0.1.1 → 0.1.3
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/index.ts +64 -21
- package/openclaw.plugin.json +1 -1
- package/package.json +8 -2
- package/runtime/cli/action-bridge.d.ts +11 -0
- package/runtime/cli/action-bridge.js +27 -0
- package/runtime/cli/commands/credential.d.ts +2 -0
- package/runtime/cli/commands/credential.js +40 -0
- package/runtime/cli/commands/index.d.ts +12 -0
- package/runtime/cli/commands/index.js +138 -0
- package/runtime/cli/commands/policy.d.ts +12 -0
- package/runtime/cli/commands/policy.js +43 -0
- package/runtime/cli/explain/format-explanation.d.ts +10 -0
- package/runtime/cli/explain/format-explanation.js +10 -0
- package/runtime/cli/explain/resolve-subject.d.ts +2 -0
- package/runtime/cli/explain/resolve-subject.js +26 -0
- package/runtime/cli/index.d.ts +25 -0
- package/runtime/cli/index.js +36 -0
- package/runtime/cli/read-models/index.d.ts +20 -0
- package/runtime/cli/read-models/index.js +161 -0
- package/runtime/cli/read-models/types.d.ts +75 -0
- package/runtime/cli/read-models/types.js +1 -0
- package/runtime/connectors/agent-network/evomap/adapter.d.ts +23 -0
- package/runtime/connectors/agent-network/evomap/adapter.js +69 -0
- package/runtime/connectors/agent-network/evomap/index.d.ts +2 -0
- package/runtime/connectors/agent-network/evomap/index.js +2 -0
- package/runtime/connectors/agent-network/evomap/manifest.d.ts +2 -0
- package/runtime/connectors/agent-network/evomap/manifest.js +7 -0
- package/runtime/connectors/base/channel-health.d.ts +29 -0
- package/runtime/connectors/base/channel-health.js +23 -0
- package/runtime/connectors/base/contract.d.ts +81 -0
- package/runtime/connectors/base/contract.js +71 -0
- package/runtime/connectors/base/failure-taxonomy.d.ts +13 -0
- package/runtime/connectors/base/failure-taxonomy.js +105 -0
- package/runtime/connectors/base/index.d.ts +6 -0
- package/runtime/connectors/base/index.js +6 -0
- package/runtime/connectors/base/manifest.d.ts +11 -0
- package/runtime/connectors/base/manifest.js +36 -0
- package/runtime/connectors/base/policy-layer.d.ts +27 -0
- package/runtime/connectors/base/policy-layer.js +213 -0
- package/runtime/connectors/base/route-planner.d.ts +10 -0
- package/runtime/connectors/base/route-planner.js +98 -0
- package/runtime/connectors/index.d.ts +4 -0
- package/runtime/connectors/index.js +4 -0
- package/runtime/connectors/social-community/instreet/adapter.d.ts +32 -0
- package/runtime/connectors/social-community/instreet/adapter.js +79 -0
- package/runtime/connectors/social-community/instreet/index.d.ts +2 -0
- package/runtime/connectors/social-community/instreet/index.js +2 -0
- package/runtime/connectors/social-community/instreet/manifest.d.ts +2 -0
- package/runtime/connectors/social-community/instreet/manifest.js +7 -0
- package/runtime/connectors/social-community/moltbook/adapter.d.ts +15 -0
- package/runtime/connectors/social-community/moltbook/adapter.js +48 -0
- package/runtime/connectors/social-community/moltbook/index.d.ts +2 -0
- package/runtime/connectors/social-community/moltbook/index.js +2 -0
- package/runtime/connectors/social-community/moltbook/manifest.d.ts +7 -0
- package/runtime/connectors/social-community/moltbook/manifest.js +12 -0
- package/runtime/core/second-nature/guidance/apply-guidance.d.ts +10 -0
- package/runtime/core/second-nature/guidance/apply-guidance.js +10 -0
- package/runtime/core/second-nature/guidance/request-guidance.d.ts +18 -0
- package/runtime/core/second-nature/guidance/request-guidance.js +22 -0
- package/runtime/core/second-nature/index.d.ts +14 -0
- package/runtime/core/second-nature/index.js +14 -0
- package/runtime/core/second-nature/orchestrator/effect-dispatcher.d.ts +100 -0
- package/runtime/core/second-nature/orchestrator/effect-dispatcher.js +139 -0
- package/runtime/core/second-nature/orchestrator/guard-layer.d.ts +2 -0
- package/runtime/core/second-nature/orchestrator/guard-layer.js +54 -0
- package/runtime/core/second-nature/orchestrator/intent-planner.d.ts +3 -0
- package/runtime/core/second-nature/orchestrator/intent-planner.js +92 -0
- package/runtime/core/second-nature/orchestrator/lease-manager.d.ts +14 -0
- package/runtime/core/second-nature/orchestrator/lease-manager.js +58 -0
- package/runtime/core/second-nature/orchestrator/resume-from-checkpoint.d.ts +32 -0
- package/runtime/core/second-nature/orchestrator/resume-from-checkpoint.js +23 -0
- package/runtime/core/second-nature/outreach/build-message.d.ts +16 -0
- package/runtime/core/second-nature/outreach/build-message.js +27 -0
- package/runtime/core/second-nature/outreach/evaluate-outreach.d.ts +13 -0
- package/runtime/core/second-nature/outreach/evaluate-outreach.js +41 -0
- package/runtime/core/second-nature/quiet/quiet-pipeline.d.ts +34 -0
- package/runtime/core/second-nature/quiet/quiet-pipeline.js +35 -0
- package/runtime/core/second-nature/reflection/run-narrative-reflection.d.ts +39 -0
- package/runtime/core/second-nature/reflection/run-narrative-reflection.js +29 -0
- package/runtime/core/second-nature/rhythm/rhythm-policy.d.ts +18 -0
- package/runtime/core/second-nature/rhythm/rhythm-policy.js +24 -0
- package/runtime/core/second-nature/rhythm/select-window.d.ts +3 -0
- package/runtime/core/second-nature/rhythm/select-window.js +50 -0
- package/runtime/core/second-nature/runtime/lifecycle-service.d.ts +26 -0
- package/runtime/core/second-nature/runtime/lifecycle-service.js +38 -0
- package/runtime/core/second-nature/runtime/service-entry.d.ts +36 -0
- package/runtime/core/second-nature/runtime/service-entry.js +44 -0
- package/runtime/core/second-nature/types.d.ts +37 -0
- package/runtime/core/second-nature/types.js +1 -0
- package/runtime/guidance/contracts.d.ts +48 -0
- package/runtime/guidance/contracts.js +54 -0
- package/runtime/guidance/fallback.d.ts +2 -0
- package/runtime/guidance/fallback.js +17 -0
- package/runtime/guidance/guidance-assembler.d.ts +5 -0
- package/runtime/guidance/guidance-assembler.js +62 -0
- package/runtime/guidance/index.d.ts +8 -0
- package/runtime/guidance/index.js +8 -0
- package/runtime/guidance/output-guard.d.ts +10 -0
- package/runtime/guidance/output-guard.js +29 -0
- package/runtime/guidance/persona-selection.d.ts +11 -0
- package/runtime/guidance/persona-selection.js +90 -0
- package/runtime/guidance/review-workflow.d.ts +15 -0
- package/runtime/guidance/review-workflow.js +60 -0
- package/runtime/guidance/template-registry.d.ts +3 -0
- package/runtime/guidance/template-registry.js +45 -0
- package/runtime/guidance/types.d.ts +72 -0
- package/runtime/guidance/types.js +1 -0
- package/runtime/observability/db/index.d.ts +10 -0
- package/runtime/observability/db/index.js +17 -0
- package/runtime/observability/db/schema/index.d.ts +946 -0
- package/runtime/observability/db/schema/index.js +70 -0
- package/runtime/observability/index.d.ts +12 -0
- package/runtime/observability/index.js +11 -0
- package/runtime/observability/projections/guidance-audit.d.ts +16 -0
- package/runtime/observability/projections/guidance-audit.js +35 -0
- package/runtime/observability/projections/outreach-quality-audit.d.ts +15 -0
- package/runtime/observability/projections/outreach-quality-audit.js +9 -0
- package/runtime/observability/projections/reflection-audit.d.ts +17 -0
- package/runtime/observability/projections/reflection-audit.js +9 -0
- package/runtime/observability/query/compose-evidence.d.ts +56 -0
- package/runtime/observability/query/compose-evidence.js +43 -0
- package/runtime/observability/query/evidence-query-engine.d.ts +17 -0
- package/runtime/observability/query/evidence-query-engine.js +166 -0
- package/runtime/observability/redaction/manifest.d.ts +18 -0
- package/runtime/observability/redaction/manifest.js +109 -0
- package/runtime/observability/redaction/policy.d.ts +19 -0
- package/runtime/observability/redaction/policy.js +71 -0
- package/runtime/observability/services/decision-ledger.d.ts +33 -0
- package/runtime/observability/services/decision-ledger.js +115 -0
- package/runtime/observability/services/execution-telemetry.d.ts +32 -0
- package/runtime/observability/services/execution-telemetry.js +126 -0
- package/runtime/observability/services/governance-audit.d.ts +27 -0
- package/runtime/observability/services/governance-audit.js +139 -0
- package/runtime/observability/services/redaction-store.d.ts +3 -0
- package/runtime/observability/services/redaction-store.js +20 -0
- package/runtime/setup/HOST_SETUP.md +112 -0
- package/runtime/shared/types/continuity.d.ts +69 -0
- package/runtime/shared/types/continuity.js +1 -0
- package/runtime/shared/types/credential.d.ts +22 -0
- package/runtime/shared/types/credential.js +1 -0
- package/runtime/shared/types/index.d.ts +3 -0
- package/runtime/shared/types/index.js +3 -0
- package/runtime/shared/types/outreach.d.ts +19 -0
- package/runtime/shared/types/outreach.js +1 -0
- package/runtime/storage/bootstrap/repair.d.ts +3 -0
- package/runtime/storage/bootstrap/repair.js +5 -0
- package/runtime/storage/db/index.d.ts +10 -0
- package/runtime/storage/db/index.js +17 -0
- package/runtime/storage/db/schema/assets.d.ts +140 -0
- package/runtime/storage/db/schema/assets.js +10 -0
- package/runtime/storage/db/schema/credentials.d.ts +178 -0
- package/runtime/storage/db/schema/credentials.js +12 -0
- package/runtime/storage/db/schema/index.d.ts +6 -0
- package/runtime/storage/db/schema/index.js +6 -0
- package/runtime/storage/db/schema/intent-commits.d.ts +161 -0
- package/runtime/storage/db/schema/intent-commits.js +11 -0
- package/runtime/storage/db/schema/policies.d.ts +81 -0
- package/runtime/storage/db/schema/policies.js +7 -0
- package/runtime/storage/db/schema/proposals.d.ts +216 -0
- package/runtime/storage/db/schema/proposals.js +14 -0
- package/runtime/storage/db/schema/provenance.d.ts +104 -0
- package/runtime/storage/db/schema/provenance.js +8 -0
- package/runtime/storage/index.d.ts +16 -0
- package/runtime/storage/index.js +16 -0
- package/runtime/storage/memory/workspace/paths.d.ts +62 -0
- package/runtime/storage/memory/workspace/paths.js +160 -0
- package/runtime/storage/memory/workspace/store.d.ts +26 -0
- package/runtime/storage/memory/workspace/store.js +153 -0
- package/runtime/storage/memory/workspace/types.d.ts +45 -0
- package/runtime/storage/memory/workspace/types.js +1 -0
- package/runtime/storage/repositories/asset-repository.d.ts +8 -0
- package/runtime/storage/repositories/asset-repository.js +19 -0
- package/runtime/storage/repositories/credential-repository.d.ts +8 -0
- package/runtime/storage/repositories/credential-repository.js +19 -0
- package/runtime/storage/repositories/index.d.ts +6 -0
- package/runtime/storage/repositories/index.js +6 -0
- package/runtime/storage/repositories/intent-commit-repository.d.ts +10 -0
- package/runtime/storage/repositories/intent-commit-repository.js +35 -0
- package/runtime/storage/repositories/policy-repository.d.ts +8 -0
- package/runtime/storage/repositories/policy-repository.js +19 -0
- package/runtime/storage/repositories/proposal-repository.d.ts +9 -0
- package/runtime/storage/repositories/proposal-repository.js +26 -0
- package/runtime/storage/repositories/provenance-repository.d.ts +20 -0
- package/runtime/storage/repositories/provenance-repository.js +41 -0
- package/runtime/storage/services/credential-vault.d.ts +8 -0
- package/runtime/storage/services/credential-vault.js +78 -0
- package/runtime/storage/services/daily-log-pipeline.d.ts +47 -0
- package/runtime/storage/services/daily-log-pipeline.js +86 -0
- package/runtime/storage/services/effect-commit-store.d.ts +11 -0
- package/runtime/storage/services/effect-commit-store.js +93 -0
- package/runtime/storage/services/governance-layer.d.ts +40 -0
- package/runtime/storage/services/governance-layer.js +103 -0
- package/runtime/storage/services/persona-candidate-loader.d.ts +5 -0
- package/runtime/storage/services/persona-candidate-loader.js +41 -0
- package/runtime/storage/services/provenance-service.d.ts +40 -0
- package/runtime/storage/services/provenance-service.js +43 -0
- package/runtime/storage/services/quiet-input-loader.d.ts +40 -0
- package/runtime/storage/services/quiet-input-loader.js +131 -0
- package/runtime/storage/services/repair-and-backup.d.ts +22 -0
- package/runtime/storage/services/repair-and-backup.js +73 -0
- package/runtime/storage/state-api.d.ts +46 -0
- package/runtime/storage/state-api.js +73 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { createQuietInputLoader } from "../../storage/services/quiet-input-loader.js";
|
|
2
|
+
import { AssetRepository } from "../../storage/repositories/asset-repository.js";
|
|
3
|
+
import { CredentialRepository } from "../../storage/repositories/credential-repository.js";
|
|
4
|
+
import { EvidenceQueryEngine } from "../../observability/query/evidence-query-engine.js";
|
|
5
|
+
import { executionAttempts } from "../../observability/db/schema/index.js";
|
|
6
|
+
import { desc } from "drizzle-orm";
|
|
7
|
+
function buildCredentialNextStep(status) {
|
|
8
|
+
if (status === "pending_verification")
|
|
9
|
+
return "submit_verification_answer";
|
|
10
|
+
if (status === "expired" || status === "revoked" || status === "failed")
|
|
11
|
+
return "refresh_credential_context";
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
export function createCliReadModels(deps) {
|
|
15
|
+
const assetRepository = new AssetRepository(deps.stateDb);
|
|
16
|
+
const credentialRepository = new CredentialRepository(deps.stateDb);
|
|
17
|
+
const quietLoader = createQuietInputLoader(assetRepository);
|
|
18
|
+
const evidenceQuery = new EvidenceQueryEngine(deps.observabilityDb);
|
|
19
|
+
return {
|
|
20
|
+
async loadStatus(_scope) {
|
|
21
|
+
let latestAttempt;
|
|
22
|
+
let credentials = [];
|
|
23
|
+
try {
|
|
24
|
+
latestAttempt = await deps.observabilityDb.db.query.executionAttempts.findFirst({
|
|
25
|
+
orderBy: [desc(executionAttempts.startedAt)],
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
latestAttempt = undefined;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
credentials = await deps.stateDb.db.query.credentialRecords.findMany();
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
credentials = [];
|
|
36
|
+
}
|
|
37
|
+
const connectorSummary = latestAttempt
|
|
38
|
+
? [{
|
|
39
|
+
platformId: latestAttempt.platformId,
|
|
40
|
+
status: latestAttempt.failureClass ? "degraded" : "healthy",
|
|
41
|
+
channel: latestAttempt.channel,
|
|
42
|
+
failureClass: latestAttempt.failureClass ?? undefined,
|
|
43
|
+
}]
|
|
44
|
+
: [];
|
|
45
|
+
return {
|
|
46
|
+
runtime: {
|
|
47
|
+
host: "openclaw-plugin",
|
|
48
|
+
serviceStatus: latestAttempt ? (latestAttempt.failureClass ? "degraded" : "running") : "unknown",
|
|
49
|
+
updatedAt: new Date().toISOString(),
|
|
50
|
+
},
|
|
51
|
+
rhythm: {
|
|
52
|
+
mode: "unknown",
|
|
53
|
+
windowId: undefined,
|
|
54
|
+
},
|
|
55
|
+
quiet: {
|
|
56
|
+
mode: "unknown",
|
|
57
|
+
lastEvent: undefined,
|
|
58
|
+
interrupted: undefined,
|
|
59
|
+
},
|
|
60
|
+
connectors: connectorSummary,
|
|
61
|
+
credentials: credentials.map((item) => ({
|
|
62
|
+
platformId: item.platformId,
|
|
63
|
+
status: item.status,
|
|
64
|
+
nextStep: buildCredentialNextStep(item.status),
|
|
65
|
+
})),
|
|
66
|
+
risk: {
|
|
67
|
+
level: latestAttempt?.failureClass ? "medium" : "low",
|
|
68
|
+
flags: latestAttempt?.failureClass ? [latestAttempt.failureClass] : [],
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
async loadDailyReport(day) {
|
|
73
|
+
let bundle;
|
|
74
|
+
try {
|
|
75
|
+
bundle = await quietLoader.loadQuietInputs({
|
|
76
|
+
dateRange: { start: `${day}T00:00:00.000Z`, end: `${day}T23:59:59.999Z` },
|
|
77
|
+
assetFilters: { includeJournal: false, includeReports: true, includeCurated: false },
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
bundle = { dailyReports: [], journalEntries: [], sourceCount: 0 };
|
|
82
|
+
}
|
|
83
|
+
const report = bundle.dailyReports[0];
|
|
84
|
+
return {
|
|
85
|
+
day,
|
|
86
|
+
summary: report?.summary ?? "",
|
|
87
|
+
highlights: report?.highlights ?? [],
|
|
88
|
+
sourceRefs: report?.sources ?? [],
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
async loadQuiet(scope) {
|
|
92
|
+
const now = new Date();
|
|
93
|
+
const start = new Date(now);
|
|
94
|
+
start.setDate(now.getDate() - 1);
|
|
95
|
+
let bundle;
|
|
96
|
+
try {
|
|
97
|
+
bundle = await quietLoader.loadQuietInputs({
|
|
98
|
+
dateRange: { start: start.toISOString(), end: now.toISOString() },
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
bundle = { dailyReports: [], journalEntries: [], sourceCount: 0 };
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
scope,
|
|
106
|
+
mode: bundle.sourceCount > 0 ? "quiet" : "unknown",
|
|
107
|
+
sourceCount: bundle.sourceCount,
|
|
108
|
+
reportCount: bundle.dailyReports.length,
|
|
109
|
+
recentJournalCount: bundle.journalEntries.length,
|
|
110
|
+
};
|
|
111
|
+
},
|
|
112
|
+
async loadSession(sessionId) {
|
|
113
|
+
const traceId = sessionId;
|
|
114
|
+
const bundle = await evidenceQuery.queryEvidence({ traceId });
|
|
115
|
+
return {
|
|
116
|
+
requestedSessionId: sessionId,
|
|
117
|
+
traceId,
|
|
118
|
+
decisionCount: bundle.decisions.length,
|
|
119
|
+
attemptCount: bundle.attempts.length,
|
|
120
|
+
governanceCount: bundle.governance.length,
|
|
121
|
+
keyFactors: bundle.explanation.keyFactors,
|
|
122
|
+
evidenceRefs: bundle.explanation.evidenceRefs,
|
|
123
|
+
};
|
|
124
|
+
},
|
|
125
|
+
async loadCredential(platformId) {
|
|
126
|
+
let record;
|
|
127
|
+
try {
|
|
128
|
+
record = await credentialRepository.findByPlatformId(platformId);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
record = undefined;
|
|
132
|
+
}
|
|
133
|
+
if (!record) {
|
|
134
|
+
return {
|
|
135
|
+
platformId,
|
|
136
|
+
status: "missing",
|
|
137
|
+
nextStep: "provide_credential_context",
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
platformId: record.platformId,
|
|
142
|
+
status: record.status,
|
|
143
|
+
verificationDeadline: record.expiresAt ?? undefined,
|
|
144
|
+
attemptsRemaining: record.attemptsRemaining ?? undefined,
|
|
145
|
+
nextStep: buildCredentialNextStep(record.status),
|
|
146
|
+
};
|
|
147
|
+
},
|
|
148
|
+
async explain(subject) {
|
|
149
|
+
const query = subject.kind === "decision" || subject.kind === "platform-selection" || subject.kind === "outreach"
|
|
150
|
+
? { decisionId: subject.id }
|
|
151
|
+
: { assetId: subject.id };
|
|
152
|
+
const bundle = await evidenceQuery.queryEvidence(query);
|
|
153
|
+
return {
|
|
154
|
+
subjectType: subject.kind,
|
|
155
|
+
conclusion: bundle.explanation.conclusion,
|
|
156
|
+
keyFactors: bundle.explanation.keyFactors,
|
|
157
|
+
evidenceRefs: bundle.explanation.evidenceRefs,
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export interface RuntimeSummary {
|
|
2
|
+
host: "openclaw-plugin";
|
|
3
|
+
serviceStatus: "idle" | "running" | "degraded" | "unknown";
|
|
4
|
+
updatedAt: string;
|
|
5
|
+
}
|
|
6
|
+
export interface RhythmSummary {
|
|
7
|
+
mode: "active" | "quiet" | "maintenance_only" | "paused_for_interrupt" | "unknown";
|
|
8
|
+
windowId?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface QuietSummary {
|
|
11
|
+
mode: "active" | "quiet" | "maintenance_only" | "paused_for_interrupt" | "unknown";
|
|
12
|
+
lastEvent?: string;
|
|
13
|
+
interrupted?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface ConnectorSummary {
|
|
16
|
+
platformId: string;
|
|
17
|
+
status: "healthy" | "degraded" | "blocked" | "unknown";
|
|
18
|
+
channel?: string;
|
|
19
|
+
failureClass?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface CredentialSummary {
|
|
22
|
+
platformId: string;
|
|
23
|
+
status: "missing" | "pending_verification" | "active" | "expired" | "revoked" | "failed";
|
|
24
|
+
nextStep?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface RiskSummary {
|
|
27
|
+
level: "low" | "medium" | "high";
|
|
28
|
+
flags: string[];
|
|
29
|
+
}
|
|
30
|
+
export interface StatusReadModel {
|
|
31
|
+
runtime: RuntimeSummary;
|
|
32
|
+
rhythm: RhythmSummary;
|
|
33
|
+
quiet: QuietSummary;
|
|
34
|
+
connectors: ConnectorSummary[];
|
|
35
|
+
credentials: CredentialSummary[];
|
|
36
|
+
risk: RiskSummary;
|
|
37
|
+
}
|
|
38
|
+
export interface DailyReportReadModel {
|
|
39
|
+
day: string;
|
|
40
|
+
summary: string;
|
|
41
|
+
highlights: string[];
|
|
42
|
+
sourceRefs: string[];
|
|
43
|
+
}
|
|
44
|
+
export interface QuietReadModel {
|
|
45
|
+
scope?: string;
|
|
46
|
+
mode: "active" | "quiet" | "maintenance_only" | "paused_for_interrupt" | "unknown";
|
|
47
|
+
sourceCount: number;
|
|
48
|
+
reportCount: number;
|
|
49
|
+
recentJournalCount: number;
|
|
50
|
+
}
|
|
51
|
+
export interface SessionDetailReadModel {
|
|
52
|
+
requestedSessionId: string;
|
|
53
|
+
traceId: string;
|
|
54
|
+
decisionCount: number;
|
|
55
|
+
attemptCount: number;
|
|
56
|
+
governanceCount: number;
|
|
57
|
+
keyFactors: string[];
|
|
58
|
+
evidenceRefs: string[];
|
|
59
|
+
}
|
|
60
|
+
export interface CredentialReadModel {
|
|
61
|
+
platformId: string;
|
|
62
|
+
status: "missing" | "pending_verification" | "active" | "expired" | "revoked" | "failed";
|
|
63
|
+
verificationDeadline?: string;
|
|
64
|
+
attemptsRemaining?: number;
|
|
65
|
+
nextStep?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface ExplainReadModel {
|
|
68
|
+
subjectType: "decision" | "platform-selection" | "outreach" | "soul-change";
|
|
69
|
+
conclusion: string;
|
|
70
|
+
keyFactors: string[];
|
|
71
|
+
evidenceRefs: string[];
|
|
72
|
+
policyRefs?: string[];
|
|
73
|
+
requiredUserInput?: string[];
|
|
74
|
+
nextStep?: string;
|
|
75
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ConnectorRequest, ExecutionPlan, RawAttempt } from "../../base/contract.js";
|
|
2
|
+
export interface EvoMapApiClient {
|
|
3
|
+
heartbeat(payload: Record<string, unknown>, nodeSecret: string): Promise<unknown>;
|
|
4
|
+
claimTask(payload: Record<string, unknown>, nodeSecret: string): Promise<unknown>;
|
|
5
|
+
}
|
|
6
|
+
export interface EvoMapA2AClient {
|
|
7
|
+
helloOrRegister(payload: Record<string, unknown>): Promise<{
|
|
8
|
+
your_node_id: string;
|
|
9
|
+
node_secret: string;
|
|
10
|
+
}>;
|
|
11
|
+
discoverWork(payload: Record<string, unknown>, nodeSecret: string): Promise<unknown>;
|
|
12
|
+
}
|
|
13
|
+
export interface EvoMapSecretPort {
|
|
14
|
+
loadNodeSecret(platformId: string): Promise<string | null>;
|
|
15
|
+
saveNodeSecret(platformId: string, nodeSecret: string): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare function createEvoMapRunner(input: {
|
|
18
|
+
apiClient: EvoMapApiClient;
|
|
19
|
+
a2aClient: EvoMapA2AClient;
|
|
20
|
+
secretPort: EvoMapSecretPort;
|
|
21
|
+
}): {
|
|
22
|
+
run(plan: ExecutionPlan, request: ConnectorRequest): Promise<RawAttempt>;
|
|
23
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export function createEvoMapRunner(input) {
|
|
2
|
+
const { apiClient, a2aClient, secretPort } = input;
|
|
3
|
+
return {
|
|
4
|
+
async run(plan, request) {
|
|
5
|
+
const started = Date.now();
|
|
6
|
+
try {
|
|
7
|
+
const payload = await executeEvoMap(plan, request, apiClient, a2aClient, secretPort);
|
|
8
|
+
return {
|
|
9
|
+
platformId: request.platformId,
|
|
10
|
+
channel: plan.channel,
|
|
11
|
+
latencyMs: Date.now() - started,
|
|
12
|
+
degraded: plan.channel === "skill",
|
|
13
|
+
success: true,
|
|
14
|
+
payload: {
|
|
15
|
+
capability: request.intent,
|
|
16
|
+
channel: plan.channel,
|
|
17
|
+
data: payload,
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
return {
|
|
23
|
+
platformId: request.platformId,
|
|
24
|
+
channel: plan.channel,
|
|
25
|
+
latencyMs: Date.now() - started,
|
|
26
|
+
degraded: plan.channel === "skill",
|
|
27
|
+
success: false,
|
|
28
|
+
error,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
async function executeEvoMap(plan, request, apiClient, a2aClient, secretPort) {
|
|
35
|
+
if (plan.channel !== "api_rest" && plan.channel !== "a2a") {
|
|
36
|
+
throw { code: "protocol_mismatch", detail: `unsupported evomap channel: ${plan.channel}` };
|
|
37
|
+
}
|
|
38
|
+
if (plan.intent === "agent.register") {
|
|
39
|
+
if (plan.channel !== "a2a") {
|
|
40
|
+
throw { code: "protocol_mismatch", detail: "evomap register requires a2a envelope channel" };
|
|
41
|
+
}
|
|
42
|
+
const registration = await a2aClient.helloOrRegister(request.payload);
|
|
43
|
+
await secretPort.saveNodeSecret(request.platformId, registration.node_secret);
|
|
44
|
+
return registration;
|
|
45
|
+
}
|
|
46
|
+
const nodeSecret = await secretPort.loadNodeSecret(request.platformId);
|
|
47
|
+
if (!nodeSecret) {
|
|
48
|
+
throw { code: "verification_required", detail: "node_secret_required" };
|
|
49
|
+
}
|
|
50
|
+
if (plan.intent === "agent.heartbeat") {
|
|
51
|
+
if (plan.channel !== "api_rest") {
|
|
52
|
+
throw { code: "protocol_mismatch", detail: "evomap heartbeat requires api_rest channel" };
|
|
53
|
+
}
|
|
54
|
+
return apiClient.heartbeat(request.payload, nodeSecret);
|
|
55
|
+
}
|
|
56
|
+
if (plan.intent === "work.discover") {
|
|
57
|
+
if (plan.channel !== "a2a") {
|
|
58
|
+
throw { code: "protocol_mismatch", detail: "evomap work.discover requires a2a envelope channel" };
|
|
59
|
+
}
|
|
60
|
+
return a2aClient.discoverWork(request.payload, nodeSecret);
|
|
61
|
+
}
|
|
62
|
+
if (plan.intent === "task.claim") {
|
|
63
|
+
if (plan.channel !== "api_rest") {
|
|
64
|
+
throw { code: "protocol_mismatch", detail: "evomap task.claim requires api_rest channel" };
|
|
65
|
+
}
|
|
66
|
+
return apiClient.claimTask(request.payload, nodeSecret);
|
|
67
|
+
}
|
|
68
|
+
throw { code: "protocol_mismatch", detail: `unsupported evomap intent: ${plan.intent}` };
|
|
69
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const evomapManifest = {
|
|
2
|
+
platformId: "evomap",
|
|
3
|
+
supportedCapabilities: ["agent.register", "agent.heartbeat", "work.discover", "task.claim"],
|
|
4
|
+
channelPriority: ["api_rest", "a2a", "skill"],
|
|
5
|
+
credentialTypes: ["node_secret", "api_key"],
|
|
6
|
+
degradedChannels: ["skill"],
|
|
7
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CapabilityIntent, ChannelType } from "./contract.js";
|
|
2
|
+
export interface ChannelHealthSnapshot {
|
|
3
|
+
platformId: string;
|
|
4
|
+
channel: ChannelType;
|
|
5
|
+
healthy: boolean;
|
|
6
|
+
degraded: boolean;
|
|
7
|
+
lastFailureAt?: string;
|
|
8
|
+
failureClass?: string;
|
|
9
|
+
retryAfterMs?: number;
|
|
10
|
+
updatedAt: string;
|
|
11
|
+
}
|
|
12
|
+
export interface AttemptContext {
|
|
13
|
+
traceId: string;
|
|
14
|
+
platformId: string;
|
|
15
|
+
intent: CapabilityIntent;
|
|
16
|
+
channel: ChannelType;
|
|
17
|
+
startedAt: string;
|
|
18
|
+
idempotencyKey?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare class ChannelHealthStore {
|
|
21
|
+
private readonly byKey;
|
|
22
|
+
private readonly attempts;
|
|
23
|
+
upsert(snapshot: ChannelHealthSnapshot): void;
|
|
24
|
+
get(platformId: string, channel: ChannelType): ChannelHealthSnapshot | undefined;
|
|
25
|
+
markAttempt(context: AttemptContext): void;
|
|
26
|
+
getAttempt(traceId: string): AttemptContext | undefined;
|
|
27
|
+
clearAttempt(traceId: string): void;
|
|
28
|
+
private key;
|
|
29
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export class ChannelHealthStore {
|
|
2
|
+
byKey = new Map();
|
|
3
|
+
attempts = new Map();
|
|
4
|
+
upsert(snapshot) {
|
|
5
|
+
const key = this.key(snapshot.platformId, snapshot.channel);
|
|
6
|
+
this.byKey.set(key, snapshot);
|
|
7
|
+
}
|
|
8
|
+
get(platformId, channel) {
|
|
9
|
+
return this.byKey.get(this.key(platformId, channel));
|
|
10
|
+
}
|
|
11
|
+
markAttempt(context) {
|
|
12
|
+
this.attempts.set(context.traceId, context);
|
|
13
|
+
}
|
|
14
|
+
getAttempt(traceId) {
|
|
15
|
+
return this.attempts.get(traceId);
|
|
16
|
+
}
|
|
17
|
+
clearAttempt(traceId) {
|
|
18
|
+
this.attempts.delete(traceId);
|
|
19
|
+
}
|
|
20
|
+
key(platformId, channel) {
|
|
21
|
+
return `${platformId}::${channel}`;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { CredentialContext, CredentialState } from "../../shared/types/credential.js";
|
|
2
|
+
import { type FailureClass } from "./failure-taxonomy.js";
|
|
3
|
+
export declare const CHANNEL_TYPES: readonly ["api_rest", "api_rpc", "a2a", "mcp", "cli", "skill", "browser"];
|
|
4
|
+
export type ChannelType = (typeof CHANNEL_TYPES)[number];
|
|
5
|
+
export declare const CAPABILITY_INTENTS: readonly ["feed.read", "post.publish", "comment.reply", "notification.list", "message.send", "agent.register", "agent.heartbeat", "work.discover", "task.claim"];
|
|
6
|
+
export type CapabilityIntent = (typeof CAPABILITY_INTENTS)[number];
|
|
7
|
+
export interface ConnectorRequest {
|
|
8
|
+
platformId: string;
|
|
9
|
+
intent: CapabilityIntent;
|
|
10
|
+
payload: Record<string, unknown>;
|
|
11
|
+
preferredChannel?: ChannelType;
|
|
12
|
+
timeoutMs?: number;
|
|
13
|
+
idempotencyKey?: string;
|
|
14
|
+
decisionId?: string;
|
|
15
|
+
intentId?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ExecutionPlan {
|
|
18
|
+
platformId: string;
|
|
19
|
+
intent: CapabilityIntent;
|
|
20
|
+
channel: ChannelType;
|
|
21
|
+
endpointMode: "rest_json" | "a2a_envelope" | "cli_stdout" | "skill_call";
|
|
22
|
+
idempotencyKey?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ConnectorResult<T> {
|
|
25
|
+
status: "success" | "retryable_failure" | "terminal_failure";
|
|
26
|
+
data?: T;
|
|
27
|
+
failureClass?: FailureClass;
|
|
28
|
+
retryAfterMs?: number;
|
|
29
|
+
metadata: {
|
|
30
|
+
platformId: string;
|
|
31
|
+
channel: ChannelType;
|
|
32
|
+
latencyMs: number;
|
|
33
|
+
degraded?: boolean;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export interface RawAttempt {
|
|
37
|
+
platformId: string;
|
|
38
|
+
channel: ChannelType;
|
|
39
|
+
latencyMs: number;
|
|
40
|
+
degraded?: boolean;
|
|
41
|
+
success: boolean;
|
|
42
|
+
payload?: unknown;
|
|
43
|
+
error?: unknown;
|
|
44
|
+
}
|
|
45
|
+
export interface CredentialContextPort {
|
|
46
|
+
loadCredentialState(platformId: string): Promise<CredentialContext>;
|
|
47
|
+
}
|
|
48
|
+
export interface CooldownLedgerPort {
|
|
49
|
+
loadCooldownState(platformId: string, intent: CapabilityIntent): Promise<{
|
|
50
|
+
blocked: boolean;
|
|
51
|
+
retryAfterMs?: number;
|
|
52
|
+
}>;
|
|
53
|
+
}
|
|
54
|
+
export interface RouteContextPort extends CredentialContextPort, CooldownLedgerPort {
|
|
55
|
+
}
|
|
56
|
+
export interface ConnectorManifestLike {
|
|
57
|
+
platformId: string;
|
|
58
|
+
supportedCapabilities: CapabilityIntent[];
|
|
59
|
+
channelPriority: ChannelType[];
|
|
60
|
+
credentialTypes: string[];
|
|
61
|
+
degradedChannels?: ChannelType[];
|
|
62
|
+
}
|
|
63
|
+
export interface ConnectorManifestLoader {
|
|
64
|
+
loadManifest(platformId: string): ConnectorManifestLike;
|
|
65
|
+
}
|
|
66
|
+
export interface RoutePlanner {
|
|
67
|
+
planRoute(intent: CapabilityIntent, request: ConnectorRequest): Promise<ExecutionPlan>;
|
|
68
|
+
}
|
|
69
|
+
export interface ExecutionRunner {
|
|
70
|
+
run(plan: ExecutionPlan, request: ConnectorRequest): Promise<RawAttempt>;
|
|
71
|
+
}
|
|
72
|
+
export interface ConnectorExecutionPort {
|
|
73
|
+
executeCapability(intent: CapabilityIntent, request: ConnectorRequest): Promise<ConnectorResult<unknown>>;
|
|
74
|
+
}
|
|
75
|
+
export declare function normalizeOutcome(attempt: RawAttempt): ConnectorResult<unknown>;
|
|
76
|
+
export declare function createConnectorContractCore(input: {
|
|
77
|
+
manifestLoader: ConnectorManifestLoader;
|
|
78
|
+
routePlanner: RoutePlanner;
|
|
79
|
+
executionRunner: ExecutionRunner;
|
|
80
|
+
}): ConnectorExecutionPort;
|
|
81
|
+
export declare function isCredentialActive(state: CredentialState): boolean;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { classifyFailure, ConnectorPolicyError } from "./failure-taxonomy.js";
|
|
3
|
+
export const CHANNEL_TYPES = ["api_rest", "api_rpc", "a2a", "mcp", "cli", "skill", "browser"];
|
|
4
|
+
export const CAPABILITY_INTENTS = [
|
|
5
|
+
"feed.read",
|
|
6
|
+
"post.publish",
|
|
7
|
+
"comment.reply",
|
|
8
|
+
"notification.list",
|
|
9
|
+
"message.send",
|
|
10
|
+
"agent.register",
|
|
11
|
+
"agent.heartbeat",
|
|
12
|
+
"work.discover",
|
|
13
|
+
"task.claim",
|
|
14
|
+
];
|
|
15
|
+
const connectorRequestSchema = z.object({
|
|
16
|
+
platformId: z.string().min(1),
|
|
17
|
+
intent: z.enum(CAPABILITY_INTENTS),
|
|
18
|
+
payload: z.record(z.string(), z.unknown()),
|
|
19
|
+
preferredChannel: z.enum(CHANNEL_TYPES).optional(),
|
|
20
|
+
timeoutMs: z.number().int().positive().optional(),
|
|
21
|
+
idempotencyKey: z.string().min(1).optional(),
|
|
22
|
+
decisionId: z.string().min(1).optional(),
|
|
23
|
+
intentId: z.string().min(1).optional(),
|
|
24
|
+
});
|
|
25
|
+
export function normalizeOutcome(attempt) {
|
|
26
|
+
if (attempt.success) {
|
|
27
|
+
return {
|
|
28
|
+
status: "success",
|
|
29
|
+
data: attempt.payload,
|
|
30
|
+
metadata: {
|
|
31
|
+
platformId: attempt.platformId,
|
|
32
|
+
channel: attempt.channel,
|
|
33
|
+
latencyMs: attempt.latencyMs,
|
|
34
|
+
degraded: attempt.degraded,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const failure = classifyFailure(attempt.error);
|
|
39
|
+
return {
|
|
40
|
+
status: failure.retryable ? "retryable_failure" : "terminal_failure",
|
|
41
|
+
failureClass: failure.class,
|
|
42
|
+
retryAfterMs: failure.retryAfterMs,
|
|
43
|
+
metadata: {
|
|
44
|
+
platformId: attempt.platformId,
|
|
45
|
+
channel: attempt.channel,
|
|
46
|
+
latencyMs: attempt.latencyMs,
|
|
47
|
+
degraded: attempt.degraded,
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export function createConnectorContractCore(input) {
|
|
52
|
+
const { manifestLoader, routePlanner, executionRunner } = input;
|
|
53
|
+
return {
|
|
54
|
+
async executeCapability(intent, request) {
|
|
55
|
+
connectorRequestSchema.parse(request);
|
|
56
|
+
if (intent !== request.intent) {
|
|
57
|
+
throw new Error("connector_intent_mismatch");
|
|
58
|
+
}
|
|
59
|
+
const manifest = manifestLoader.loadManifest(request.platformId);
|
|
60
|
+
if (!manifest.supportedCapabilities.includes(intent)) {
|
|
61
|
+
throw new ConnectorPolicyError("protocol_mismatch", "capability_not_supported_by_manifest");
|
|
62
|
+
}
|
|
63
|
+
const plan = await routePlanner.planRoute(intent, request);
|
|
64
|
+
const attempt = await executionRunner.run(plan, request);
|
|
65
|
+
return normalizeOutcome(attempt);
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export function isCredentialActive(state) {
|
|
70
|
+
return state === "active";
|
|
71
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const FAILURE_CLASSES: readonly ["transport_failure", "auth_failure", "credential_expired", "verification_required", "rate_limited", "cooldown_blocked", "parse_failure", "protocol_mismatch", "semantic_rejection", "idempotency_conflict", "concurrency_conflict", "permanent_input_error", "unknown_platform_change"];
|
|
2
|
+
export type FailureClass = (typeof FAILURE_CLASSES)[number];
|
|
3
|
+
export interface FailureClassification {
|
|
4
|
+
class: FailureClass;
|
|
5
|
+
retryable: boolean;
|
|
6
|
+
retryAfterMs?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class ConnectorPolicyError extends Error {
|
|
9
|
+
readonly failureClass: FailureClass;
|
|
10
|
+
readonly retryAfterMs?: number | undefined;
|
|
11
|
+
constructor(failureClass: FailureClass, message: string, retryAfterMs?: number | undefined);
|
|
12
|
+
}
|
|
13
|
+
export declare function classifyFailure(error: unknown): FailureClassification;
|