@useorgx/openclaw-plugin 0.4.9 → 0.7.2
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 +77 -11
- package/dashboard/dist/assets/6mILZQ2a.js +1 -0
- package/dashboard/dist/assets/6mILZQ2a.js.br +0 -0
- package/dashboard/dist/assets/6mILZQ2a.js.gz +0 -0
- package/dashboard/dist/assets/8dksYiq4.js +2 -0
- package/dashboard/dist/assets/8dksYiq4.js.br +0 -0
- package/dashboard/dist/assets/8dksYiq4.js.gz +0 -0
- package/dashboard/dist/assets/B5zYRHc3.js +1 -0
- package/dashboard/dist/assets/B5zYRHc3.js.br +0 -0
- package/dashboard/dist/assets/B5zYRHc3.js.gz +0 -0
- package/dashboard/dist/assets/B6wPWJ35.js +1 -0
- package/dashboard/dist/assets/B6wPWJ35.js.br +0 -0
- package/dashboard/dist/assets/B6wPWJ35.js.gz +0 -0
- package/dashboard/dist/assets/BJgZIVUQ.js +53 -0
- package/dashboard/dist/assets/BJgZIVUQ.js.br +0 -0
- package/dashboard/dist/assets/BJgZIVUQ.js.gz +0 -0
- package/dashboard/dist/assets/BWEwjt1W.js +1 -0
- package/dashboard/dist/assets/BWEwjt1W.js.br +0 -0
- package/dashboard/dist/assets/BWEwjt1W.js.gz +0 -0
- package/dashboard/dist/assets/BgOYB78t.js +4 -0
- package/dashboard/dist/assets/BgOYB78t.js.br +0 -0
- package/dashboard/dist/assets/BgOYB78t.js.gz +0 -0
- package/dashboard/dist/assets/BzRbDCAD.css +1 -0
- package/dashboard/dist/assets/BzRbDCAD.css.br +0 -0
- package/dashboard/dist/assets/BzRbDCAD.css.gz +0 -0
- package/dashboard/dist/assets/C-KIc3Wc.js.br +0 -0
- package/dashboard/dist/assets/C-KIc3Wc.js.gz +0 -0
- package/dashboard/dist/assets/C8uM3AX8.js +1 -0
- package/dashboard/dist/assets/C8uM3AX8.js.br +0 -0
- package/dashboard/dist/assets/C8uM3AX8.js.gz +0 -0
- package/dashboard/dist/assets/C9jy61eu.js +212 -0
- package/dashboard/dist/assets/C9jy61eu.js.br +0 -0
- package/dashboard/dist/assets/C9jy61eu.js.gz +0 -0
- package/dashboard/dist/assets/CC63EwFD.js +1 -0
- package/dashboard/dist/assets/CC63EwFD.js.br +0 -0
- package/dashboard/dist/assets/CC63EwFD.js.gz +0 -0
- package/dashboard/dist/assets/CL_wXqR7.js +1 -0
- package/dashboard/dist/assets/CL_wXqR7.js.br +0 -0
- package/dashboard/dist/assets/CL_wXqR7.js.gz +0 -0
- package/dashboard/dist/assets/CZaT3ob_.js +1 -0
- package/dashboard/dist/assets/CZaT3ob_.js.br +0 -0
- package/dashboard/dist/assets/CZaT3ob_.js.gz +0 -0
- package/dashboard/dist/assets/CgaottFX.js +1 -0
- package/dashboard/dist/assets/CgaottFX.js.br +0 -0
- package/dashboard/dist/assets/CgaottFX.js.gz +0 -0
- package/dashboard/dist/assets/{CpJsfbXo.js → CxQ08qFN.js} +2 -2
- package/dashboard/dist/assets/CxQ08qFN.js.br +0 -0
- package/dashboard/dist/assets/CxQ08qFN.js.gz +0 -0
- package/dashboard/dist/assets/CzCxAZlW.js +1 -0
- package/dashboard/dist/assets/CzCxAZlW.js.br +0 -0
- package/dashboard/dist/assets/CzCxAZlW.js.gz +0 -0
- package/dashboard/dist/assets/D3iMTYEj.js +1 -0
- package/dashboard/dist/assets/D3iMTYEj.js.br +0 -0
- package/dashboard/dist/assets/D3iMTYEj.js.gz +0 -0
- package/dashboard/dist/assets/D8JNX8kq.js +2 -0
- package/dashboard/dist/assets/D8JNX8kq.js.br +0 -0
- package/dashboard/dist/assets/D8JNX8kq.js.gz +0 -0
- package/dashboard/dist/assets/DnA8dpj6.js +1 -0
- package/dashboard/dist/assets/DnA8dpj6.js.br +0 -0
- package/dashboard/dist/assets/DnA8dpj6.js.gz +0 -0
- package/dashboard/dist/assets/IUexzymk.js +1 -0
- package/dashboard/dist/assets/IUexzymk.js.br +0 -0
- package/dashboard/dist/assets/IUexzymk.js.gz +0 -0
- package/dashboard/dist/assets/cNrhgGc1.js +8 -0
- package/dashboard/dist/assets/cNrhgGc1.js.br +0 -0
- package/dashboard/dist/assets/cNrhgGc1.js.gz +0 -0
- package/dashboard/dist/assets/ic2FaMnh.js +1 -0
- package/dashboard/dist/assets/ic2FaMnh.js.br +0 -0
- package/dashboard/dist/assets/ic2FaMnh.js.gz +0 -0
- package/dashboard/dist/assets/qm8xLgv-.css +1 -0
- package/dashboard/dist/assets/qm8xLgv-.css.br +0 -0
- package/dashboard/dist/assets/qm8xLgv-.css.gz +0 -0
- package/dashboard/dist/assets/rttbDbEx.js +1 -0
- package/dashboard/dist/assets/rttbDbEx.js.br +0 -0
- package/dashboard/dist/assets/rttbDbEx.js.gz +0 -0
- package/dashboard/dist/brand/anthropic-mark.svg.br +0 -0
- package/dashboard/dist/brand/anthropic-mark.svg.gz +0 -0
- package/dashboard/dist/brand/openai-mark.svg.br +0 -0
- package/dashboard/dist/brand/openai-mark.svg.gz +0 -0
- package/dashboard/dist/brand/openclaw-mark.svg.br +0 -0
- package/dashboard/dist/brand/openclaw-mark.svg.gz +0 -0
- package/dashboard/dist/brand/xandy-orchestrator.png +0 -0
- package/dashboard/dist/index.html +7 -5
- package/dashboard/dist/index.html.br +0 -0
- package/dashboard/dist/index.html.gz +0 -0
- package/dist/activity-actor-fields.js +26 -4
- package/dist/activity-store.js +34 -8
- package/dist/agent-context-store.js +79 -17
- package/dist/agent-run-store.js +44 -3
- package/dist/agent-suite.d.ts +9 -0
- package/dist/agent-suite.js +149 -9
- package/dist/artifacts/artifact-domain-schemas.d.ts +66 -0
- package/dist/artifacts/artifact-domain-schemas.js +357 -0
- package/dist/artifacts/register-artifact.d.ts +4 -3
- package/dist/artifacts/register-artifact.js +170 -57
- package/dist/chat-store.d.ts +157 -0
- package/dist/chat-store.js +586 -0
- package/dist/cli/orgx.js +11 -0
- package/dist/contracts/client.d.ts +43 -3
- package/dist/contracts/client.js +159 -30
- package/dist/contracts/practice-exercise-schema.d.ts +216 -0
- package/dist/contracts/practice-exercise-schema.js +314 -0
- package/dist/contracts/retro-schema.d.ts +81 -0
- package/dist/contracts/retro-schema.js +80 -0
- package/dist/contracts/shared-types.d.ts +159 -0
- package/dist/contracts/shared-types.js +199 -1
- package/dist/contracts/skill-pack-schema.d.ts +192 -0
- package/dist/contracts/skill-pack-schema.js +180 -0
- package/dist/contracts/types.d.ts +247 -2
- package/dist/entities/auto-assignment.js +43 -17
- package/dist/event-sanitization.d.ts +11 -0
- package/dist/event-sanitization.js +113 -0
- package/dist/gateway-watchdog.d.ts +5 -0
- package/dist/gateway-watchdog.js +50 -0
- package/dist/hooks/post-reporting-event.mjs +1 -5
- package/dist/http/helpers/activity-headline.js +13 -132
- package/dist/http/helpers/auto-continue-engine.d.ts +198 -10
- package/dist/http/helpers/auto-continue-engine.js +3145 -186
- package/dist/http/helpers/autopilot-operations.d.ts +19 -0
- package/dist/http/helpers/autopilot-operations.js +182 -31
- package/dist/http/helpers/autopilot-runtime.d.ts +1 -0
- package/dist/http/helpers/autopilot-runtime.js +328 -25
- package/dist/http/helpers/autopilot-slice-utils.d.ts +18 -0
- package/dist/http/helpers/autopilot-slice-utils.js +514 -93
- package/dist/http/helpers/decision-mapper.d.ts +40 -0
- package/dist/http/helpers/decision-mapper.js +223 -7
- package/dist/http/helpers/dispatch-lifecycle.d.ts +19 -2
- package/dist/http/helpers/dispatch-lifecycle.js +242 -37
- package/dist/http/helpers/kickoff-context.js +104 -0
- package/dist/http/helpers/llm-client.d.ts +47 -0
- package/dist/http/helpers/llm-client.js +256 -0
- package/dist/http/helpers/mission-control.d.ts +102 -3
- package/dist/http/helpers/mission-control.js +498 -9
- package/dist/http/helpers/sentinel-catalog.d.ts +23 -0
- package/dist/http/helpers/sentinel-catalog.js +193 -0
- package/dist/http/helpers/session-classification.d.ts +9 -0
- package/dist/http/helpers/session-classification.js +564 -0
- package/dist/http/helpers/slice-experience-v2.d.ts +137 -0
- package/dist/http/helpers/slice-experience-v2.js +677 -0
- package/dist/http/helpers/slice-run-projections.d.ts +72 -0
- package/dist/http/helpers/slice-run-projections.js +877 -0
- package/dist/http/helpers/triage-mapper.d.ts +43 -0
- package/dist/http/helpers/triage-mapper.js +549 -0
- package/dist/http/helpers/value-utils.js +7 -2
- package/dist/http/helpers/workspace-scope.d.ts +15 -0
- package/dist/http/helpers/workspace-scope.js +170 -0
- package/dist/http/index.js +1420 -105
- package/dist/http/routes/agent-suite.d.ts +9 -0
- package/dist/http/routes/agent-suite.js +294 -8
- package/dist/http/routes/agents-catalog.js +64 -19
- package/dist/http/routes/chat.d.ts +19 -0
- package/dist/http/routes/chat.js +522 -0
- package/dist/http/routes/decision-actions.d.ts +8 -1
- package/dist/http/routes/decision-actions.js +42 -5
- package/dist/http/routes/dispatch-gateway-envelope.d.ts +25 -0
- package/dist/http/routes/dispatch-gateway-envelope.js +26 -0
- package/dist/http/routes/entities.d.ts +16 -0
- package/dist/http/routes/entities.js +232 -6
- package/dist/http/routes/live-legacy.d.ts +5 -0
- package/dist/http/routes/live-legacy.js +23 -509
- package/dist/http/routes/live-misc.d.ts +12 -0
- package/dist/http/routes/live-misc.js +251 -31
- package/dist/http/routes/live-snapshot.d.ts +49 -2
- package/dist/http/routes/live-snapshot.js +653 -23
- package/dist/http/routes/live-terminal.d.ts +11 -0
- package/dist/http/routes/live-terminal.js +154 -0
- package/dist/http/routes/live-triage.d.ts +61 -0
- package/dist/http/routes/live-triage.js +192 -0
- package/dist/http/routes/mission-control-actions.d.ts +49 -1
- package/dist/http/routes/mission-control-actions.js +1246 -84
- package/dist/http/routes/mission-control-read.d.ts +48 -3
- package/dist/http/routes/mission-control-read.js +1658 -20
- package/dist/http/routes/realtime-orchestrator.d.ts +10 -0
- package/dist/http/routes/realtime-orchestrator.js +74 -0
- package/dist/http/routes/run-control.d.ts +5 -2
- package/dist/http/routes/run-control.js +10 -0
- package/dist/http/routes/sentinels-catalog.d.ts +7 -0
- package/dist/http/routes/sentinels-catalog.js +24 -0
- package/dist/http/routes/summary.js +10 -3
- package/dist/http/routes/usage.d.ts +24 -0
- package/dist/http/routes/usage.js +362 -0
- package/dist/http/routes/work-artifacts.js +28 -9
- package/dist/index.js +165 -27
- package/dist/local-openclaw.js +29 -6
- package/dist/mcp-client-setup.js +3 -3
- package/dist/mcp-http-handler.d.ts +3 -0
- package/dist/mcp-http-handler.js +34 -60
- package/dist/next-up-queue-store.d.ts +16 -1
- package/dist/next-up-queue-store.js +89 -7
- package/dist/outbox.d.ts +5 -0
- package/dist/outbox.js +113 -9
- package/dist/paths.js +36 -5
- package/dist/reporting/rollups.d.ts +41 -0
- package/dist/reporting/rollups.js +113 -0
- package/dist/retro/domain-templates.d.ts +45 -0
- package/dist/retro/domain-templates.js +297 -0
- package/dist/retro/quality-rubric.d.ts +33 -0
- package/dist/retro/quality-rubric.js +213 -0
- package/dist/runtime-cleanup.d.ts +18 -0
- package/dist/runtime-cleanup.js +87 -0
- package/dist/services/background.d.ts +11 -0
- package/dist/services/background.js +22 -0
- package/dist/services/experiment-randomization.d.ts +21 -0
- package/dist/services/experiment-randomization.js +63 -0
- package/dist/skill-pack-state.d.ts +36 -5
- package/dist/skill-pack-state.js +273 -29
- package/dist/sync/local-agent-telemetry.d.ts +13 -0
- package/dist/sync/local-agent-telemetry.js +128 -0
- package/dist/sync/outbox-replay.js +131 -24
- package/dist/team-context-store.d.ts +23 -0
- package/dist/team-context-store.js +116 -0
- package/dist/telemetry/posthog.js +4 -2
- package/dist/tools/core-tools.d.ts +10 -14
- package/dist/tools/core-tools.js +1289 -24
- package/dist/types.d.ts +2 -0
- package/dist/types.js +2 -0
- package/dist/worker-supervisor.js +23 -0
- package/package.json +20 -6
- package/dashboard/dist/assets/B3ziCA02.js +0 -8
- package/dashboard/dist/assets/B5NEElEI.css +0 -1
- package/dashboard/dist/assets/BhapSNAs.js +0 -215
- package/dashboard/dist/assets/iFdvE7lx.js +0 -1
- package/dashboard/dist/assets/jRJsmpYM.js +0 -1
- package/dashboard/dist/assets/sAhvFnpk.js +0 -4
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared LLM client for classification, summarization, and generation tasks.
|
|
3
|
+
*
|
|
4
|
+
* Generalizes the pattern from activity-headline.ts into a reusable client
|
|
5
|
+
* with in-memory caching, timeout, and heuristic fallback.
|
|
6
|
+
*/
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
8
|
+
import { pickString } from "./value-utils.js";
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Configuration
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
const DEFAULT_MODEL = "openai/gpt-4.1-nano";
|
|
13
|
+
const DEFAULT_GENERATION_MODEL = "openai/gpt-4.1-mini";
|
|
14
|
+
const DEFAULT_TIMEOUT_MS = 4_000;
|
|
15
|
+
const DEFAULT_CACHE_TTL_MS = 12 * 60 * 60_000; // 12 hours
|
|
16
|
+
const CACHE_MAX_ENTRIES = 2_000;
|
|
17
|
+
const OPENROUTER_URL = "https://openrouter.ai/api/v1/chat/completions";
|
|
18
|
+
const cache = new Map();
|
|
19
|
+
function cacheKey(taskId, content) {
|
|
20
|
+
return `${taskId}:${createHash("sha256").update(content).digest("hex")}`;
|
|
21
|
+
}
|
|
22
|
+
function trimCache() {
|
|
23
|
+
while (cache.size > CACHE_MAX_ENTRIES) {
|
|
24
|
+
const firstKey = cache.keys().next().value;
|
|
25
|
+
if (!firstKey)
|
|
26
|
+
break;
|
|
27
|
+
cache.delete(firstKey);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function getCached(key) {
|
|
31
|
+
const entry = cache.get(key);
|
|
32
|
+
if (entry && entry.expiresAt > Date.now())
|
|
33
|
+
return entry;
|
|
34
|
+
if (entry)
|
|
35
|
+
cache.delete(key);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
function setCached(key, value, source, ttlMs) {
|
|
39
|
+
if (ttlMs <= 0)
|
|
40
|
+
return;
|
|
41
|
+
cache.set(key, { value, source, expiresAt: Date.now() + ttlMs });
|
|
42
|
+
trimCache();
|
|
43
|
+
}
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// API key resolution
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
let resolvedApiKey;
|
|
48
|
+
export function resolveApiKey() {
|
|
49
|
+
if (resolvedApiKey !== undefined)
|
|
50
|
+
return resolvedApiKey;
|
|
51
|
+
const candidates = [
|
|
52
|
+
process.env.ORGX_LLM_API_KEY ?? "",
|
|
53
|
+
process.env.ORGX_ACTIVITY_SUMMARY_API_KEY ?? "",
|
|
54
|
+
process.env.OPENROUTER_API_KEY ?? "",
|
|
55
|
+
];
|
|
56
|
+
const key = candidates.find((c) => c.trim().length > 0)?.trim() ?? "";
|
|
57
|
+
resolvedApiKey = key || null;
|
|
58
|
+
return resolvedApiKey;
|
|
59
|
+
}
|
|
60
|
+
/** Reset cached key (for testing or key rotation). */
|
|
61
|
+
export function resetApiKeyCache() {
|
|
62
|
+
resolvedApiKey = undefined;
|
|
63
|
+
}
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// OpenRouter completion
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
function extractCompletionText(payload) {
|
|
68
|
+
const choices = payload.choices;
|
|
69
|
+
if (!Array.isArray(choices) || choices.length === 0)
|
|
70
|
+
return null;
|
|
71
|
+
const first = choices[0];
|
|
72
|
+
if (!first || typeof first !== "object")
|
|
73
|
+
return null;
|
|
74
|
+
const firstRecord = first;
|
|
75
|
+
const message = firstRecord.message;
|
|
76
|
+
if (message && typeof message === "object") {
|
|
77
|
+
const content = message.content;
|
|
78
|
+
if (typeof content === "string")
|
|
79
|
+
return content;
|
|
80
|
+
if (Array.isArray(content)) {
|
|
81
|
+
const textParts = content
|
|
82
|
+
.map((part) => {
|
|
83
|
+
if (typeof part === "string")
|
|
84
|
+
return part;
|
|
85
|
+
if (!part || typeof part !== "object")
|
|
86
|
+
return "";
|
|
87
|
+
const record = part;
|
|
88
|
+
return typeof record.text === "string" ? record.text : "";
|
|
89
|
+
})
|
|
90
|
+
.filter((part) => part.length > 0);
|
|
91
|
+
if (textParts.length > 0)
|
|
92
|
+
return textParts.join(" ");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return pickString(firstRecord, ["text", "content"]);
|
|
96
|
+
}
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Public API: text completion
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
/**
|
|
101
|
+
* Call LLM for a text completion with automatic caching and heuristic fallback.
|
|
102
|
+
*
|
|
103
|
+
* @param request - The LLM request configuration
|
|
104
|
+
* @param fallback - Heuristic fallback that produces a result when LLM is unavailable
|
|
105
|
+
* @param parse - Optional transform on the raw LLM text (default: identity)
|
|
106
|
+
*/
|
|
107
|
+
export async function callLlm(request, fallback, parse) {
|
|
108
|
+
const ttl = request.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;
|
|
109
|
+
const key = cacheKey(request.taskId, `${request.systemPrompt}\n${request.userPrompt}`);
|
|
110
|
+
const cached = getCached(key);
|
|
111
|
+
if (cached) {
|
|
112
|
+
return { result: cached.value, source: cached.source, model: null };
|
|
113
|
+
}
|
|
114
|
+
const apiKey = resolveApiKey();
|
|
115
|
+
if (!apiKey) {
|
|
116
|
+
const heuristic = fallback();
|
|
117
|
+
setCached(key, heuristic, "heuristic", ttl);
|
|
118
|
+
return { result: heuristic, source: "heuristic", model: null };
|
|
119
|
+
}
|
|
120
|
+
const model = process.env.ORGX_LLM_MODEL?.trim() || request.model || DEFAULT_MODEL;
|
|
121
|
+
const controller = new AbortController();
|
|
122
|
+
const timeout = setTimeout(() => controller.abort(), request.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
123
|
+
try {
|
|
124
|
+
const response = await fetch(OPENROUTER_URL, {
|
|
125
|
+
method: "POST",
|
|
126
|
+
headers: {
|
|
127
|
+
"Content-Type": "application/json",
|
|
128
|
+
Authorization: `Bearer ${apiKey}`,
|
|
129
|
+
},
|
|
130
|
+
body: JSON.stringify({
|
|
131
|
+
model,
|
|
132
|
+
temperature: request.temperature ?? 0.1,
|
|
133
|
+
max_tokens: request.maxTokens ?? 128,
|
|
134
|
+
messages: [
|
|
135
|
+
{ role: "system", content: request.systemPrompt },
|
|
136
|
+
{ role: "user", content: request.userPrompt },
|
|
137
|
+
],
|
|
138
|
+
}),
|
|
139
|
+
signal: controller.signal,
|
|
140
|
+
});
|
|
141
|
+
if (!response.ok) {
|
|
142
|
+
throw new Error(`LLM request failed (${response.status})`);
|
|
143
|
+
}
|
|
144
|
+
const payload = (await response.json());
|
|
145
|
+
const raw = extractCompletionText(payload) ?? "";
|
|
146
|
+
const parsed = parse ? parse(raw) : raw.trim();
|
|
147
|
+
if (parsed && parsed.length > 0) {
|
|
148
|
+
setCached(key, parsed, "llm", ttl);
|
|
149
|
+
return { result: parsed, source: "llm", model };
|
|
150
|
+
}
|
|
151
|
+
const heuristic = fallback();
|
|
152
|
+
setCached(key, heuristic, "heuristic", ttl);
|
|
153
|
+
return { result: heuristic, source: "heuristic", model };
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
const heuristic = fallback();
|
|
157
|
+
setCached(key, heuristic, "heuristic", ttl);
|
|
158
|
+
return { result: heuristic, source: "heuristic", model: null };
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
clearTimeout(timeout);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
// Public API: JSON-structured completion
|
|
166
|
+
// ---------------------------------------------------------------------------
|
|
167
|
+
/**
|
|
168
|
+
* Call LLM expecting a JSON response. Parses and validates via the provided parser.
|
|
169
|
+
*
|
|
170
|
+
* @param request - The LLM request (systemPrompt should instruct JSON output)
|
|
171
|
+
* @param parse - Parse raw JSON string into typed result, return null on failure
|
|
172
|
+
* @param fallback - Heuristic fallback
|
|
173
|
+
*/
|
|
174
|
+
export async function callLlmJson(request, parse, fallback) {
|
|
175
|
+
const ttl = request.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;
|
|
176
|
+
const key = cacheKey(request.taskId, `${request.systemPrompt}\n${request.userPrompt}`);
|
|
177
|
+
const cached = getCached(key);
|
|
178
|
+
if (cached) {
|
|
179
|
+
const parsed = parse(cached.value);
|
|
180
|
+
if (parsed !== null) {
|
|
181
|
+
return { result: parsed, source: cached.source, model: null };
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const apiKey = resolveApiKey();
|
|
185
|
+
if (!apiKey) {
|
|
186
|
+
const heuristic = fallback();
|
|
187
|
+
return { result: heuristic, source: "heuristic", model: null };
|
|
188
|
+
}
|
|
189
|
+
const model = process.env.ORGX_LLM_MODEL?.trim() || request.model || DEFAULT_GENERATION_MODEL;
|
|
190
|
+
const controller = new AbortController();
|
|
191
|
+
const timeout = setTimeout(() => controller.abort(), request.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
192
|
+
try {
|
|
193
|
+
const response = await fetch(OPENROUTER_URL, {
|
|
194
|
+
method: "POST",
|
|
195
|
+
headers: {
|
|
196
|
+
"Content-Type": "application/json",
|
|
197
|
+
Authorization: `Bearer ${apiKey}`,
|
|
198
|
+
},
|
|
199
|
+
body: JSON.stringify({
|
|
200
|
+
model,
|
|
201
|
+
temperature: request.temperature ?? 0.1,
|
|
202
|
+
max_tokens: request.maxTokens ?? 512,
|
|
203
|
+
messages: [
|
|
204
|
+
{ role: "system", content: request.systemPrompt },
|
|
205
|
+
{ role: "user", content: request.userPrompt },
|
|
206
|
+
],
|
|
207
|
+
}),
|
|
208
|
+
signal: controller.signal,
|
|
209
|
+
});
|
|
210
|
+
if (!response.ok) {
|
|
211
|
+
throw new Error(`LLM request failed (${response.status})`);
|
|
212
|
+
}
|
|
213
|
+
const payload = (await response.json());
|
|
214
|
+
const raw = extractCompletionText(payload) ?? "";
|
|
215
|
+
// Try to extract JSON from markdown fences or raw text
|
|
216
|
+
const jsonStr = extractJsonFromText(raw);
|
|
217
|
+
const parsed = parse(jsonStr);
|
|
218
|
+
if (parsed !== null) {
|
|
219
|
+
setCached(key, jsonStr, "llm", ttl);
|
|
220
|
+
return { result: parsed, source: "llm", model };
|
|
221
|
+
}
|
|
222
|
+
return { result: fallback(), source: "heuristic", model };
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
return { result: fallback(), source: "heuristic", model: null };
|
|
226
|
+
}
|
|
227
|
+
finally {
|
|
228
|
+
clearTimeout(timeout);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
// Helpers
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
function extractJsonFromText(text) {
|
|
235
|
+
const trimmed = text.trim();
|
|
236
|
+
// Try markdown JSON fence
|
|
237
|
+
const fenceMatch = trimmed.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
|
|
238
|
+
if (fenceMatch?.[1])
|
|
239
|
+
return fenceMatch[1].trim();
|
|
240
|
+
// Try raw JSON (starts with { or [)
|
|
241
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("["))
|
|
242
|
+
return trimmed;
|
|
243
|
+
// Try to find JSON embedded in text
|
|
244
|
+
const jsonStart = trimmed.indexOf("{");
|
|
245
|
+
if (jsonStart >= 0) {
|
|
246
|
+
const candidate = trimmed.slice(jsonStart);
|
|
247
|
+
try {
|
|
248
|
+
JSON.parse(candidate);
|
|
249
|
+
return candidate;
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
// fall through
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return trimmed;
|
|
256
|
+
}
|
|
@@ -23,6 +23,19 @@ export interface MissionControlNode {
|
|
|
23
23
|
expectedDurationHours: number;
|
|
24
24
|
expectedBudgetUsd: number;
|
|
25
25
|
assignedAgents: MissionControlAssignedAgent[];
|
|
26
|
+
behaviorConfigId?: string | null;
|
|
27
|
+
behaviorConfigVersion?: string | null;
|
|
28
|
+
behaviorConfigHash?: string | null;
|
|
29
|
+
behaviorPolicySource?: string | null;
|
|
30
|
+
behaviorContext?: string | null;
|
|
31
|
+
behaviorRequiresApproval?: boolean | null;
|
|
32
|
+
behaviorApprovalStatus?: string | null;
|
|
33
|
+
behaviorApprovalDecisionId?: string | null;
|
|
34
|
+
behaviorAutomationLevel?: "auto" | "supervised" | "manual" | null;
|
|
35
|
+
sliceScopePreference?: "adaptive" | "task" | "milestone" | "workstream" | null;
|
|
36
|
+
maxSliceTasks?: number | null;
|
|
37
|
+
maxParallelAgents?: number | null;
|
|
38
|
+
dependencyMode?: "strict" | "relaxed" | null;
|
|
26
39
|
updatedAt: string | null;
|
|
27
40
|
}
|
|
28
41
|
export interface MissionControlEdge {
|
|
@@ -30,6 +43,33 @@ export interface MissionControlEdge {
|
|
|
30
43
|
to: string;
|
|
31
44
|
kind: "depends_on";
|
|
32
45
|
}
|
|
46
|
+
export interface MissionControlCycleDiagnostics {
|
|
47
|
+
detected: boolean;
|
|
48
|
+
cycleEdgeCount: number;
|
|
49
|
+
removedEdges: Array<{
|
|
50
|
+
from: string;
|
|
51
|
+
to: string;
|
|
52
|
+
}>;
|
|
53
|
+
affectedNodes: Array<{
|
|
54
|
+
nodeId: string;
|
|
55
|
+
nodeType: MissionControlNodeType;
|
|
56
|
+
removedDependencyIds: string[];
|
|
57
|
+
remainingDependencyIds: string[];
|
|
58
|
+
}>;
|
|
59
|
+
}
|
|
60
|
+
export type SliceScope = "task" | "milestone" | "workstream";
|
|
61
|
+
export type SliceScopePreference = "adaptive" | SliceScope;
|
|
62
|
+
export interface MissionControlExecutionPolicy {
|
|
63
|
+
domain: string;
|
|
64
|
+
requiredSkills: string[];
|
|
65
|
+
profile?: string | null;
|
|
66
|
+
sliceScopePreference?: SliceScopePreference | null;
|
|
67
|
+
maxSliceTasks?: number | null;
|
|
68
|
+
maxParallelAgents?: number | null;
|
|
69
|
+
dependencyMode?: "strict" | "relaxed" | null;
|
|
70
|
+
}
|
|
71
|
+
export declare const SLICE_SCOPE_MAX_TASKS: Record<SliceScope, number>;
|
|
72
|
+
export declare const SLICE_SCOPE_TIMEOUT_MULTIPLIER: Record<SliceScope, number>;
|
|
33
73
|
export declare const ORGX_SKILL_BY_DOMAIN: Record<string, string>;
|
|
34
74
|
interface BudgetEnvBounds {
|
|
35
75
|
min?: number;
|
|
@@ -67,6 +107,7 @@ export declare function buildMissionControlGraph(client: OrgXClient, initiativeI
|
|
|
67
107
|
edges: MissionControlEdge[];
|
|
68
108
|
recentTodos: string[];
|
|
69
109
|
degraded: string[];
|
|
110
|
+
cycleDiagnostics?: MissionControlCycleDiagnostics;
|
|
70
111
|
}>;
|
|
71
112
|
export declare function normalizeEntityMutationPayload(payload: Record<string, unknown>): Record<string, unknown>;
|
|
72
113
|
export declare function resolveAutoAssignments(input: {
|
|
@@ -85,10 +126,68 @@ export declare function resolveAutoAssignments(input: {
|
|
|
85
126
|
}>;
|
|
86
127
|
export declare function normalizeExecutionDomain(value: string | null | undefined): string | null;
|
|
87
128
|
export declare function inferExecutionDomainFromText(...values: Array<string | null | undefined>): string;
|
|
88
|
-
export declare function
|
|
89
|
-
|
|
90
|
-
|
|
129
|
+
export declare function selectSliceTasksByScope(input: {
|
|
130
|
+
scope: SliceScope;
|
|
131
|
+
workstreamId: string;
|
|
132
|
+
milestoneId?: string | null;
|
|
133
|
+
recentTodos: string[];
|
|
134
|
+
nodeById: Map<string, MissionControlNode>;
|
|
135
|
+
includeVerification: boolean;
|
|
136
|
+
}): {
|
|
137
|
+
tasks: MissionControlNode[];
|
|
138
|
+
milestoneIds: string[];
|
|
139
|
+
};
|
|
140
|
+
export declare function evaluateScopeCompletion(input: {
|
|
141
|
+
scope: SliceScope;
|
|
142
|
+
milestoneIds: string[];
|
|
143
|
+
workstreamId: string;
|
|
144
|
+
nodeById: Map<string, MissionControlNode>;
|
|
145
|
+
}): {
|
|
146
|
+
scopeComplete: boolean;
|
|
147
|
+
remainingTasks: number;
|
|
148
|
+
};
|
|
149
|
+
export declare function deriveExecutionPolicy(taskNode: MissionControlNode, workstreamNode: MissionControlNode | null): MissionControlExecutionPolicy;
|
|
150
|
+
export declare function deriveBehaviorConfigContext(taskNode: MissionControlNode, workstreamNode: MissionControlNode | null): {
|
|
151
|
+
configId: string | null;
|
|
152
|
+
version: string | null;
|
|
153
|
+
hash: string | null;
|
|
154
|
+
policySource: string | null;
|
|
155
|
+
context: string | null;
|
|
156
|
+
requiresApproval: boolean;
|
|
157
|
+
approvalStatus: string | null;
|
|
158
|
+
approvalDecisionId: string | null;
|
|
91
159
|
};
|
|
160
|
+
export declare function deriveBehaviorAutomationLevel(taskNode: MissionControlNode, workstreamNode: MissionControlNode | null): "auto" | "supervised" | "manual";
|
|
161
|
+
export declare function detectBehaviorConfigDrift(input: {
|
|
162
|
+
taskNode: MissionControlNode;
|
|
163
|
+
workstreamNode: MissionControlNode | null;
|
|
164
|
+
behaviorConfig: {
|
|
165
|
+
configId: string | null;
|
|
166
|
+
version: string | null;
|
|
167
|
+
hash: string | null;
|
|
168
|
+
policySource: string | null;
|
|
169
|
+
context: string | null;
|
|
170
|
+
};
|
|
171
|
+
behaviorAutomationLevel: "auto" | "supervised" | "manual";
|
|
172
|
+
}): {
|
|
173
|
+
fields: Array<"config_id" | "version" | "hash" | "policy_source" | "context" | "automation_level">;
|
|
174
|
+
declared: {
|
|
175
|
+
configId: string | null;
|
|
176
|
+
version: string | null;
|
|
177
|
+
hash: string | null;
|
|
178
|
+
policySource: string | null;
|
|
179
|
+
context: string | null;
|
|
180
|
+
automationLevel: "auto" | "supervised" | "manual" | null;
|
|
181
|
+
};
|
|
182
|
+
runtime: {
|
|
183
|
+
configId: string | null;
|
|
184
|
+
version: string | null;
|
|
185
|
+
hash: string | null;
|
|
186
|
+
policySource: string | null;
|
|
187
|
+
context: string | null;
|
|
188
|
+
automationLevel: "auto" | "supervised" | "manual";
|
|
189
|
+
};
|
|
190
|
+
} | null;
|
|
92
191
|
export declare function spawnGuardIsRateLimited(result: unknown): boolean;
|
|
93
192
|
export declare function summarizeSpawnGuardBlockReason(result: unknown): string;
|
|
94
193
|
export {};
|