05ed037fe8
- DNS: pilot.landvex.com -> 16.170.83.169 - TLS: Let's Encrypt certificate (expires 2026-09-30) - Nginx: reverse proxy with SSL termination - API: https://pilot.landvex.com/api/v1/missions - UI: https://pilot.landvex.com/ - Upload: POST /api/v1/missions/import (multipart/form-data) Verified: ✅ https://pilot.landvex.com/health ✅ https://pilot.landvex.com/version ✅ https://pilot.landvex.com/api/v1/missions (list) ✅ https://pilot.landvex.com/api/v1/missions/:id (get) ✅ POST /api/v1/missions/import (video upload) ✅ UI loads with title 'LandveX Intelligence Lab' Next: Pilot 001 — Break the system!
167 lines
6.0 KiB
JavaScript
167 lines
6.0 KiB
JavaScript
#!/usr/bin/env node
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
// Agent Runtime v9 — Med normaliserad Evidence Quality
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
import { RuntimeTraceV2 } from './runtime-trace-v2.mjs';
|
|
import { resolve } from './evidence-resolver-v4.mjs';
|
|
import { getPolicy } from './policy-registry.mjs';
|
|
import { DecisionReplay } from './decision-replay.mjs';
|
|
|
|
class AgentRuntimeV9 {
|
|
constructor(task) {
|
|
this.task = task;
|
|
this.trace = new RuntimeTraceV2();
|
|
this.decisionReplay = new DecisionReplay();
|
|
}
|
|
|
|
async execute() {
|
|
await this.runPlanner();
|
|
await this.runContext();
|
|
await this.runMemory();
|
|
await this.runKnowledge();
|
|
|
|
const resolutionResult = await this.runIntentResolution();
|
|
const eosResult = await this.runEOSCheck(resolutionResult);
|
|
const decisionId = this.recordDecision(resolutionResult, eosResult);
|
|
|
|
if (!eosResult.passed) {
|
|
return {
|
|
status: 'blocked',
|
|
reason: eosResult.reason,
|
|
policy: eosResult.blockedBy,
|
|
evidence: eosResult.evidence,
|
|
decisionId
|
|
};
|
|
}
|
|
|
|
await this.runDeveloper();
|
|
await this.runReviewer();
|
|
await this.runCommit();
|
|
await this.runOperator();
|
|
|
|
return { status: 'completed', trace: this.trace.toJSON(), decisionId };
|
|
}
|
|
|
|
async runPlanner() {
|
|
const node = this.trace.addNode('PLANNER', { task: this.task.description });
|
|
this.trace.completeNode(node.id, { plan: { steps: [], estimatedTime: null, dependencies: [] } });
|
|
}
|
|
|
|
async runContext() {
|
|
const node = this.trace.addNode('CONTEXT', { task: this.task.description });
|
|
this.trace.completeNode(node.id, { confidence: 0.8, git: { branch: null, uncommitted: null, remote: null } });
|
|
}
|
|
|
|
async runMemory() {
|
|
const node = this.trace.addNode('MEMORY', { queries: [] });
|
|
this.trace.completeNode(node.id, { results: { relevantDecisions: [], similarTasks: [], lessonsLearned: [] } });
|
|
}
|
|
|
|
async runKnowledge() {
|
|
const node = this.trace.addNode('KNOWLEDGE', { queries: [] });
|
|
this.trace.completeNode(node.id, { results: { relatedCapabilities: [], dependencies: [], impact: [] } });
|
|
}
|
|
|
|
async runIntentResolution() {
|
|
const node = this.trace.addNode('INTENT', { task: this.task.description });
|
|
const result = resolve(this.task);
|
|
|
|
this.trace.completeNode(node.id, {
|
|
candidates: result.candidates.map(c => c.operation),
|
|
evidence: result.evidence,
|
|
resolution: result.resolution.operation.id,
|
|
confidence: result.resolution.confidence,
|
|
reasoning: result.resolution.reasoning,
|
|
evidenceQuality: result.resolution.evidenceQuality
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
async runEOSCheck(resolutionResult) {
|
|
const node = this.trace.addNode('EOS', { operation: resolutionResult.resolution.operation.id });
|
|
const operation = resolutionResult.resolution.operation;
|
|
|
|
if (operation.id === 'UNKNOWN_OPERATION') {
|
|
this.trace.blockNode(node.id, operation.description, {
|
|
policyId: 'UNKNOWN',
|
|
policyName: 'Unknown Operation Policy',
|
|
evidence: resolutionResult.resolution.evidence,
|
|
riskClass: operation.severity,
|
|
requiredAction: 'Eskalera till mänsklig granskning eller tillhandahåll mer kontext',
|
|
unknownOperation: true
|
|
});
|
|
|
|
return {
|
|
passed: false,
|
|
blockedBy: operation.id,
|
|
reason: `${operation.description}. Eskalering krävs.`,
|
|
severity: operation.severity,
|
|
evidence: {
|
|
operation: operation.id,
|
|
confidence: resolutionResult.resolution.confidence,
|
|
matchedEvidence: resolutionResult.resolution.evidence,
|
|
evidenceQuality: resolutionResult.resolution.evidenceQuality
|
|
}
|
|
};
|
|
}
|
|
|
|
if (!operation.allowed) {
|
|
const policyInfo = getPolicy(operation.policy);
|
|
this.trace.blockNode(node.id, operation.description, {
|
|
policyId: operation.policy,
|
|
policyName: policyInfo?.name || 'Unknown Policy',
|
|
evidence: resolutionResult.resolution.evidence,
|
|
riskClass: operation.severity,
|
|
requiredAction: `Använd godkänd process: ${policyInfo?.description || 'Kontakta EOS Team'}`
|
|
});
|
|
|
|
return {
|
|
passed: false,
|
|
blockedBy: operation.id,
|
|
reason: `${operation.description} är förbjudet. Policy: ${operation.policy}`,
|
|
severity: operation.severity,
|
|
evidence: {
|
|
operation: operation.id,
|
|
confidence: resolutionResult.resolution.confidence,
|
|
matchedEvidence: resolutionResult.resolution.evidence,
|
|
evidenceQuality: resolutionResult.resolution.evidenceQuality
|
|
}
|
|
};
|
|
}
|
|
|
|
this.trace.completeNode(node.id, { passed: true, operation: operation.id });
|
|
return { passed: true };
|
|
}
|
|
|
|
recordDecision(resolutionResult, eosResult) {
|
|
return this.decisionReplay.recordDecision(this.task, resolutionResult.resolution, eosResult, this.trace);
|
|
}
|
|
|
|
async runDeveloper() {
|
|
const node = this.trace.addNode('DEVELOPER', { task: this.task.description });
|
|
this.trace.completeNode(node.id, { status: 'completed' });
|
|
}
|
|
|
|
async runReviewer() {
|
|
const node = this.trace.addNode('REVIEWER', { task: this.task.description });
|
|
this.trace.completeNode(node.id, { status: 'completed' });
|
|
}
|
|
|
|
async runCommit() {
|
|
const node = this.trace.addNode('COMMIT', { task: this.task.description });
|
|
this.trace.completeNode(node.id, { status: 'completed' });
|
|
}
|
|
|
|
async runOperator() {
|
|
const node = this.trace.addNode('OPERATOR', { task: this.task.description });
|
|
this.trace.completeNode(node.id, { status: 'completed' });
|
|
}
|
|
|
|
getTrace() { return this.trace; }
|
|
getDecisionReplay() { return this.decisionReplay; }
|
|
}
|
|
|
|
export { AgentRuntimeV9 };
|