@a5c-ai/agent-runtime 5.0.1-staging.016f0b0e8119
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/README.md +23 -0
- package/dist/apiResult.d.ts +19 -0
- package/dist/apiResult.d.ts.map +1 -0
- package/dist/apiResult.js +16 -0
- package/dist/background/state.d.ts +14 -0
- package/dist/background/state.d.ts.map +1 -0
- package/dist/background/state.js +25 -0
- package/dist/backgroundProcessRegistry.d.ts +66 -0
- package/dist/backgroundProcessRegistry.d.ts.map +1 -0
- package/dist/backgroundProcessRegistry.js +202 -0
- package/dist/cost/claudeCodeParser.d.ts +81 -0
- package/dist/cost/claudeCodeParser.d.ts.map +1 -0
- package/dist/cost/claudeCodeParser.js +232 -0
- package/dist/cost/collector.d.ts +42 -0
- package/dist/cost/collector.d.ts.map +1 -0
- package/dist/cost/collector.js +105 -0
- package/dist/cost/effectCost.d.ts +23 -0
- package/dist/cost/effectCost.d.ts.map +1 -0
- package/dist/cost/effectCost.js +26 -0
- package/dist/cost/index.d.ts +19 -0
- package/dist/cost/index.d.ts.map +1 -0
- package/dist/cost/index.js +39 -0
- package/dist/cost/journal.d.ts +40 -0
- package/dist/cost/journal.d.ts.map +1 -0
- package/dist/cost/journal.js +137 -0
- package/dist/cost/types.d.ts +164 -0
- package/dist/cost/types.d.ts.map +1 -0
- package/dist/cost/types.js +228 -0
- package/dist/daemon/automationExecutor.d.ts +16 -0
- package/dist/daemon/automationExecutor.d.ts.map +1 -0
- package/dist/daemon/automationExecutor.js +222 -0
- package/dist/daemon/config.d.ts +8 -0
- package/dist/daemon/config.d.ts.map +1 -0
- package/dist/daemon/config.js +209 -0
- package/dist/daemon/daemonLog.d.ts +13 -0
- package/dist/daemon/daemonLog.d.ts.map +1 -0
- package/dist/daemon/daemonLog.js +64 -0
- package/dist/daemon/fileWatcher.d.ts +9 -0
- package/dist/daemon/fileWatcher.d.ts.map +1 -0
- package/dist/daemon/fileWatcher.js +141 -0
- package/dist/daemon/index.d.ts +13 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +22 -0
- package/dist/daemon/lifecycle.d.ts +12 -0
- package/dist/daemon/lifecycle.d.ts.map +1 -0
- package/dist/daemon/lifecycle.js +257 -0
- package/dist/daemon/loop.d.ts +21 -0
- package/dist/daemon/loop.d.ts.map +1 -0
- package/dist/daemon/loop.js +196 -0
- package/dist/daemon/timerScheduler.d.ts +13 -0
- package/dist/daemon/timerScheduler.d.ts.map +1 -0
- package/dist/daemon/timerScheduler.js +122 -0
- package/dist/daemon/types.d.ts +93 -0
- package/dist/daemon/types.d.ts.map +1 -0
- package/dist/daemon/types.js +25 -0
- package/dist/daemon/webhookListener.d.ts +6 -0
- package/dist/daemon/webhookListener.d.ts.map +1 -0
- package/dist/daemon/webhookListener.js +110 -0
- package/dist/execution/index.d.ts +8 -0
- package/dist/execution/index.d.ts.map +1 -0
- package/dist/execution/index.js +12 -0
- package/dist/execution/modes/docker.d.ts +21 -0
- package/dist/execution/modes/docker.d.ts.map +1 -0
- package/dist/execution/modes/docker.js +125 -0
- package/dist/execution/modes/index.d.ts +10 -0
- package/dist/execution/modes/index.d.ts.map +1 -0
- package/dist/execution/modes/index.js +14 -0
- package/dist/execution/modes/kubernetes.d.ts +29 -0
- package/dist/execution/modes/kubernetes.d.ts.map +1 -0
- package/dist/execution/modes/kubernetes.js +121 -0
- package/dist/execution/modes/local.d.ts +23 -0
- package/dist/execution/modes/local.d.ts.map +1 -0
- package/dist/execution/modes/local.js +102 -0
- package/dist/execution/modes/ssh.d.ts +23 -0
- package/dist/execution/modes/ssh.d.ts.map +1 -0
- package/dist/execution/modes/ssh.js +134 -0
- package/dist/execution/provider.d.ts +32 -0
- package/dist/execution/provider.d.ts.map +1 -0
- package/dist/execution/provider.js +90 -0
- package/dist/execution/types.d.ts +105 -0
- package/dist/execution/types.d.ts.map +1 -0
- package/dist/execution/types.js +9 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/observability/health.d.ts +19 -0
- package/dist/observability/health.d.ts.map +1 -0
- package/dist/observability/health.js +129 -0
- package/dist/observability/index.d.ts +6 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +20 -0
- package/dist/observability/runStatus.d.ts +44 -0
- package/dist/observability/runStatus.d.ts.map +1 -0
- package/dist/observability/runStatus.js +169 -0
- package/dist/observability/timeline.d.ts +11 -0
- package/dist/observability/timeline.d.ts.map +1 -0
- package/dist/observability/timeline.js +176 -0
- package/dist/observability/types.d.ts +62 -0
- package/dist/observability/types.d.ts.map +1 -0
- package/dist/observability/types.js +8 -0
- package/dist/observability/webhooks.d.ts +68 -0
- package/dist/observability/webhooks.d.ts.map +1 -0
- package/dist/observability/webhooks.js +132 -0
- package/dist/resources/budget-tracker.d.ts +56 -0
- package/dist/resources/budget-tracker.d.ts.map +1 -0
- package/dist/resources/budget-tracker.js +131 -0
- package/dist/resources/concurrency-guard.d.ts +55 -0
- package/dist/resources/concurrency-guard.d.ts.map +1 -0
- package/dist/resources/concurrency-guard.js +132 -0
- package/dist/resources/index.d.ts +12 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +20 -0
- package/dist/resources/manager.d.ts +49 -0
- package/dist/resources/manager.d.ts.map +1 -0
- package/dist/resources/manager.js +111 -0
- package/dist/resources/timeout-cascade.d.ts +56 -0
- package/dist/resources/timeout-cascade.d.ts.map +1 -0
- package/dist/resources/timeout-cascade.js +145 -0
- package/dist/resources/types.d.ts +108 -0
- package/dist/resources/types.d.ts.map +1 -0
- package/dist/resources/types.js +9 -0
- package/dist/session/context.d.ts +22 -0
- package/dist/session/context.d.ts.map +1 -0
- package/dist/session/context.js +113 -0
- package/dist/session/continuityState.d.ts +39 -0
- package/dist/session/continuityState.d.ts.map +1 -0
- package/dist/session/continuityState.js +164 -0
- package/dist/session/cost.d.ts +63 -0
- package/dist/session/cost.d.ts.map +1 -0
- package/dist/session/cost.js +194 -0
- package/dist/session/discovery.d.ts +22 -0
- package/dist/session/discovery.d.ts.map +1 -0
- package/dist/session/discovery.js +35 -0
- package/dist/session/history.d.ts +30 -0
- package/dist/session/history.d.ts.map +1 -0
- package/dist/session/history.js +143 -0
- package/dist/session/index.d.ts +20 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +78 -0
- package/dist/session/memoryExtraction.d.ts +65 -0
- package/dist/session/memoryExtraction.d.ts.map +1 -0
- package/dist/session/memoryExtraction.js +201 -0
- package/dist/session/parse.d.ts +45 -0
- package/dist/session/parse.d.ts.map +1 -0
- package/dist/session/parse.js +170 -0
- package/dist/session/persistence.d.ts +46 -0
- package/dist/session/persistence.d.ts.map +1 -0
- package/dist/session/persistence.js +180 -0
- package/dist/session/types.d.ts +267 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +45 -0
- package/dist/session/write.d.ts +61 -0
- package/dist/session/write.d.ts.map +1 -0
- package/dist/session/write.js +213 -0
- package/dist/telemetry/audit-log.d.ts +56 -0
- package/dist/telemetry/audit-log.d.ts.map +1 -0
- package/dist/telemetry/audit-log.js +59 -0
- package/dist/telemetry/index.d.ts +9 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +15 -0
- package/dist/telemetry/provider.d.ts +39 -0
- package/dist/telemetry/provider.d.ts.map +1 -0
- package/dist/telemetry/provider.js +91 -0
- package/dist/telemetry/span-tree.d.ts +46 -0
- package/dist/telemetry/span-tree.d.ts.map +1 -0
- package/dist/telemetry/span-tree.js +93 -0
- package/dist/telemetry/types.d.ts +85 -0
- package/dist/telemetry/types.d.ts.map +1 -0
- package/dist/telemetry/types.js +21 -0
- package/package.json +90 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Run Health Model (GAP-STATE-008).
|
|
4
|
+
*
|
|
5
|
+
* Computes a point-in-time health snapshot from journal events.
|
|
6
|
+
* Pure function — no file I/O, takes events as input.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.computeRunHealthFromEvents = computeRunHealthFromEvents;
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Defaults
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
const DEFAULT_CONFIG = {
|
|
14
|
+
stuckThresholdMs: 300_000, // 5 minutes
|
|
15
|
+
degradedErrorRate: 0.3,
|
|
16
|
+
failedErrorRate: 0.7,
|
|
17
|
+
maxPendingAge: 600_000, // 10 minutes
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Compute a health snapshot from an array of journal events.
|
|
21
|
+
*/
|
|
22
|
+
function computeRunHealthFromEvents(events, options) {
|
|
23
|
+
const config = { ...DEFAULT_CONFIG, ...options?.config };
|
|
24
|
+
const now = options?.now ?? Date.now();
|
|
25
|
+
// Track effects
|
|
26
|
+
const requestedAt = new Map(); // effectId → timestamp ms
|
|
27
|
+
const resolvedEffects = new Set();
|
|
28
|
+
let failedEffects = 0;
|
|
29
|
+
let totalLatency = 0;
|
|
30
|
+
let latencyCount = 0;
|
|
31
|
+
let lastActivityAt = null;
|
|
32
|
+
let hasRunFailed = false;
|
|
33
|
+
const iterations = new Set();
|
|
34
|
+
for (const event of events) {
|
|
35
|
+
lastActivityAt = event.recordedAt;
|
|
36
|
+
const ts = new Date(event.recordedAt).getTime();
|
|
37
|
+
if (event.type === "RUN_FAILED") {
|
|
38
|
+
hasRunFailed = true;
|
|
39
|
+
}
|
|
40
|
+
if (event.type === "EFFECT_REQUESTED") {
|
|
41
|
+
const effectId = typeof event.data.effectId === "string" ? event.data.effectId : undefined;
|
|
42
|
+
if (effectId) {
|
|
43
|
+
requestedAt.set(effectId, ts);
|
|
44
|
+
}
|
|
45
|
+
const iteration = typeof event.data.iteration === "number" ? event.data.iteration : undefined;
|
|
46
|
+
if (iteration != null) {
|
|
47
|
+
iterations.add(iteration);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (event.type === "EFFECT_RESOLVED") {
|
|
51
|
+
const effectId = typeof event.data.effectId === "string" ? event.data.effectId : undefined;
|
|
52
|
+
if (effectId) {
|
|
53
|
+
resolvedEffects.add(effectId);
|
|
54
|
+
const reqTs = requestedAt.get(effectId);
|
|
55
|
+
if (reqTs != null) {
|
|
56
|
+
totalLatency += ts - reqTs;
|
|
57
|
+
latencyCount++;
|
|
58
|
+
}
|
|
59
|
+
const status = typeof event.data.status === "string" ? event.data.status : undefined;
|
|
60
|
+
if (status === "error") {
|
|
61
|
+
failedEffects++;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Compute metrics
|
|
67
|
+
const totalEffects = requestedAt.size;
|
|
68
|
+
const resolvedCount = resolvedEffects.size;
|
|
69
|
+
const pendingCount = totalEffects - resolvedCount;
|
|
70
|
+
const errorRate = resolvedCount > 0 ? failedEffects / resolvedCount : 0;
|
|
71
|
+
const avgEffectLatencyMs = latencyCount > 0 ? Math.round(totalLatency / latencyCount) : 0;
|
|
72
|
+
// Oldest pending effect age
|
|
73
|
+
let oldestPendingAgeMs = 0;
|
|
74
|
+
for (const [effectId, reqTs] of requestedAt) {
|
|
75
|
+
if (!resolvedEffects.has(effectId)) {
|
|
76
|
+
const age = now - reqTs;
|
|
77
|
+
if (age > oldestPendingAgeMs) {
|
|
78
|
+
oldestPendingAgeMs = age;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const metrics = {
|
|
83
|
+
errorRate,
|
|
84
|
+
avgEffectLatencyMs,
|
|
85
|
+
pendingCount,
|
|
86
|
+
oldestPendingAgeMs,
|
|
87
|
+
iterationCount: iterations.size,
|
|
88
|
+
lastActivityAt,
|
|
89
|
+
totalEffects,
|
|
90
|
+
resolvedEffects: resolvedCount,
|
|
91
|
+
failedEffects,
|
|
92
|
+
};
|
|
93
|
+
// Determine status and issues
|
|
94
|
+
const issues = [];
|
|
95
|
+
let status = "healthy";
|
|
96
|
+
if (hasRunFailed) {
|
|
97
|
+
status = "failed";
|
|
98
|
+
issues.push("Run failed: RUN_FAILED event detected");
|
|
99
|
+
}
|
|
100
|
+
else if (errorRate >= config.failedErrorRate && resolvedCount > 0) {
|
|
101
|
+
status = "failed";
|
|
102
|
+
issues.push(`High error rate: ${(errorRate * 100).toFixed(1)}% exceeds failed threshold (${(config.failedErrorRate * 100).toFixed(1)}%)`);
|
|
103
|
+
}
|
|
104
|
+
else if (lastActivityAt != null &&
|
|
105
|
+
now - new Date(lastActivityAt).getTime() > config.stuckThresholdMs &&
|
|
106
|
+
pendingCount > 0) {
|
|
107
|
+
status = "stuck";
|
|
108
|
+
const idleMs = now - new Date(lastActivityAt).getTime();
|
|
109
|
+
issues.push(`Run stuck: no activity for ${Math.round(idleMs / 1000)}s (threshold: ${Math.round(config.stuckThresholdMs / 1000)}s)`);
|
|
110
|
+
}
|
|
111
|
+
else if (errorRate >= config.degradedErrorRate && resolvedCount > 0) {
|
|
112
|
+
status = "degraded";
|
|
113
|
+
issues.push(`Elevated error rate: ${(errorRate * 100).toFixed(1)}% exceeds degraded threshold (${(config.degradedErrorRate * 100).toFixed(1)}%)`);
|
|
114
|
+
}
|
|
115
|
+
// Additional issues (additive, don't change status)
|
|
116
|
+
if (oldestPendingAgeMs > config.maxPendingAge &&
|
|
117
|
+
status !== "failed") {
|
|
118
|
+
issues.push(`Oldest pending effect age: ${Math.round(oldestPendingAgeMs / 1000)}s exceeds max pending age (${Math.round(config.maxPendingAge / 1000)}s)`);
|
|
119
|
+
if (status === "healthy") {
|
|
120
|
+
status = "degraded";
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
status,
|
|
125
|
+
metrics,
|
|
126
|
+
issues,
|
|
127
|
+
computedAt: new Date(now).toISOString(),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { buildPhaseTimeline, buildPhaseTimelineFromEvents } from "./timeline";
|
|
2
|
+
export { computeRunHealthFromEvents } from "./health";
|
|
3
|
+
export { getRunHealthSnapshot, getOrchestrationStatus, getPendingWorkItems, type OrchestrationStatus, type OrchestrationPhase, type PendingWorkItem, } from "./runStatus";
|
|
4
|
+
export type { PhaseTimeline, PhaseEntry, PhaseName, Milestone, IterationTimeline, RunHealthSnapshot, RunHealthStatus, RunHealthMetrics, HealthConfig, } from "./types";
|
|
5
|
+
export { registerWebhook, unregisterWebhook, listWebhooks, buildWebhookEvent, evaluateAlertLevel, filterRegistrations, type AlertLevel, type WebhookEventType, type WebhookRegistration, type WebhookEvent, type WebhookDeliveryResult, type WebhookRegistry, type WebhookRegistrationInput, WEBHOOK_SCHEMA_VERSION, } from "./webhooks";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/observability/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,aAAa,EACb,UAAU,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,YAAY,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAC7B,sBAAsB,GACvB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WEBHOOK_SCHEMA_VERSION = exports.filterRegistrations = exports.evaluateAlertLevel = exports.buildWebhookEvent = exports.listWebhooks = exports.unregisterWebhook = exports.registerWebhook = exports.getPendingWorkItems = exports.getOrchestrationStatus = exports.getRunHealthSnapshot = exports.computeRunHealthFromEvents = exports.buildPhaseTimelineFromEvents = exports.buildPhaseTimeline = void 0;
|
|
4
|
+
var timeline_1 = require("./timeline");
|
|
5
|
+
Object.defineProperty(exports, "buildPhaseTimeline", { enumerable: true, get: function () { return timeline_1.buildPhaseTimeline; } });
|
|
6
|
+
Object.defineProperty(exports, "buildPhaseTimelineFromEvents", { enumerable: true, get: function () { return timeline_1.buildPhaseTimelineFromEvents; } });
|
|
7
|
+
var health_1 = require("./health");
|
|
8
|
+
Object.defineProperty(exports, "computeRunHealthFromEvents", { enumerable: true, get: function () { return health_1.computeRunHealthFromEvents; } });
|
|
9
|
+
var runStatus_1 = require("./runStatus");
|
|
10
|
+
Object.defineProperty(exports, "getRunHealthSnapshot", { enumerable: true, get: function () { return runStatus_1.getRunHealthSnapshot; } });
|
|
11
|
+
Object.defineProperty(exports, "getOrchestrationStatus", { enumerable: true, get: function () { return runStatus_1.getOrchestrationStatus; } });
|
|
12
|
+
Object.defineProperty(exports, "getPendingWorkItems", { enumerable: true, get: function () { return runStatus_1.getPendingWorkItems; } });
|
|
13
|
+
var webhooks_1 = require("./webhooks");
|
|
14
|
+
Object.defineProperty(exports, "registerWebhook", { enumerable: true, get: function () { return webhooks_1.registerWebhook; } });
|
|
15
|
+
Object.defineProperty(exports, "unregisterWebhook", { enumerable: true, get: function () { return webhooks_1.unregisterWebhook; } });
|
|
16
|
+
Object.defineProperty(exports, "listWebhooks", { enumerable: true, get: function () { return webhooks_1.listWebhooks; } });
|
|
17
|
+
Object.defineProperty(exports, "buildWebhookEvent", { enumerable: true, get: function () { return webhooks_1.buildWebhookEvent; } });
|
|
18
|
+
Object.defineProperty(exports, "evaluateAlertLevel", { enumerable: true, get: function () { return webhooks_1.evaluateAlertLevel; } });
|
|
19
|
+
Object.defineProperty(exports, "filterRegistrations", { enumerable: true, get: function () { return webhooks_1.filterRegistrations; } });
|
|
20
|
+
Object.defineProperty(exports, "WEBHOOK_SCHEMA_VERSION", { enumerable: true, get: function () { return webhooks_1.WEBHOOK_SCHEMA_VERSION; } });
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run status and inspection APIs (GAP-OBS-001, GAP-UX-005, GAP-UX-006).
|
|
3
|
+
*
|
|
4
|
+
* - getRunHealthSnapshot: wraps computeRunHealthFromEvents with journal loading
|
|
5
|
+
* - getOrchestrationStatus: structured status view combining metadata, health, effects
|
|
6
|
+
* - getPendingWorkItems: detailed inspection of pending effects
|
|
7
|
+
*/
|
|
8
|
+
import type { RunHealthSnapshot } from "./types";
|
|
9
|
+
/**
|
|
10
|
+
* Compute a health snapshot for a run by loading its journal.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getRunHealthSnapshot(runDir: string): Promise<RunHealthSnapshot>;
|
|
13
|
+
export type OrchestrationPhase = "created" | "running" | "waiting" | "completed" | "failed";
|
|
14
|
+
export interface OrchestrationStatus {
|
|
15
|
+
runId: string;
|
|
16
|
+
processId: string;
|
|
17
|
+
phase: OrchestrationPhase;
|
|
18
|
+
iterationCount: number;
|
|
19
|
+
totalEffects: number;
|
|
20
|
+
pendingEffects: number;
|
|
21
|
+
resolvedEffects: number;
|
|
22
|
+
failedEffects: number;
|
|
23
|
+
health: RunHealthSnapshot;
|
|
24
|
+
createdAt: string;
|
|
25
|
+
lastActivityAt: string | null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get structured orchestration status for a run.
|
|
29
|
+
*/
|
|
30
|
+
export declare function getOrchestrationStatus(runDir: string): Promise<OrchestrationStatus>;
|
|
31
|
+
export interface PendingWorkItem {
|
|
32
|
+
effectId: string;
|
|
33
|
+
taskId?: string;
|
|
34
|
+
kind?: string;
|
|
35
|
+
title?: string;
|
|
36
|
+
requestedAt: string;
|
|
37
|
+
ageMs: number;
|
|
38
|
+
labels?: string[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* List pending (unresolved) effects with rich detail.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getPendingWorkItems(runDir: string): Promise<PendingWorkItem[]>;
|
|
44
|
+
//# sourceMappingURL=runStatus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runStatus.d.ts","sourceRoot":"","sources":["../../src/observability/runStatus.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAMjD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,CAAC,CAG5B;AAMD,MAAM,MAAM,kBAAkB,GAC1B,SAAS,GACT,SAAS,GACT,SAAS,GACT,WAAW,GACX,QAAQ,CAAC;AAEb,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,mBAAmB,CAAC,CAqC9B;AAMD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,EAAE,CAAC,CA4E5B"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Run status and inspection APIs (GAP-OBS-001, GAP-UX-005, GAP-UX-006).
|
|
4
|
+
*
|
|
5
|
+
* - getRunHealthSnapshot: wraps computeRunHealthFromEvents with journal loading
|
|
6
|
+
* - getOrchestrationStatus: structured status view combining metadata, health, effects
|
|
7
|
+
* - getPendingWorkItems: detailed inspection of pending effects
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.getRunHealthSnapshot = getRunHealthSnapshot;
|
|
44
|
+
exports.getOrchestrationStatus = getOrchestrationStatus;
|
|
45
|
+
exports.getPendingWorkItems = getPendingWorkItems;
|
|
46
|
+
const node_fs_1 = require("node:fs");
|
|
47
|
+
const path = __importStar(require("node:path"));
|
|
48
|
+
const babysitter_sdk_1 = require("@a5c-ai/babysitter-sdk");
|
|
49
|
+
const health_1 = require("./health");
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// GAP-OBS-001: Run Health Snapshot
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
/**
|
|
54
|
+
* Compute a health snapshot for a run by loading its journal.
|
|
55
|
+
*/
|
|
56
|
+
async function getRunHealthSnapshot(runDir) {
|
|
57
|
+
const events = await (0, babysitter_sdk_1.loadJournal)(runDir);
|
|
58
|
+
return (0, health_1.computeRunHealthFromEvents)(events);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get structured orchestration status for a run.
|
|
62
|
+
*/
|
|
63
|
+
async function getOrchestrationStatus(runDir) {
|
|
64
|
+
const [metadata, events] = await Promise.all([
|
|
65
|
+
(0, babysitter_sdk_1.readRunMetadata)(runDir),
|
|
66
|
+
(0, babysitter_sdk_1.loadJournal)(runDir),
|
|
67
|
+
]);
|
|
68
|
+
const health = (0, health_1.computeRunHealthFromEvents)(events);
|
|
69
|
+
// Determine phase from events
|
|
70
|
+
let phase = "created";
|
|
71
|
+
const hasCompleted = events.some((e) => e.type === "RUN_COMPLETED");
|
|
72
|
+
const hasFailed = events.some((e) => e.type === "RUN_FAILED");
|
|
73
|
+
const hasPending = health.metrics.pendingCount > 0;
|
|
74
|
+
if (hasFailed) {
|
|
75
|
+
phase = "failed";
|
|
76
|
+
}
|
|
77
|
+
else if (hasCompleted) {
|
|
78
|
+
phase = "completed";
|
|
79
|
+
}
|
|
80
|
+
else if (hasPending) {
|
|
81
|
+
phase = "waiting";
|
|
82
|
+
}
|
|
83
|
+
else if (events.length > 1) {
|
|
84
|
+
phase = "running";
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
runId: metadata.runId,
|
|
88
|
+
processId: metadata.processId,
|
|
89
|
+
phase,
|
|
90
|
+
iterationCount: health.metrics.iterationCount,
|
|
91
|
+
totalEffects: health.metrics.totalEffects,
|
|
92
|
+
pendingEffects: health.metrics.pendingCount,
|
|
93
|
+
resolvedEffects: health.metrics.resolvedEffects,
|
|
94
|
+
failedEffects: health.metrics.failedEffects,
|
|
95
|
+
health,
|
|
96
|
+
createdAt: metadata.createdAt,
|
|
97
|
+
lastActivityAt: health.metrics.lastActivityAt,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* List pending (unresolved) effects with rich detail.
|
|
102
|
+
*/
|
|
103
|
+
async function getPendingWorkItems(runDir) {
|
|
104
|
+
const events = await (0, babysitter_sdk_1.loadJournal)(runDir);
|
|
105
|
+
const now = Date.now();
|
|
106
|
+
// Track requested and resolved effect IDs
|
|
107
|
+
const requested = new Map();
|
|
108
|
+
const resolved = new Set();
|
|
109
|
+
for (const event of events) {
|
|
110
|
+
if (event.type === "EFFECT_REQUESTED") {
|
|
111
|
+
const effectId = typeof event.data.effectId === "string"
|
|
112
|
+
? event.data.effectId
|
|
113
|
+
: undefined;
|
|
114
|
+
if (effectId) {
|
|
115
|
+
requested.set(effectId, {
|
|
116
|
+
effectId,
|
|
117
|
+
requestedAt: event.recordedAt,
|
|
118
|
+
data: event.data,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (event.type === "EFFECT_RESOLVED") {
|
|
123
|
+
const effectId = typeof event.data.effectId === "string"
|
|
124
|
+
? event.data.effectId
|
|
125
|
+
: undefined;
|
|
126
|
+
if (effectId) {
|
|
127
|
+
resolved.add(effectId);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Build pending items
|
|
132
|
+
const items = [];
|
|
133
|
+
for (const [effectId, req] of requested) {
|
|
134
|
+
if (resolved.has(effectId))
|
|
135
|
+
continue;
|
|
136
|
+
const reqTs = new Date(req.requestedAt).getTime();
|
|
137
|
+
// Try to read task definition for richer details
|
|
138
|
+
let title;
|
|
139
|
+
let kind;
|
|
140
|
+
let taskId;
|
|
141
|
+
let labels;
|
|
142
|
+
try {
|
|
143
|
+
const taskPath = path.join(runDir, "tasks", effectId, "task.json");
|
|
144
|
+
const raw = await node_fs_1.promises.readFile(taskPath, "utf-8");
|
|
145
|
+
const taskDef = JSON.parse(raw);
|
|
146
|
+
title = typeof taskDef.title === "string" ? taskDef.title : undefined;
|
|
147
|
+
kind = typeof taskDef.kind === "string" ? taskDef.kind : undefined;
|
|
148
|
+
taskId = typeof taskDef.taskId === "string" ? taskDef.taskId : undefined;
|
|
149
|
+
labels = Array.isArray(taskDef.labels) ? taskDef.labels : undefined;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// Task def may not exist for all effect types
|
|
153
|
+
kind = typeof req.data.kind === "string" ? req.data.kind : undefined;
|
|
154
|
+
taskId = typeof req.data.taskId === "string" ? req.data.taskId : undefined;
|
|
155
|
+
}
|
|
156
|
+
items.push({
|
|
157
|
+
effectId,
|
|
158
|
+
taskId,
|
|
159
|
+
kind,
|
|
160
|
+
title,
|
|
161
|
+
requestedAt: req.requestedAt,
|
|
162
|
+
ageMs: now - reqTs,
|
|
163
|
+
labels,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
// Sort by age descending (oldest first)
|
|
167
|
+
items.sort((a, b) => b.ageMs - a.ageMs);
|
|
168
|
+
return items;
|
|
169
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GAP-OBS-NEW-002: Phase Timeline Visualization.
|
|
3
|
+
*
|
|
4
|
+
* Synthesizes phase timeline data from journal events. Identifies planning,
|
|
5
|
+
* execution, verification, and completion phases with duration metrics.
|
|
6
|
+
*/
|
|
7
|
+
import { type JournalEvent } from "@a5c-ai/babysitter-sdk";
|
|
8
|
+
import type { PhaseTimeline } from "./types";
|
|
9
|
+
export declare function buildPhaseTimelineFromEvents(events: JournalEvent[]): PhaseTimeline;
|
|
10
|
+
export declare function buildPhaseTimeline(runDir: string): Promise<PhaseTimeline>;
|
|
11
|
+
//# sourceMappingURL=timeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/observability/timeline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EACV,aAAa,EAKd,MAAM,SAAS,CAAC;AA2BjB,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,aAAa,CA6HlF;AAoCD,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAG/E"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* GAP-OBS-NEW-002: Phase Timeline Visualization.
|
|
4
|
+
*
|
|
5
|
+
* Synthesizes phase timeline data from journal events. Identifies planning,
|
|
6
|
+
* execution, verification, and completion phases with duration metrics.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.buildPhaseTimelineFromEvents = buildPhaseTimelineFromEvents;
|
|
10
|
+
exports.buildPhaseTimeline = buildPhaseTimeline;
|
|
11
|
+
const babysitter_sdk_1 = require("@a5c-ai/babysitter-sdk");
|
|
12
|
+
const VERIFICATION_TASK_IDS = new Set([
|
|
13
|
+
"typecheck",
|
|
14
|
+
"lint",
|
|
15
|
+
"run-tests",
|
|
16
|
+
"adversarial-review",
|
|
17
|
+
]);
|
|
18
|
+
function ms(a, b) {
|
|
19
|
+
return new Date(b).getTime() - new Date(a).getTime();
|
|
20
|
+
}
|
|
21
|
+
function makePhase(name, startedAt, endedAt) {
|
|
22
|
+
return {
|
|
23
|
+
name,
|
|
24
|
+
startedAt,
|
|
25
|
+
endedAt,
|
|
26
|
+
durationMs: endedAt ? ms(startedAt, endedAt) : null,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function isVerificationEvent(event) {
|
|
30
|
+
const taskId = event.data.taskId;
|
|
31
|
+
return taskId != null && VERIFICATION_TASK_IDS.has(taskId);
|
|
32
|
+
}
|
|
33
|
+
function buildPhaseTimelineFromEvents(events) {
|
|
34
|
+
if (events.length === 0) {
|
|
35
|
+
return {
|
|
36
|
+
phases: [],
|
|
37
|
+
milestones: [],
|
|
38
|
+
iterations: [],
|
|
39
|
+
currentPhase: "planning",
|
|
40
|
+
totalDurationMs: null,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const phases = [];
|
|
44
|
+
const milestones = [];
|
|
45
|
+
let currentPhase = "planning";
|
|
46
|
+
const firstEvent = events[0];
|
|
47
|
+
const lastEvent = events[events.length - 1];
|
|
48
|
+
// Find key transition points
|
|
49
|
+
const firstEffectReq = events.find((e) => e.type === "EFFECT_REQUESTED");
|
|
50
|
+
const runCompleted = events.find((e) => e.type === "RUN_COMPLETED");
|
|
51
|
+
const runFailed = events.find((e) => e.type === "RUN_FAILED");
|
|
52
|
+
// Find first verification event (typecheck/lint/test/review)
|
|
53
|
+
const firstVerificationReq = events.find((e) => e.type === "EFFECT_REQUESTED" && isVerificationEvent(e));
|
|
54
|
+
const lastVerificationResolved = [...events]
|
|
55
|
+
.reverse()
|
|
56
|
+
.find((e) => e.type === "EFFECT_RESOLVED" && isVerificationEvent(e));
|
|
57
|
+
// Phase 1: Planning — from RUN_CREATED to first EFFECT_REQUESTED
|
|
58
|
+
if (firstEvent.type === "RUN_CREATED") {
|
|
59
|
+
const planEnd = firstEffectReq?.recordedAt ?? null;
|
|
60
|
+
phases.push(makePhase("planning", firstEvent.recordedAt, planEnd));
|
|
61
|
+
if (planEnd) {
|
|
62
|
+
currentPhase = "execution";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Phase 2: Execution — from first EFFECT_REQUESTED to verification start (or last resolved)
|
|
66
|
+
if (firstEffectReq) {
|
|
67
|
+
// Find the last non-verification EFFECT_RESOLVED as fallback execution end
|
|
68
|
+
const lastNonVerifResolved = [...events]
|
|
69
|
+
.reverse()
|
|
70
|
+
.find((e) => e.type === "EFFECT_RESOLVED" && !isVerificationEvent(e));
|
|
71
|
+
const execEnd = firstVerificationReq?.recordedAt
|
|
72
|
+
?? runCompleted?.recordedAt
|
|
73
|
+
?? runFailed?.recordedAt
|
|
74
|
+
?? lastNonVerifResolved?.recordedAt
|
|
75
|
+
?? null;
|
|
76
|
+
phases.push(makePhase("execution", firstEffectReq.recordedAt, execEnd));
|
|
77
|
+
currentPhase = execEnd ? (firstVerificationReq ? "verification" : "execution") : "execution";
|
|
78
|
+
}
|
|
79
|
+
// Phase 3: Verification — quality gates
|
|
80
|
+
if (firstVerificationReq) {
|
|
81
|
+
const verEnd = lastVerificationResolved?.recordedAt
|
|
82
|
+
?? runCompleted?.recordedAt
|
|
83
|
+
?? runFailed?.recordedAt
|
|
84
|
+
?? null;
|
|
85
|
+
phases.push(makePhase("verification", firstVerificationReq.recordedAt, verEnd));
|
|
86
|
+
currentPhase = verEnd ? "completion" : "verification";
|
|
87
|
+
}
|
|
88
|
+
// Phase 4: Completion
|
|
89
|
+
if (runCompleted) {
|
|
90
|
+
phases.push(makePhase("completion", runCompleted.recordedAt, runCompleted.recordedAt));
|
|
91
|
+
currentPhase = "completed";
|
|
92
|
+
}
|
|
93
|
+
else if (runFailed) {
|
|
94
|
+
phases.push(makePhase("completion", runFailed.recordedAt, runFailed.recordedAt));
|
|
95
|
+
currentPhase = "failed";
|
|
96
|
+
}
|
|
97
|
+
// Extract milestones
|
|
98
|
+
for (const event of events) {
|
|
99
|
+
if (event.type === "EFFECT_RESOLVED" && event.data.kind === "breakpoint") {
|
|
100
|
+
milestones.push({
|
|
101
|
+
type: "breakpoint",
|
|
102
|
+
label: event.data.title ?? `Breakpoint ${event.data.effectId}`,
|
|
103
|
+
occurredAt: event.recordedAt,
|
|
104
|
+
data: event.data,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (event.type === "EFFECT_RESOLVED" &&
|
|
108
|
+
(event.data.taskId === "adversarial-review")) {
|
|
109
|
+
milestones.push({
|
|
110
|
+
type: "quality-gate",
|
|
111
|
+
label: `Quality review: ${event.data.taskId}`,
|
|
112
|
+
occurredAt: event.recordedAt,
|
|
113
|
+
data: event.data,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (event.type === "RUN_COMPLETED") {
|
|
117
|
+
milestones.push({
|
|
118
|
+
type: "run-completed",
|
|
119
|
+
label: "Run completed",
|
|
120
|
+
occurredAt: event.recordedAt,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (event.type === "RUN_FAILED") {
|
|
124
|
+
milestones.push({
|
|
125
|
+
type: "run-failed",
|
|
126
|
+
label: "Run failed",
|
|
127
|
+
occurredAt: event.recordedAt,
|
|
128
|
+
data: event.data,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Build iteration breakdowns
|
|
133
|
+
const iterations = buildIterations(events);
|
|
134
|
+
const totalDurationMs = events.length >= 2 ? ms(firstEvent.recordedAt, lastEvent.recordedAt) : null;
|
|
135
|
+
return {
|
|
136
|
+
phases,
|
|
137
|
+
milestones,
|
|
138
|
+
iterations,
|
|
139
|
+
currentPhase,
|
|
140
|
+
totalDurationMs,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function buildIterations(events) {
|
|
144
|
+
const iterationMap = new Map();
|
|
145
|
+
for (const event of events) {
|
|
146
|
+
const iter = event.data.iteration;
|
|
147
|
+
if (iter != null) {
|
|
148
|
+
let group = iterationMap.get(iter);
|
|
149
|
+
if (!group) {
|
|
150
|
+
group = [];
|
|
151
|
+
iterationMap.set(iter, group);
|
|
152
|
+
}
|
|
153
|
+
group.push(event);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const iterations = [];
|
|
157
|
+
for (const [iteration, iterEvents] of iterationMap) {
|
|
158
|
+
if (iterEvents.length === 0)
|
|
159
|
+
continue;
|
|
160
|
+
const first = iterEvents[0];
|
|
161
|
+
const last = iterEvents[iterEvents.length - 1];
|
|
162
|
+
const endedAt = last.type === "EFFECT_RESOLVED" ? last.recordedAt : null;
|
|
163
|
+
iterations.push({
|
|
164
|
+
iteration,
|
|
165
|
+
phases: [], // Per-iteration phase breakdown could be added later
|
|
166
|
+
startedAt: first.recordedAt,
|
|
167
|
+
endedAt,
|
|
168
|
+
durationMs: endedAt ? ms(first.recordedAt, endedAt) : null,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return iterations.sort((a, b) => a.iteration - b.iteration);
|
|
172
|
+
}
|
|
173
|
+
async function buildPhaseTimeline(runDir) {
|
|
174
|
+
const events = await (0, babysitter_sdk_1.loadJournal)(runDir);
|
|
175
|
+
return buildPhaseTimelineFromEvents(events);
|
|
176
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observability types.
|
|
3
|
+
*
|
|
4
|
+
* GAP-OBS-NEW-002: Phase Timeline types.
|
|
5
|
+
* GAP-STATE-008: Run Health Model types.
|
|
6
|
+
*/
|
|
7
|
+
export type RunHealthStatus = "healthy" | "degraded" | "stuck" | "failed";
|
|
8
|
+
export interface RunHealthMetrics {
|
|
9
|
+
errorRate: number;
|
|
10
|
+
avgEffectLatencyMs: number;
|
|
11
|
+
pendingCount: number;
|
|
12
|
+
oldestPendingAgeMs: number;
|
|
13
|
+
iterationCount: number;
|
|
14
|
+
lastActivityAt: string | null;
|
|
15
|
+
totalEffects: number;
|
|
16
|
+
resolvedEffects: number;
|
|
17
|
+
failedEffects: number;
|
|
18
|
+
}
|
|
19
|
+
export interface RunHealthSnapshot {
|
|
20
|
+
status: RunHealthStatus;
|
|
21
|
+
metrics: RunHealthMetrics;
|
|
22
|
+
issues: string[];
|
|
23
|
+
computedAt: string;
|
|
24
|
+
}
|
|
25
|
+
export interface HealthConfig {
|
|
26
|
+
/** Threshold for detecting stuck runs (default: 300000ms = 5min). */
|
|
27
|
+
stuckThresholdMs: number;
|
|
28
|
+
/** Error rate above which run is 'degraded' (default: 0.3). */
|
|
29
|
+
degradedErrorRate: number;
|
|
30
|
+
/** Error rate above which run is 'failed' (default: 0.7). */
|
|
31
|
+
failedErrorRate: number;
|
|
32
|
+
/** Max age for pending effects before generating issue (default: 600000ms = 10min). */
|
|
33
|
+
maxPendingAge: number;
|
|
34
|
+
}
|
|
35
|
+
export type PhaseName = "planning" | "execution" | "verification" | "completion";
|
|
36
|
+
export interface PhaseEntry {
|
|
37
|
+
name: PhaseName;
|
|
38
|
+
startedAt: string;
|
|
39
|
+
endedAt: string | null;
|
|
40
|
+
durationMs: number | null;
|
|
41
|
+
}
|
|
42
|
+
export interface Milestone {
|
|
43
|
+
type: "breakpoint" | "quality-gate" | "run-completed" | "run-failed";
|
|
44
|
+
label: string;
|
|
45
|
+
occurredAt: string;
|
|
46
|
+
data?: Record<string, unknown>;
|
|
47
|
+
}
|
|
48
|
+
export interface IterationTimeline {
|
|
49
|
+
iteration: number;
|
|
50
|
+
phases: PhaseEntry[];
|
|
51
|
+
startedAt: string;
|
|
52
|
+
endedAt: string | null;
|
|
53
|
+
durationMs: number | null;
|
|
54
|
+
}
|
|
55
|
+
export interface PhaseTimeline {
|
|
56
|
+
phases: PhaseEntry[];
|
|
57
|
+
milestones: Milestone[];
|
|
58
|
+
iterations: IterationTimeline[];
|
|
59
|
+
currentPhase: PhaseName | "completed" | "failed";
|
|
60
|
+
totalDurationMs: number | null;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/observability/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE1E,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,eAAe,EAAE,MAAM,CAAC;IACxB,uFAAuF;IACvF,aAAa,EAAE,MAAM,CAAC;CACvB;AAMD,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,cAAc,GAAG,YAAY,CAAC;AAEjF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,YAAY,GAAG,cAAc,GAAG,eAAe,GAAG,YAAY,CAAC;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,YAAY,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IACjD,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC"}
|