@useorgx/openclaw-plugin 0.4.8 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. package/README.md +35 -0
  2. package/dashboard/dist/assets/BJgZIVUQ.js +53 -0
  3. package/dashboard/dist/assets/BJgZIVUQ.js.br +0 -0
  4. package/dashboard/dist/assets/BJgZIVUQ.js.gz +0 -0
  5. package/dashboard/dist/assets/BXWDRGm-.js +1 -0
  6. package/dashboard/dist/assets/BXWDRGm-.js.br +0 -0
  7. package/dashboard/dist/assets/BXWDRGm-.js.gz +0 -0
  8. package/dashboard/dist/assets/BgOYB78t.js +4 -0
  9. package/dashboard/dist/assets/BgOYB78t.js.br +0 -0
  10. package/dashboard/dist/assets/BgOYB78t.js.gz +0 -0
  11. package/dashboard/dist/assets/C-KIc3Wc.js.br +0 -0
  12. package/dashboard/dist/assets/C-KIc3Wc.js.gz +0 -0
  13. package/dashboard/dist/assets/CE38zU4U.js +1 -0
  14. package/dashboard/dist/assets/CE38zU4U.js.br +0 -0
  15. package/dashboard/dist/assets/CE38zU4U.js.gz +0 -0
  16. package/dashboard/dist/assets/CFGKRAzG.js +1 -0
  17. package/dashboard/dist/assets/CFGKRAzG.js.br +0 -0
  18. package/dashboard/dist/assets/CFGKRAzG.js.gz +0 -0
  19. package/dashboard/dist/assets/CGGR2GZh.js +1 -0
  20. package/dashboard/dist/assets/CGGR2GZh.js.br +0 -0
  21. package/dashboard/dist/assets/CGGR2GZh.js.gz +0 -0
  22. package/dashboard/dist/assets/CL_wXqR7.js +1 -0
  23. package/dashboard/dist/assets/CL_wXqR7.js.br +0 -0
  24. package/dashboard/dist/assets/CL_wXqR7.js.gz +0 -0
  25. package/dashboard/dist/assets/CPFiTmlw.js +8 -0
  26. package/dashboard/dist/assets/CPFiTmlw.js.br +0 -0
  27. package/dashboard/dist/assets/CPFiTmlw.js.gz +0 -0
  28. package/dashboard/dist/assets/CZZTvkQZ.js +1 -0
  29. package/dashboard/dist/assets/CZZTvkQZ.js.br +0 -0
  30. package/dashboard/dist/assets/CZZTvkQZ.js.gz +0 -0
  31. package/dashboard/dist/assets/{CpJsfbXo.js → CxQ08qFN.js} +2 -2
  32. package/dashboard/dist/assets/CxQ08qFN.js.br +0 -0
  33. package/dashboard/dist/assets/CxQ08qFN.js.gz +0 -0
  34. package/dashboard/dist/assets/D-bf6hEI.js +213 -0
  35. package/dashboard/dist/assets/D-bf6hEI.js.br +0 -0
  36. package/dashboard/dist/assets/D-bf6hEI.js.gz +0 -0
  37. package/dashboard/dist/assets/DG6y9wJI.js +2 -0
  38. package/dashboard/dist/assets/DG6y9wJI.js.br +0 -0
  39. package/dashboard/dist/assets/DG6y9wJI.js.gz +0 -0
  40. package/dashboard/dist/assets/DNxKz-GV.js +1 -0
  41. package/dashboard/dist/assets/DNxKz-GV.js.br +0 -0
  42. package/dashboard/dist/assets/DNxKz-GV.js.gz +0 -0
  43. package/dashboard/dist/assets/DW_rKUic.js +11 -0
  44. package/dashboard/dist/assets/DW_rKUic.js.br +0 -0
  45. package/dashboard/dist/assets/DW_rKUic.js.gz +0 -0
  46. package/dashboard/dist/assets/DbNoijHm.js +1 -0
  47. package/dashboard/dist/assets/DbNoijHm.js.br +0 -0
  48. package/dashboard/dist/assets/DbNoijHm.js.gz +0 -0
  49. package/dashboard/dist/assets/DjcdE6jC.js +2 -0
  50. package/dashboard/dist/assets/DjcdE6jC.js.br +0 -0
  51. package/dashboard/dist/assets/DjcdE6jC.js.gz +0 -0
  52. package/dashboard/dist/assets/FZYuCDnt.js +1 -0
  53. package/dashboard/dist/assets/FZYuCDnt.js.br +0 -0
  54. package/dashboard/dist/assets/FZYuCDnt.js.gz +0 -0
  55. package/dashboard/dist/assets/PAUiij_z.js +1 -0
  56. package/dashboard/dist/assets/PAUiij_z.js.br +0 -0
  57. package/dashboard/dist/assets/PAUiij_z.js.gz +0 -0
  58. package/dashboard/dist/assets/cNrhgGc1.js +8 -0
  59. package/dashboard/dist/assets/cNrhgGc1.js.br +0 -0
  60. package/dashboard/dist/assets/cNrhgGc1.js.gz +0 -0
  61. package/dashboard/dist/assets/h5biQs2I.css +1 -0
  62. package/dashboard/dist/assets/h5biQs2I.css.br +0 -0
  63. package/dashboard/dist/assets/h5biQs2I.css.gz +0 -0
  64. package/dashboard/dist/assets/ic2FaMnh.js +1 -0
  65. package/dashboard/dist/assets/ic2FaMnh.js.br +0 -0
  66. package/dashboard/dist/assets/ic2FaMnh.js.gz +0 -0
  67. package/dashboard/dist/assets/nByHNHoW.js +1 -0
  68. package/dashboard/dist/assets/nByHNHoW.js.br +0 -0
  69. package/dashboard/dist/assets/nByHNHoW.js.gz +0 -0
  70. package/dashboard/dist/assets/qm8xLgv-.css +1 -0
  71. package/dashboard/dist/assets/qm8xLgv-.css.br +0 -0
  72. package/dashboard/dist/assets/qm8xLgv-.css.gz +0 -0
  73. package/dashboard/dist/assets/tS9mbYZi.js +1 -0
  74. package/dashboard/dist/assets/tS9mbYZi.js.br +0 -0
  75. package/dashboard/dist/assets/tS9mbYZi.js.gz +0 -0
  76. package/dashboard/dist/brand/anthropic-mark.svg.br +0 -0
  77. package/dashboard/dist/brand/anthropic-mark.svg.gz +0 -0
  78. package/dashboard/dist/brand/openai-mark.svg.br +0 -0
  79. package/dashboard/dist/brand/openai-mark.svg.gz +0 -0
  80. package/dashboard/dist/brand/openclaw-mark.svg.br +0 -0
  81. package/dashboard/dist/brand/openclaw-mark.svg.gz +0 -0
  82. package/dashboard/dist/brand/xandy-orchestrator.png +0 -0
  83. package/dashboard/dist/index.html +7 -5
  84. package/dashboard/dist/index.html.br +0 -0
  85. package/dashboard/dist/index.html.gz +0 -0
  86. package/dist/activity-actor-fields.js +26 -4
  87. package/dist/activity-store.js +38 -26
  88. package/dist/agent-context-store.js +84 -42
  89. package/dist/agent-run-store.js +49 -28
  90. package/dist/agent-suite.d.ts +9 -0
  91. package/dist/agent-suite.js +150 -17
  92. package/dist/artifacts/artifact-domain-schemas.d.ts +66 -0
  93. package/dist/artifacts/artifact-domain-schemas.js +357 -0
  94. package/dist/artifacts/register-artifact.d.ts +4 -3
  95. package/dist/artifacts/register-artifact.js +170 -57
  96. package/dist/auth/flows.d.ts +47 -0
  97. package/dist/auth/flows.js +169 -0
  98. package/dist/auth-store.js +6 -26
  99. package/dist/byok-store.js +5 -19
  100. package/dist/chat-store.d.ts +157 -0
  101. package/dist/chat-store.js +586 -0
  102. package/dist/cli/orgx.d.ts +66 -0
  103. package/dist/cli/orgx.js +102 -0
  104. package/dist/config/refresh.d.ts +32 -0
  105. package/dist/config/refresh.js +55 -0
  106. package/dist/config/resolution.d.ts +37 -0
  107. package/dist/config/resolution.js +178 -0
  108. package/dist/contracts/client.d.ts +43 -3
  109. package/dist/contracts/client.js +159 -30
  110. package/dist/contracts/retro-schema.d.ts +81 -0
  111. package/dist/contracts/retro-schema.js +80 -0
  112. package/dist/contracts/shared-types.d.ts +306 -0
  113. package/dist/contracts/shared-types.js +179 -0
  114. package/dist/contracts/skill-pack-schema.d.ts +192 -0
  115. package/dist/contracts/skill-pack-schema.js +180 -0
  116. package/dist/contracts/types.d.ts +224 -132
  117. package/dist/contracts/types.js +5 -0
  118. package/dist/entities/auto-assignment.d.ts +36 -0
  119. package/dist/entities/auto-assignment.js +141 -0
  120. package/dist/entity-comment-store.js +5 -25
  121. package/dist/event-sanitization.d.ts +11 -0
  122. package/dist/event-sanitization.js +113 -0
  123. package/dist/fs-utils.js +13 -1
  124. package/dist/gateway-watchdog.d.ts +5 -0
  125. package/dist/gateway-watchdog.js +50 -0
  126. package/dist/hash-utils.d.ts +2 -0
  127. package/dist/hash-utils.js +12 -0
  128. package/dist/hooks/post-reporting-event.mjs +1 -5
  129. package/dist/http/helpers/activity-headline.d.ts +10 -0
  130. package/dist/http/helpers/activity-headline.js +73 -0
  131. package/dist/http/helpers/artifact-fallback.d.ts +13 -0
  132. package/dist/http/helpers/artifact-fallback.js +148 -0
  133. package/dist/http/helpers/auto-continue-engine.d.ts +486 -0
  134. package/dist/http/helpers/auto-continue-engine.js +3563 -0
  135. package/dist/http/helpers/autopilot-operations.d.ts +176 -0
  136. package/dist/http/helpers/autopilot-operations.js +554 -0
  137. package/dist/http/helpers/autopilot-runtime.d.ts +43 -0
  138. package/dist/http/helpers/autopilot-runtime.js +607 -0
  139. package/dist/http/helpers/autopilot-slice-utils.d.ts +56 -0
  140. package/dist/http/helpers/autopilot-slice-utils.js +899 -0
  141. package/dist/http/helpers/decision-mapper.d.ts +52 -0
  142. package/dist/http/helpers/decision-mapper.js +260 -0
  143. package/dist/http/helpers/dispatch-lifecycle.d.ts +119 -0
  144. package/dist/http/helpers/dispatch-lifecycle.js +809 -0
  145. package/dist/http/helpers/hash-utils.d.ts +1 -0
  146. package/dist/http/helpers/hash-utils.js +1 -0
  147. package/dist/http/helpers/kickoff-context.d.ts +12 -0
  148. package/dist/http/helpers/kickoff-context.js +228 -0
  149. package/dist/http/helpers/llm-client.d.ts +47 -0
  150. package/dist/http/helpers/llm-client.js +256 -0
  151. package/dist/http/helpers/mission-control.d.ts +193 -0
  152. package/dist/http/helpers/mission-control.js +1383 -0
  153. package/dist/http/helpers/openclaw-cli.d.ts +37 -0
  154. package/dist/http/helpers/openclaw-cli.js +283 -0
  155. package/dist/http/helpers/runtime-sse.d.ts +20 -0
  156. package/dist/http/helpers/runtime-sse.js +110 -0
  157. package/dist/http/helpers/sentinel-catalog.d.ts +23 -0
  158. package/dist/http/helpers/sentinel-catalog.js +193 -0
  159. package/dist/http/helpers/session-classification.d.ts +9 -0
  160. package/dist/http/helpers/session-classification.js +564 -0
  161. package/dist/http/helpers/slice-experience-v2.d.ts +137 -0
  162. package/dist/http/helpers/slice-experience-v2.js +677 -0
  163. package/dist/http/helpers/slice-run-projections.d.ts +72 -0
  164. package/dist/http/helpers/slice-run-projections.js +860 -0
  165. package/dist/http/helpers/triage-mapper.d.ts +43 -0
  166. package/dist/http/helpers/triage-mapper.js +549 -0
  167. package/dist/http/helpers/value-utils.d.ts +6 -0
  168. package/dist/http/helpers/value-utils.js +72 -0
  169. package/dist/http/helpers/workspace-scope.d.ts +15 -0
  170. package/dist/http/helpers/workspace-scope.js +170 -0
  171. package/dist/http/index.d.ts +88 -0
  172. package/dist/http/index.js +3610 -0
  173. package/dist/http/router.d.ts +23 -0
  174. package/dist/http/router.js +23 -0
  175. package/dist/http/routes/agent-control.d.ts +79 -0
  176. package/dist/http/routes/agent-control.js +684 -0
  177. package/dist/http/routes/agent-suite.d.ts +38 -0
  178. package/dist/http/routes/agent-suite.js +397 -0
  179. package/dist/http/routes/agents-catalog.d.ts +40 -0
  180. package/dist/http/routes/agents-catalog.js +128 -0
  181. package/dist/http/routes/billing.d.ts +23 -0
  182. package/dist/http/routes/billing.js +55 -0
  183. package/dist/http/routes/chat.d.ts +19 -0
  184. package/dist/http/routes/chat.js +522 -0
  185. package/dist/http/routes/debug.d.ts +14 -0
  186. package/dist/http/routes/debug.js +21 -0
  187. package/dist/http/routes/decision-actions.d.ts +20 -0
  188. package/dist/http/routes/decision-actions.js +103 -0
  189. package/dist/http/routes/delegation.d.ts +19 -0
  190. package/dist/http/routes/delegation.js +32 -0
  191. package/dist/http/routes/dispatch-gateway-envelope.d.ts +25 -0
  192. package/dist/http/routes/dispatch-gateway-envelope.js +26 -0
  193. package/dist/http/routes/entities.d.ts +63 -0
  194. package/dist/http/routes/entities.js +440 -0
  195. package/dist/http/routes/entity-dynamic.d.ts +25 -0
  196. package/dist/http/routes/entity-dynamic.js +191 -0
  197. package/dist/http/routes/health.d.ts +22 -0
  198. package/dist/http/routes/health.js +49 -0
  199. package/dist/http/routes/live-legacy.d.ts +115 -0
  200. package/dist/http/routes/live-legacy.js +112 -0
  201. package/dist/http/routes/live-misc.d.ts +81 -0
  202. package/dist/http/routes/live-misc.js +426 -0
  203. package/dist/http/routes/live-snapshot.d.ts +136 -0
  204. package/dist/http/routes/live-snapshot.js +916 -0
  205. package/dist/http/routes/live-terminal.d.ts +11 -0
  206. package/dist/http/routes/live-terminal.js +261 -0
  207. package/dist/http/routes/live-triage.d.ts +61 -0
  208. package/dist/http/routes/live-triage.js +248 -0
  209. package/dist/http/routes/mission-control-actions.d.ts +131 -0
  210. package/dist/http/routes/mission-control-actions.js +1791 -0
  211. package/dist/http/routes/mission-control-read.d.ts +73 -0
  212. package/dist/http/routes/mission-control-read.js +1640 -0
  213. package/dist/http/routes/onboarding.d.ts +34 -0
  214. package/dist/http/routes/onboarding.js +101 -0
  215. package/dist/http/routes/realtime-orchestrator.d.ts +10 -0
  216. package/dist/http/routes/realtime-orchestrator.js +74 -0
  217. package/dist/http/routes/run-control.d.ts +27 -0
  218. package/dist/http/routes/run-control.js +96 -0
  219. package/dist/http/routes/runtime-hooks.d.ts +69 -0
  220. package/dist/http/routes/runtime-hooks.js +437 -0
  221. package/dist/http/routes/sentinels-catalog.d.ts +7 -0
  222. package/dist/http/routes/sentinels-catalog.js +24 -0
  223. package/dist/http/routes/settings-byok.d.ts +23 -0
  224. package/dist/http/routes/settings-byok.js +163 -0
  225. package/dist/http/routes/summary.d.ts +18 -0
  226. package/dist/http/routes/summary.js +49 -0
  227. package/dist/http/routes/usage.d.ts +24 -0
  228. package/dist/http/routes/usage.js +362 -0
  229. package/dist/http/routes/work-artifacts.d.ts +9 -0
  230. package/dist/http/routes/work-artifacts.js +55 -0
  231. package/dist/http/shared-state.d.ts +16 -0
  232. package/dist/http/shared-state.js +1 -0
  233. package/dist/http-handler.d.ts +1 -88
  234. package/dist/http-handler.js +1 -10605
  235. package/dist/index.js +287 -2284
  236. package/dist/json-utils.d.ts +1 -0
  237. package/dist/json-utils.js +8 -0
  238. package/dist/local-openclaw.js +29 -6
  239. package/dist/mcp-client-setup.js +3 -3
  240. package/dist/mcp-http-handler.js +33 -59
  241. package/dist/next-up-queue-store.d.ts +16 -1
  242. package/dist/next-up-queue-store.js +93 -25
  243. package/dist/outbox.d.ts +5 -0
  244. package/dist/outbox.js +113 -9
  245. package/dist/paths.js +24 -5
  246. package/dist/reporting/rollups.d.ts +53 -0
  247. package/dist/reporting/rollups.js +148 -0
  248. package/dist/retro/domain-templates.d.ts +45 -0
  249. package/dist/retro/domain-templates.js +297 -0
  250. package/dist/retro/quality-rubric.d.ts +33 -0
  251. package/dist/retro/quality-rubric.js +213 -0
  252. package/dist/runtime-cleanup.d.ts +18 -0
  253. package/dist/runtime-cleanup.js +87 -0
  254. package/dist/runtime-instance-store.js +5 -31
  255. package/dist/services/background.d.ts +34 -0
  256. package/dist/services/background.js +45 -0
  257. package/dist/services/experiment-randomization.d.ts +21 -0
  258. package/dist/services/experiment-randomization.js +63 -0
  259. package/dist/services/instrumentation.d.ts +29 -0
  260. package/dist/services/instrumentation.js +136 -0
  261. package/dist/skill-pack-state.d.ts +36 -5
  262. package/dist/skill-pack-state.js +273 -29
  263. package/dist/snapshot-store.js +5 -25
  264. package/dist/stores/json-store.d.ts +11 -0
  265. package/dist/stores/json-store.js +42 -0
  266. package/dist/sync/local-agent-telemetry.d.ts +13 -0
  267. package/dist/sync/local-agent-telemetry.js +128 -0
  268. package/dist/sync/outbox-replay.d.ts +55 -0
  269. package/dist/sync/outbox-replay.js +621 -0
  270. package/dist/team-context-store.d.ts +23 -0
  271. package/dist/team-context-store.js +116 -0
  272. package/dist/telemetry/posthog.js +4 -2
  273. package/dist/tools/core-tools.d.ts +72 -0
  274. package/dist/tools/core-tools.js +2270 -0
  275. package/dist/types.d.ts +2 -0
  276. package/dist/types.js +2 -0
  277. package/dist/worker-supervisor.js +23 -0
  278. package/package.json +14 -4
  279. package/dashboard/dist/assets/B3ziCA02.js +0 -8
  280. package/dashboard/dist/assets/BNeJ0kpF.js +0 -1
  281. package/dashboard/dist/assets/BzkiMPmM.js +0 -215
  282. package/dashboard/dist/assets/CUV9IHHi.js +0 -1
  283. package/dashboard/dist/assets/Ie7d9Iq2.css +0 -1
  284. package/dashboard/dist/assets/sAhvFnpk.js +0 -4
@@ -0,0 +1 @@
1
+ export { idempotencyKey, stableHash } from "../../hash-utils.js";
@@ -0,0 +1 @@
1
+ export { idempotencyKey, stableHash } from "../../hash-utils.js";
@@ -0,0 +1,12 @@
1
+ import type { OrgXClient } from "../../api.js";
2
+ import type { KickoffContext, KickoffContextRequest } from "../../types.js";
3
+ export declare function fetchKickoffContextSafe(client: OrgXClient, payload: KickoffContextRequest): Promise<KickoffContext | null>;
4
+ export declare function renderKickoffMessage(input: {
5
+ baseMessage: string;
6
+ kickoff: KickoffContext | null;
7
+ domain: string | null;
8
+ requiredSkills: string[];
9
+ }): {
10
+ message: string;
11
+ contextHash: string | null;
12
+ };
@@ -0,0 +1,228 @@
1
+ function normalizeKickoffContextResponse(value) {
2
+ if (!value || typeof value !== "object")
3
+ return null;
4
+ const record = value;
5
+ if (typeof record.context_hash === "string" && record.context_hash.trim().length > 0) {
6
+ return record;
7
+ }
8
+ if (record.ok === true && record.data && typeof record.data === "object") {
9
+ const data = record.data;
10
+ if (typeof data.context_hash === "string" && data.context_hash.trim().length > 0) {
11
+ return data;
12
+ }
13
+ }
14
+ return null;
15
+ }
16
+ export async function fetchKickoffContextSafe(client, payload) {
17
+ try {
18
+ const anyClient = client;
19
+ if (typeof anyClient.getKickoffContext === "function") {
20
+ const resp = await anyClient.getKickoffContext(payload);
21
+ return normalizeKickoffContextResponse(resp);
22
+ }
23
+ if (typeof anyClient.rawRequest === "function") {
24
+ const resp = await anyClient.rawRequest("POST", "/api/client/kickoff-context", payload ?? {});
25
+ return normalizeKickoffContextResponse(resp);
26
+ }
27
+ }
28
+ catch {
29
+ // best effort: fall back to local kickoff message
30
+ }
31
+ return null;
32
+ }
33
+ function normalizeKickoffLines(input) {
34
+ if (!Array.isArray(input))
35
+ return [];
36
+ return input
37
+ .map((line) => (typeof line === "string" ? line.trim() : ""))
38
+ .filter((line) => line.length > 0);
39
+ }
40
+ export function renderKickoffMessage(input) {
41
+ const base = input.baseMessage.trim();
42
+ const kickoff = input.kickoff;
43
+ if (!kickoff)
44
+ return { message: base, contextHash: null };
45
+ const title = (kickoff.task?.title ??
46
+ kickoff.workstream?.title ??
47
+ kickoff.initiative?.title ??
48
+ "").trim();
49
+ const overview = (kickoff.overview ?? "").trim();
50
+ const acceptance = normalizeKickoffLines(kickoff.acceptance_criteria ?? null);
51
+ const constraints = normalizeKickoffLines(kickoff.constraints ?? null);
52
+ const risks = normalizeKickoffLines(kickoff.risks ?? null);
53
+ const reporting = normalizeKickoffLines(kickoff.reporting_expectations ?? null);
54
+ const decisions = Array.isArray(kickoff.decisions) ? kickoff.decisions : [];
55
+ const artifacts = Array.isArray(kickoff.artifacts) ? kickoff.artifacts : [];
56
+ const allow = normalizeKickoffLines(kickoff.tool_scope?.allow ?? null);
57
+ const deny = normalizeKickoffLines(kickoff.tool_scope?.deny ?? null);
58
+ const toolNotes = (kickoff.tool_scope?.notes ?? "").trim();
59
+ const personaVoice = (kickoff.persona?.voice ?? "").trim();
60
+ const collaborationStyle = (kickoff.persona?.collaboration_style ?? "").trim();
61
+ const personaDefaults = normalizeKickoffLines(kickoff.persona?.defaults ?? null);
62
+ const runtimeSettings = kickoff.runtime_settings && typeof kickoff.runtime_settings === "object"
63
+ ? kickoff.runtime_settings
64
+ : null;
65
+ const customRunInstructions = runtimeSettings && typeof runtimeSettings.custom_run_instructions === "string"
66
+ ? runtimeSettings.custom_run_instructions.trim()
67
+ : "";
68
+ const runtimeFlagLines = [
69
+ runtimeSettings && typeof runtimeSettings.decision_v2_enabled === "boolean"
70
+ ? `- Decision V2: ${runtimeSettings.decision_v2_enabled ? "enabled" : "disabled"}`
71
+ : null,
72
+ runtimeSettings && typeof runtimeSettings.decision_dedupe_enabled === "boolean"
73
+ ? `- Decision dedupe: ${runtimeSettings.decision_dedupe_enabled ? "enabled" : "disabled"}`
74
+ : null,
75
+ runtimeSettings &&
76
+ typeof runtimeSettings.decision_evidence_required_for_blocking === "boolean"
77
+ ? `- Blocking evidence required: ${runtimeSettings.decision_evidence_required_for_blocking ? "enabled" : "disabled"}`
78
+ : null,
79
+ runtimeSettings &&
80
+ typeof runtimeSettings.decision_auto_resolve_guarded_enabled === "boolean"
81
+ ? `- Guarded auto-resolve: ${runtimeSettings.decision_auto_resolve_guarded_enabled ? "enabled" : "disabled"}`
82
+ : null,
83
+ ].filter((line) => Boolean(line));
84
+ const contextHash = kickoff.context_hash?.trim() || null;
85
+ const schemaVersion = (kickoff.schema_version ?? "").trim();
86
+ const lines = [];
87
+ lines.push("# Kickoff");
88
+ lines.push("");
89
+ if (title) {
90
+ lines.push(`## Target`);
91
+ lines.push(`- ${title}`);
92
+ lines.push("");
93
+ }
94
+ if (overview) {
95
+ lines.push("## Overview");
96
+ lines.push(overview);
97
+ lines.push("");
98
+ }
99
+ else if (base) {
100
+ lines.push("## Objective");
101
+ lines.push(base);
102
+ lines.push("");
103
+ }
104
+ if (acceptance.length > 0) {
105
+ lines.push("## Acceptance Criteria");
106
+ for (const item of acceptance)
107
+ lines.push(`- ${item}`);
108
+ lines.push("");
109
+ }
110
+ if (constraints.length > 0) {
111
+ lines.push("## Constraints");
112
+ for (const item of constraints)
113
+ lines.push(`- ${item}`);
114
+ lines.push("");
115
+ }
116
+ if (risks.length > 0) {
117
+ lines.push("## Risks");
118
+ for (const item of risks)
119
+ lines.push(`- ${item}`);
120
+ lines.push("");
121
+ }
122
+ if (decisions.length > 0 || artifacts.length > 0) {
123
+ lines.push("## References");
124
+ for (const item of decisions) {
125
+ const decisionTitle = typeof item?.title === "string"
126
+ ? String(item.title).trim()
127
+ : "";
128
+ const id = typeof item?.id === "string" ? String(item.id).trim() : "";
129
+ const label = decisionTitle || id || "decision";
130
+ lines.push(`- Decision: ${label}`);
131
+ }
132
+ for (const item of artifacts) {
133
+ const artifactTitle = typeof item?.title === "string"
134
+ ? String(item.title).trim()
135
+ : "";
136
+ const id = typeof item?.id === "string" ? String(item.id).trim() : "";
137
+ const label = artifactTitle || id || "artifact";
138
+ lines.push(`- Artifact: ${label}`);
139
+ }
140
+ lines.push("");
141
+ }
142
+ lines.push("## Operating Mode");
143
+ if (input.domain)
144
+ lines.push(`- Domain: ${input.domain}`);
145
+ if (input.requiredSkills.length > 0) {
146
+ lines.push(`- Skills: ${input.requiredSkills.join(", ")}`);
147
+ }
148
+ lines.push("- Communicate early when blocked. Provide options, tradeoffs, and a recommendation.");
149
+ lines.push("- Verify before claiming done. Prefer proof (commands/tests) over confidence.");
150
+ lines.push("");
151
+ if (runtimeFlagLines.length > 0 || customRunInstructions) {
152
+ lines.push("## Runtime Settings");
153
+ for (const line of runtimeFlagLines)
154
+ lines.push(line);
155
+ if (customRunInstructions) {
156
+ lines.push("- Custom run instructions:");
157
+ lines.push(` ${customRunInstructions}`);
158
+ }
159
+ lines.push("");
160
+ }
161
+ if (personaVoice || collaborationStyle || personaDefaults.length > 0) {
162
+ lines.push("## Behavior");
163
+ if (personaVoice)
164
+ lines.push(`- Voice: ${personaVoice}`);
165
+ if (collaborationStyle)
166
+ lines.push(`- Collaboration style: ${collaborationStyle}`);
167
+ for (const item of personaDefaults)
168
+ lines.push(`- Default: ${item}`);
169
+ lines.push("");
170
+ }
171
+ if (allow.length > 0 || deny.length > 0 || toolNotes) {
172
+ lines.push("## Tool Scope");
173
+ if (allow.length > 0)
174
+ lines.push(`- Allow: ${allow.join(", ")}`);
175
+ if (deny.length > 0)
176
+ lines.push(`- Deny: ${deny.join(", ")}`);
177
+ if (toolNotes)
178
+ lines.push(`- Notes: ${toolNotes}`);
179
+ lines.push("");
180
+ }
181
+ if (reporting.length > 0) {
182
+ lines.push("## Reporting");
183
+ for (const item of reporting)
184
+ lines.push(`- ${item}`);
185
+ lines.push("");
186
+ }
187
+ const teamContext = kickoff.team_context;
188
+ if (teamContext) {
189
+ const completions = Array.isArray(teamContext.recent_completions)
190
+ ? teamContext.recent_completions.slice(0, 5)
191
+ : [];
192
+ const teamDecisions = Array.isArray(teamContext.recent_decisions)
193
+ ? teamContext.recent_decisions.slice(0, 3)
194
+ : [];
195
+ if (completions.length > 0 || teamDecisions.length > 0) {
196
+ lines.push("## Team Activity");
197
+ lines.push("Recent work by other agents (for awareness, not direct action):");
198
+ for (const c of completions) {
199
+ const outputs = Array.isArray(c.key_outputs) && c.key_outputs.length > 0
200
+ ? ` (${c.key_outputs.join(", ")})`
201
+ : "";
202
+ lines.push(`- [${c.domain}] ${c.task_title}: ${c.summary}${outputs}`);
203
+ }
204
+ if (teamDecisions.length > 0) {
205
+ lines.push("");
206
+ lines.push("Recent decisions:");
207
+ for (const d of teamDecisions) {
208
+ lines.push(`- ${d.title}: ${d.resolution}`);
209
+ }
210
+ }
211
+ lines.push("");
212
+ lines.push("Reference naturally when relevant. Do not summarize back.");
213
+ lines.push("");
214
+ }
215
+ }
216
+ if (contextHash || schemaVersion) {
217
+ lines.push("## Provenance");
218
+ if (schemaVersion)
219
+ lines.push(`- kickoff_schema: ${schemaVersion}`);
220
+ if (contextHash)
221
+ lines.push(`- kickoff_context_hash: ${contextHash}`);
222
+ lines.push("");
223
+ }
224
+ return {
225
+ message: lines.join("\n").trimEnd(),
226
+ contextHash,
227
+ };
228
+ }
@@ -0,0 +1,47 @@
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
+ export type LlmSource = "llm" | "heuristic";
8
+ export interface LlmRequest {
9
+ /** Namespace for cache keys (e.g. "retro", "turn_summary", "classify_status") */
10
+ taskId: string;
11
+ systemPrompt: string;
12
+ userPrompt: string;
13
+ /** Override default model. Use DEFAULT_GENERATION_MODEL for longer outputs. */
14
+ model?: string;
15
+ /** Default 0.1 */
16
+ temperature?: number;
17
+ /** Default 128 */
18
+ maxTokens?: number;
19
+ /** Default 4000ms */
20
+ timeoutMs?: number;
21
+ /** Default 12h. Set 0 to disable caching. */
22
+ cacheTtlMs?: number;
23
+ }
24
+ export interface LlmResponse<T> {
25
+ result: T;
26
+ source: LlmSource;
27
+ model: string | null;
28
+ }
29
+ export declare function resolveApiKey(): string | null;
30
+ /** Reset cached key (for testing or key rotation). */
31
+ export declare function resetApiKeyCache(): void;
32
+ /**
33
+ * Call LLM for a text completion with automatic caching and heuristic fallback.
34
+ *
35
+ * @param request - The LLM request configuration
36
+ * @param fallback - Heuristic fallback that produces a result when LLM is unavailable
37
+ * @param parse - Optional transform on the raw LLM text (default: identity)
38
+ */
39
+ export declare function callLlm(request: LlmRequest, fallback: () => string, parse?: (raw: string) => string | null): Promise<LlmResponse<string>>;
40
+ /**
41
+ * Call LLM expecting a JSON response. Parses and validates via the provided parser.
42
+ *
43
+ * @param request - The LLM request (systemPrompt should instruct JSON output)
44
+ * @param parse - Parse raw JSON string into typed result, return null on failure
45
+ * @param fallback - Heuristic fallback
46
+ */
47
+ export declare function callLlmJson<T>(request: LlmRequest, parse: (raw: string) => T | null, fallback: () => T): Promise<LlmResponse<T>>;
@@ -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
+ }