@askexenow/exe-os 0.9.299 → 0.9.300
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/deploy/compose/.env.customer.example +1 -1
- package/deploy/compose/.env.example +1 -1
- package/deploy/compose/docker-compose.yml +31 -5
- package/deploy/compose/generate-env.ts +1 -1
- package/deploy/compose/observability/otel-collector-config.yaml +10 -1
- package/deploy/compose/setup.sh +1 -1
- package/dist/active-agent-56J56WW5.js +27 -0
- package/dist/active-agent-VDWK7TES.js +28 -0
- package/dist/agentic-ontology-MZ4WHFDE.js +25 -0
- package/dist/assets/com.askexe.exed.plist +6 -5
- package/dist/backfill-metadata-IHKI5GXV.js +600 -0
- package/dist/backfill-metadata-ZU3SZNBD.js +600 -0
- package/dist/behaviors-G4KWGS24.js +46 -0
- package/dist/behaviors-WO67R6C4.js +46 -0
- package/dist/bin/agentic-ontology-backfill.js +5 -5
- package/dist/bin/agentic-reflection-backfill.js +6 -6
- package/dist/bin/agentic-semantic-label.js +5 -5
- package/dist/bin/backfill-conversations.js +6 -6
- package/dist/bin/backfill-responses.js +6 -6
- package/dist/bin/backfill-vectors.js +8 -8
- package/dist/bin/bulk-sync-postgres.js +13 -7
- package/dist/bin/cc-doctor.js +5 -5
- package/dist/bin/cleanup-stale-review-tasks.js +10 -10
- package/dist/bin/cli.js +16 -16
- package/dist/bin/deferred-daemon-restart.js +1 -1
- package/dist/bin/exe-agent-config.js +2 -2
- package/dist/bin/exe-agent.js +10 -10
- package/dist/bin/exe-assign.js +8 -8
- package/dist/bin/exe-boot.js +30 -20
- package/dist/bin/exe-call.js +4 -4
- package/dist/bin/exe-cloud.js +13 -7
- package/dist/bin/exe-dispatch.js +10 -10
- package/dist/bin/exe-doctor.js +2 -2
- package/dist/bin/exe-export-behaviors.js +7 -7
- package/dist/bin/exe-forget.js +6 -6
- package/dist/bin/exe-gateway.js +7 -7
- package/dist/bin/exe-healthcheck.js +5 -5
- package/dist/bin/exe-heartbeat.js +10 -10
- package/dist/bin/exe-kill.js +13 -13
- package/dist/bin/exe-launch-agent.js +29 -19
- package/dist/bin/exe-new-employee.js +6 -6
- package/dist/bin/exe-pending-messages.js +11 -11
- package/dist/bin/exe-pending-notifications.js +10 -10
- package/dist/bin/exe-pending-reviews.js +10 -10
- package/dist/bin/exe-rename.js +4 -4
- package/dist/bin/exe-review.js +12 -12
- package/dist/bin/exe-search.js +5 -5
- package/dist/bin/exe-session-cleanup.js +15 -15
- package/dist/bin/exe-settings.js +13 -7
- package/dist/bin/exe-start-codex.js +11 -11
- package/dist/bin/exe-start-opencode.js +8 -8
- package/dist/bin/exe-status.js +11 -11
- package/dist/bin/exe-team.js +3 -3
- package/dist/bin/git-sweep.js +11 -11
- package/dist/bin/graph-backfill.js +6 -6
- package/dist/bin/graph-export.js +5 -5
- package/dist/bin/import-history.js +9 -9
- package/dist/bin/install-launchd.js +7 -3
- package/dist/bin/install.js +19 -15
- package/dist/bin/intercom-check.js +4 -4
- package/dist/bin/mcp-sessions.js +2 -2
- package/dist/bin/orchestration-metrics.js +4 -4
- package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
- package/dist/bin/postgres-agentic-semantic-backfill.js +1 -1
- package/dist/bin/pre-publish.js +24 -1
- package/dist/bin/scan-tasks.js +10 -10
- package/dist/bin/setup.js +1 -1
- package/dist/bin/shard-migrate.js +4 -4
- package/dist/bin/stack-update.js +123 -3
- package/dist/bin/vps-health-gate.js +1 -1
- package/dist/capability-cards-XAQSL26B.js +89 -0
- package/dist/capacity-monitor-6MQLFFQT.js +51 -0
- package/dist/capacity-monitor-BB3LKJLE.js +51 -0
- package/dist/catchup-brief-BQSL5M5S.js +175 -0
- package/dist/catchup-brief-COALBX6L.js +175 -0
- package/dist/cc-binary-detect-B5JDCJ5J.js +19 -0
- package/dist/chunk-22LDUTY7.js +14597 -0
- package/dist/chunk-24M4AJPG.js +128 -0
- package/dist/chunk-2B7RCTPT.js +85 -0
- package/dist/chunk-2QBA6YE6.js +127 -0
- package/dist/chunk-2RGDEBZC.js +731 -0
- package/dist/chunk-32DBQWR5.js +333 -0
- package/dist/chunk-3EOPMTG2.js +128 -0
- package/dist/chunk-3NS4V4JW.js +382 -0
- package/dist/chunk-3NYY2NZ3.js +836 -0
- package/dist/chunk-3ROUD5WA.js +97 -0
- package/dist/chunk-3RY2ARDN.js +129 -0
- package/dist/chunk-3Y5IRIRU.js +290 -0
- package/dist/chunk-3ZWWUKBI.js +210 -0
- package/dist/chunk-463G3VAH.js +122 -0
- package/dist/chunk-4LC7BFI2.js +76 -0
- package/dist/chunk-4Z3FWLOE.js +836 -0
- package/dist/chunk-5BAU4T5G.js +208 -0
- package/dist/chunk-5FP7YHCG.js +1158 -0
- package/dist/chunk-5U3JZP62.js +1352 -0
- package/dist/chunk-5VNFXIGF.js +85 -0
- package/dist/chunk-6UVUJNLY.js +1186 -0
- package/dist/chunk-7KPWYWYL.js +290 -0
- package/dist/chunk-7URNGDEY.js +2145 -0
- package/dist/chunk-ADZQBZOX.js +122 -0
- package/dist/chunk-APSZAEDO.js +1186 -0
- package/dist/chunk-ASHF6VO4.js +2265 -0
- package/dist/chunk-BT2LEHIW.js +448 -0
- package/dist/chunk-BTS5QUWB.js +50 -0
- package/dist/chunk-BWJDJ3BS.js +604 -0
- package/dist/chunk-CME46VWP.js +150 -0
- package/dist/chunk-D3ICCKXY.js +54 -0
- package/dist/chunk-D3IOU3NO.js +377 -0
- package/dist/chunk-DFGXRKI2.js +221 -0
- package/dist/chunk-DO65VHQZ.js +128 -0
- package/dist/chunk-E2OMUBXQ.js +567 -0
- package/dist/chunk-ECMXIV6N.js +97 -0
- package/dist/chunk-EDMVA3PT.js +727 -0
- package/dist/chunk-F5OSXH4A.js +4388 -0
- package/dist/chunk-F5OWHPRG.js +236 -0
- package/dist/chunk-F7MZA3QP.js +199 -0
- package/dist/chunk-FRNXQSB4.js +134 -0
- package/dist/chunk-FTAASABV.js +362 -0
- package/dist/chunk-GBL5QSTM.js +197 -0
- package/dist/chunk-GRXWINOW.js +244 -0
- package/dist/chunk-GUPNVUG5.js +348 -0
- package/dist/chunk-GY66UPMX.js +167 -0
- package/dist/chunk-HCCG67BY.js +43 -0
- package/dist/chunk-HCSZZXZZ.js +197 -0
- package/dist/chunk-HNGNZU62.js +240 -0
- package/dist/chunk-HP2D5LIE.js +214 -0
- package/dist/chunk-HUABQHDC.js +1352 -0
- package/dist/chunk-HYKO2LNW.js +157 -0
- package/dist/chunk-IFL6DG2K.js +181 -0
- package/dist/chunk-IKPQRHVQ.js +304 -0
- package/dist/chunk-JCWA3X6A.js +402 -0
- package/dist/chunk-JHPK33IP.js +2162 -0
- package/dist/chunk-JWGDH5I2.js +127 -0
- package/dist/chunk-KBXQFXYM.js +567 -0
- package/dist/chunk-KGY5QIOJ.js +1350 -0
- package/dist/chunk-KLES22FB.js +1094 -0
- package/dist/chunk-KY43UELJ.js +331 -0
- package/dist/chunk-L32V4O5Z.js +58 -0
- package/dist/chunk-LC7ETNTJ.js +1350 -0
- package/dist/chunk-LEJ5FKIK.js +55 -0
- package/dist/chunk-LNLLCAI4.js +377 -0
- package/dist/chunk-LQWZYMNU.js +448 -0
- package/dist/chunk-LY3SOO73.js +76 -0
- package/dist/chunk-M6CIHXXB.js +159 -0
- package/dist/chunk-MJOQ35DX.js +427 -0
- package/dist/chunk-MO5HER5Y.js +345 -0
- package/dist/chunk-MY4TGLT6.js +284 -0
- package/dist/chunk-N3ARGCVG.js +345 -0
- package/dist/chunk-N4XG2M2U.js +735 -0
- package/dist/chunk-N72JNFJ4.js +535 -0
- package/dist/chunk-NM3AUMFE.js +2145 -0
- package/dist/chunk-NPPQ3TR4.js +735 -0
- package/dist/chunk-NTWF4DAF.js +581 -0
- package/dist/chunk-NXL3VKXM.js +331 -0
- package/dist/chunk-OMSLHEEF.js +456 -0
- package/dist/chunk-OYIP3QVN.js +167 -0
- package/dist/chunk-P2IOW54H.js +668 -0
- package/dist/chunk-P5KXQ3RN.js +731 -0
- package/dist/chunk-P5UXP53T.js +81 -0
- package/dist/chunk-PH6VRRFR.js +395 -0
- package/dist/chunk-Q3GKOF7Z.js +85 -0
- package/dist/chunk-QKBN3CY2.js +381 -0
- package/dist/chunk-QNNAVMQH.js +1094 -0
- package/dist/chunk-QODDW4YI.js +171 -0
- package/dist/chunk-QPAYPTSH.js +2162 -0
- package/dist/chunk-QRWDJ5RI.js +381 -0
- package/dist/chunk-RBFZCHVB.js +105 -0
- package/dist/chunk-RCEULTPF.js +185 -0
- package/dist/chunk-RCGHXBCX.js +630 -0
- package/dist/chunk-ROSCLRTH.js +204 -0
- package/dist/chunk-RYAOSGUW.js +227 -0
- package/dist/chunk-S2SPGHPY.js +38 -0
- package/dist/chunk-SBPEWD7Z.js +171 -0
- package/dist/chunk-SDPUWZP5.js +333 -0
- package/dist/chunk-SVLSHDNL.js +54 -0
- package/dist/chunk-SVUYBT5N.js +262 -0
- package/dist/chunk-T7PTLVJV.js +284 -0
- package/dist/chunk-TGUSLO4B.js +50 -0
- package/dist/chunk-TPJH6PE6.js +1158 -0
- package/dist/chunk-TVW7EDOJ.js +382 -0
- package/dist/chunk-TYRUIE6P.js +58 -0
- package/dist/chunk-UN5EPVBN.js +14597 -0
- package/dist/chunk-URLH7ZVR.js +70 -0
- package/dist/chunk-USYRTGR7.js +402 -0
- package/dist/chunk-V4ABCEHM.js +30 -0
- package/dist/chunk-VKCNXOQ6.js +214 -0
- package/dist/chunk-WB2B25UM.js +230 -0
- package/dist/chunk-WCUZX7F7.js +204 -0
- package/dist/chunk-WL5RMOZQ.js +362 -0
- package/dist/chunk-WPAXAOHD.js +1079 -0
- package/dist/chunk-XABJRAUW.js +3346 -0
- package/dist/chunk-YDFY6YCH.js +280 -0
- package/dist/chunk-YGUMRYCN.js +33 -0
- package/dist/chunk-YJSP5PPG.js +128 -0
- package/dist/chunk-YOMETWOJ.js +4388 -0
- package/dist/chunk-Z4FVFSE3.js +81 -0
- package/dist/chunk-Z4TLSNUW.js +244 -0
- package/dist/chunk-ZP6T5K6I.js +535 -0
- package/dist/chunk-ZR6ZJT32.js +123 -0
- package/dist/co-activation-JGF5YIDU.js +74 -0
- package/dist/co-occurrence-HLLC6GT2.js +95 -0
- package/dist/co-occurrence-W2LIAPHI.js +95 -0
- package/dist/code-context-index-FCL47WKE.js +30 -0
- package/dist/conversation-entity-extractor-WC2RU6RS.js +114 -0
- package/dist/core-memory-CRSR2PSL.js +110 -0
- package/dist/core-memory-VSKFRMEV.js +110 -0
- package/dist/crdt-sync-6VH2YDVY.js +33 -0
- package/dist/crm-webhook-RXFPZJXP.js +10 -0
- package/dist/crm-webhook-Z26LEFKG.js +10 -0
- package/dist/cto-delegation-gate-45IBLPTK.js +280 -0
- package/dist/cto-delegation-gate-SF4EUB2Q.js +280 -0
- package/dist/daemon-orchestration-VB3BLYIT.js +143 -0
- package/dist/daemon-orchestration-W66UYGUD.js +143 -0
- package/dist/db-backup-NVUTS7L5.js +43 -0
- package/dist/doc-graph-extractor-MLYQYT4B.js +133 -0
- package/dist/doc-graph-extractor-SVFSXKL6.js +133 -0
- package/dist/dreaming-AZYRAGKA.js +34 -0
- package/dist/dreaming-WG5CDUHX.js +34 -0
- package/dist/entity-boost-XAFCDDB6.js +375 -0
- package/dist/exe-drift-3SGA53CL.js +70 -0
- package/dist/exe-export-APUNLKWF.js +77 -0
- package/dist/exe-export-NM4SXB3P.js +77 -0
- package/dist/exe-import-6GLNCP62.js +80 -0
- package/dist/exe-import-U4H4ES3Z.js +80 -0
- package/dist/exe-key-FIPXUTMF.js +673 -0
- package/dist/exe-key-WTLCMOYJ.js +673 -0
- package/dist/exe-snapshot-ILO3WSEC.js +338 -0
- package/dist/exe-snapshot-IODRQLBX.js +338 -0
- package/dist/fast-db-init-7LYYUCSJ.js +7 -0
- package/dist/fast-db-init-IU7GYFWB.js +7 -0
- package/dist/gateway/index.js +11 -11
- package/dist/git-staleness-GGCFPHQ5.js +112 -0
- package/dist/git-task-sweep-M3SWXFKJ.js +42 -0
- package/dist/git-task-sweep-Y6KNWB67.js +42 -0
- package/dist/global-procedures-626WAU3I.js +22 -0
- package/dist/graph-auto-extract-TKHQ4OR3.js +183 -0
- package/dist/graph-auto-extract-VGFEWFZX.js +183 -0
- package/dist/graph-rag-KECA5TE4.js +35 -0
- package/dist/hooks/bug-report-worker.js +12 -12
- package/dist/hooks/codex-stop-task-finalizer.js +12 -12
- package/dist/hooks/commit-complete.js +12 -12
- package/dist/hooks/error-recall.js +6 -6
- package/dist/hooks/exe-heartbeat-hook.js +3 -3
- package/dist/hooks/ingest-worker.js +3 -3
- package/dist/hooks/ingest.js +6 -6
- package/dist/hooks/instructions-loaded.js +4 -4
- package/dist/hooks/manifest.json +20 -20
- package/dist/hooks/notification.js +4 -4
- package/dist/hooks/post-compact.js +11 -11
- package/dist/hooks/post-tool-combined.js +6 -6
- package/dist/hooks/pre-compact.js +15 -15
- package/dist/hooks/pre-tool-use.js +15 -15
- package/dist/hooks/prompt-submit.js +23 -23
- package/dist/hooks/session-end.js +20 -20
- package/dist/hooks/session-start.js +12 -12
- package/dist/hooks/stop.js +18 -18
- package/dist/hooks/subagent-stop.js +11 -11
- package/dist/hooks/summary-worker.js +18 -18
- package/dist/index.js +20 -20
- package/dist/installer-3FB5EMPB.js +40 -0
- package/dist/installer-BRQ42CPB.js +344 -0
- package/dist/installer-PXZJG256.js +298 -0
- package/dist/lib/cloud-sync.js +13 -7
- package/dist/lib/consolidation.js +7 -7
- package/dist/lib/database.js +6 -4
- package/dist/lib/db-daemon-client.js +11 -202
- package/dist/lib/db.js +6 -4
- package/dist/lib/embedder.js +3 -3
- package/dist/lib/employee-templates.js +4 -4
- package/dist/lib/employees.js +2 -2
- package/dist/lib/exe-daemon-client.js +2 -2
- package/dist/lib/exe-daemon.js +53 -51
- package/dist/lib/hybrid-search.js +5 -5
- package/dist/lib/identity.js +2 -2
- package/dist/lib/messaging.js +10 -10
- package/dist/lib/reminders.js +3 -3
- package/dist/lib/schedules.js +5 -5
- package/dist/lib/session-registry.js +4 -4
- package/dist/lib/skill-learning.js +6 -6
- package/dist/lib/store.js +4 -4
- package/dist/lib/task-router.js +3 -3
- package/dist/lib/tasks.js +11 -11
- package/dist/lib/tmux-routing.js +9 -9
- package/dist/lib/token-spend.js +3 -3
- package/dist/mcp/register-tools.js +65 -63
- package/dist/mcp/server.js +66 -64
- package/dist/mcp/tools/complete-reminder.js +4 -4
- package/dist/mcp/tools/create-reminder.js +4 -4
- package/dist/mcp/tools/create-task.js +13 -13
- package/dist/mcp/tools/deactivate-behavior.js +7 -7
- package/dist/mcp/tools/list-reminders.js +4 -4
- package/dist/mcp/tools/list-tasks.js +13 -13
- package/dist/mcp/tools/send-message.js +12 -12
- package/dist/mcp/tools/update-task.js +12 -12
- package/dist/mcp-http-config-OF3MB7M5.js +31 -0
- package/dist/memory-cards-CPIZVXWI.js +180 -0
- package/dist/memory-graph-extractor-JIYWLBFF.js +22 -0
- package/dist/memory-graph-extractor-MDPSLZDM.js +22 -0
- package/dist/memory-poisoning-defense-5UZT3WWA.js +224 -0
- package/dist/memory-queue-client-WKWRFERJ.js +16 -0
- package/dist/memory-reflection-TA2VQYPH.js +244 -0
- package/dist/message-queue-client-IFQQ2HI7.js +92 -0
- package/dist/notifications-CZBQ3H5T.js +47 -0
- package/dist/notifications-EIIL2EQV.js +47 -0
- package/dist/orchestration-events-VUYR6MXE.js +27 -0
- package/dist/orchestrator-MAMR4C37.js +35 -0
- package/dist/orchestrator-VE5WHEJH.js +35 -0
- package/dist/pipeline-router-DKXD6DJO.js +15 -0
- package/dist/pipeline-router-YNW63BY5.js +15 -0
- package/dist/plan-limits-ZM4MNZKY.js +28 -0
- package/dist/project-boot-E2TWYTAC.js +299 -0
- package/dist/projection-worker-WFPRM4AI.js +1084 -0
- package/dist/projection-worker-YKV3PFCV.js +1084 -0
- package/dist/prospective-memory-OAFZUODU.js +232 -0
- package/dist/reranker-AFU75HEX.js +19 -0
- package/dist/reranker-RYNSJNDF.js +19 -0
- package/dist/retrieval-health-RSQEIYIB.js +12 -0
- package/dist/review-polling-LGX7DUNT.js +126 -0
- package/dist/review-polling-MJBCYV4I.js +126 -0
- package/dist/runtime/index.js +16 -16
- package/dist/services/codex-reviewd/index.js +855 -0
- package/dist/session-events-5N47BRFK.js +38 -0
- package/dist/session-events-PT6SVS2P.js +38 -0
- package/dist/session-kill-telemetry-HKL2NQMR.js +31 -0
- package/dist/session-scope-GQNCM6UQ.js +88 -0
- package/dist/session-scope-MMGM232A.js +88 -0
- package/dist/setup-wizard-SELXXVLD.js +12 -0
- package/dist/setup-wizard-X7YSRDNQ.js +12 -0
- package/dist/skill-refinement-CCP4ULZ3.js +159 -0
- package/dist/skill-refinement-WCPDNHZ5.js +159 -0
- package/dist/stack-update-5VSGG36W.js +84 -0
- package/dist/steward-gate-PIXNK4BK.js +15 -0
- package/dist/task-enforcement-LEBWCYZT.js +506 -0
- package/dist/task-enforcement-VOSQRAQB.js +506 -0
- package/dist/task-scope-CQZ33PRU.js +37 -0
- package/dist/task-scope-JTTEZKDU.js +37 -0
- package/dist/tasks-crud-DC4GCXQQ.js +79 -0
- package/dist/tasks-crud-T32IRPXF.js +79 -0
- package/dist/tasks-notify-OBFVHJDP.js +40 -0
- package/dist/tasks-notify-OUQWUM6W.js +40 -0
- package/dist/tasks-review-N33MTHWJ.js +49 -0
- package/dist/tasks-review-OSBG2YN2.js +49 -0
- package/dist/telemetry-upload-EYHEWTKG.js +741 -0
- package/dist/telemetry-upload-XLBW4DRP.js +741 -0
- package/dist/token-budget-I6FMMDFX.js +86 -0
- package/dist/tool-capability-index-IWQBQKM7.js +10 -0
- package/dist/tool-telemetry-2E3Z7CRV.js +17 -0
- package/dist/tui/App.js +17 -17
- package/dist/tui-data-VWT4Q5UT.js +260 -0
- package/dist/tui-data-XFBFBSBE.js +260 -0
- package/dist/wiki-acl-EUOPNUIQ.js +111 -0
- package/dist/worker-gate-OQMKAMP7.js +21 -0
- package/dist/worker-gate-ZPP3SZK6.js +21 -0
- package/dist/workflow-engine-P7WYJP2B.js +28 -0
- package/dist/workflow-engine-UYNB5RTB.js +28 -0
- package/dist/worktree-H5C4LMQR.js +28 -0
- package/dist/worktree-sweep-KFWF3XZD.js +21 -0
- package/package.json +1 -1
- package/release-notes.json +30 -104
- package/src/commands/exe.md +18 -1
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import {
|
|
2
|
+
executeAction,
|
|
3
|
+
substituteTemplate
|
|
4
|
+
} from "./chunk-TVW7EDOJ.js";
|
|
5
|
+
|
|
6
|
+
// src/automation/workflow-engine.ts
|
|
7
|
+
import { randomUUID } from "crypto";
|
|
8
|
+
var _definitions = /* @__PURE__ */ new Map();
|
|
9
|
+
var _instances = /* @__PURE__ */ new Map();
|
|
10
|
+
function createWorkflowDefinition(input) {
|
|
11
|
+
const def = {
|
|
12
|
+
id: randomUUID().slice(0, 12),
|
|
13
|
+
...input,
|
|
14
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
15
|
+
};
|
|
16
|
+
def.steps = def.steps.map((s, i) => ({ ...s, index: s.index || i + 1 }));
|
|
17
|
+
_definitions.set(def.id, def);
|
|
18
|
+
return def;
|
|
19
|
+
}
|
|
20
|
+
function getWorkflowDefinition(id) {
|
|
21
|
+
return _definitions.get(id);
|
|
22
|
+
}
|
|
23
|
+
function listWorkflowDefinitions() {
|
|
24
|
+
return [..._definitions.values()];
|
|
25
|
+
}
|
|
26
|
+
function buildTemplateContext(instance) {
|
|
27
|
+
const ctx = { ...instance.context };
|
|
28
|
+
const stepMap = {};
|
|
29
|
+
for (const sr of instance.step_results) {
|
|
30
|
+
stepMap[String(sr.step_index)] = {
|
|
31
|
+
status: sr.status,
|
|
32
|
+
result: sr.result,
|
|
33
|
+
error: sr.error
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
ctx.step = stepMap;
|
|
37
|
+
return ctx;
|
|
38
|
+
}
|
|
39
|
+
function resolveActionParams(action, context) {
|
|
40
|
+
const resolved = {};
|
|
41
|
+
for (const [key, val] of Object.entries(action.params)) {
|
|
42
|
+
resolved[key] = substituteTemplate(val, context);
|
|
43
|
+
}
|
|
44
|
+
return { ...action, params: resolved };
|
|
45
|
+
}
|
|
46
|
+
function startWorkflow(definitionId, context = {}) {
|
|
47
|
+
const def = _definitions.get(definitionId);
|
|
48
|
+
if (!def) throw new Error(`Workflow definition "${definitionId}" not found`);
|
|
49
|
+
const instance = {
|
|
50
|
+
id: randomUUID().slice(0, 12),
|
|
51
|
+
definition_id: definitionId,
|
|
52
|
+
status: "running",
|
|
53
|
+
current_step: 1,
|
|
54
|
+
step_results: [],
|
|
55
|
+
context,
|
|
56
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
57
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
58
|
+
};
|
|
59
|
+
_instances.set(instance.id, instance);
|
|
60
|
+
return instance;
|
|
61
|
+
}
|
|
62
|
+
function getWorkflowInstance(id) {
|
|
63
|
+
return _instances.get(id);
|
|
64
|
+
}
|
|
65
|
+
function listWorkflowInstances(status) {
|
|
66
|
+
const all = [..._instances.values()];
|
|
67
|
+
return status ? all.filter((i) => i.status === status) : all;
|
|
68
|
+
}
|
|
69
|
+
async function advanceWorkflow(instanceId) {
|
|
70
|
+
const instance = _instances.get(instanceId);
|
|
71
|
+
if (!instance) throw new Error(`Workflow instance "${instanceId}" not found`);
|
|
72
|
+
if (instance.status !== "running") {
|
|
73
|
+
throw new Error(`Workflow "${instanceId}" is ${instance.status}, cannot advance`);
|
|
74
|
+
}
|
|
75
|
+
const def = _definitions.get(instance.definition_id);
|
|
76
|
+
if (!def) throw new Error(`Workflow definition "${instance.definition_id}" not found`);
|
|
77
|
+
const step = def.steps.find((s) => s.index === instance.current_step);
|
|
78
|
+
if (!step) {
|
|
79
|
+
instance.status = "completed";
|
|
80
|
+
instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
81
|
+
return instance;
|
|
82
|
+
}
|
|
83
|
+
const templateCtx = buildTemplateContext(instance);
|
|
84
|
+
const stepResult = {
|
|
85
|
+
step_index: step.index,
|
|
86
|
+
status: "success",
|
|
87
|
+
started_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
88
|
+
};
|
|
89
|
+
switch (step.type) {
|
|
90
|
+
case "execute_action": {
|
|
91
|
+
const action = step.action ?? buildActionFromConnector(step);
|
|
92
|
+
if (!action) {
|
|
93
|
+
stepResult.status = "failed";
|
|
94
|
+
stepResult.error = "No action defined for execute_action step";
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
const resolvedAction = resolveActionParams(action, templateCtx);
|
|
98
|
+
const result = await executeAction(resolvedAction, templateCtx);
|
|
99
|
+
stepResult.status = result.success ? "success" : "failed";
|
|
100
|
+
stepResult.result = result;
|
|
101
|
+
stepResult.error = result.error;
|
|
102
|
+
if (!result.success) {
|
|
103
|
+
instance.status = "failed";
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
case "wait_for_approval": {
|
|
108
|
+
const { createTask } = await import("./lib/tasks.js");
|
|
109
|
+
const { getCoordinatorName } = await import("./lib/employees.js");
|
|
110
|
+
const message = step.approval_message ? substituteTemplate(step.approval_message, templateCtx) : `Workflow "${def.name}" step ${step.index} ("${step.name}") requires approval.`;
|
|
111
|
+
const task = await createTask({
|
|
112
|
+
title: `[Workflow Approval] ${def.name}: ${step.name}`,
|
|
113
|
+
assignedTo: getCoordinatorName(),
|
|
114
|
+
assignedBy: "workflow-engine",
|
|
115
|
+
projectName: "exe-os",
|
|
116
|
+
priority: "p1",
|
|
117
|
+
context: `${message}
|
|
118
|
+
|
|
119
|
+
**Workflow:** ${def.name} (${instance.id})
|
|
120
|
+
**Step:** ${step.index} \u2014 ${step.name}
|
|
121
|
+
|
|
122
|
+
To approve: call approve_workflow_step with instance_id="${instance.id}"
|
|
123
|
+
To reject: call approve_workflow_step with instance_id="${instance.id}" approved=false`,
|
|
124
|
+
baseDir: process.cwd()
|
|
125
|
+
});
|
|
126
|
+
instance.approval_task_id = task.id;
|
|
127
|
+
instance.status = "waiting_approval";
|
|
128
|
+
stepResult.status = "pending_approval";
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
case "conditional": {
|
|
132
|
+
if (!step.condition) {
|
|
133
|
+
stepResult.status = "failed";
|
|
134
|
+
stepResult.error = "No condition defined for conditional step";
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
const resolvedExpr = substituteTemplate(step.condition.expression, templateCtx);
|
|
138
|
+
const conditionMet = evaluateSimpleExpression(resolvedExpr);
|
|
139
|
+
stepResult.result = { expression: resolvedExpr, met: conditionMet };
|
|
140
|
+
if (conditionMet && step.condition.then_step) {
|
|
141
|
+
instance.current_step = step.condition.then_step;
|
|
142
|
+
stepResult.completed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
143
|
+
instance.step_results.push(stepResult);
|
|
144
|
+
instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
145
|
+
return instance;
|
|
146
|
+
} else if (!conditionMet && step.condition.else_step) {
|
|
147
|
+
instance.current_step = step.condition.else_step;
|
|
148
|
+
stepResult.completed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
149
|
+
instance.step_results.push(stepResult);
|
|
150
|
+
instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
151
|
+
return instance;
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
stepResult.completed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
157
|
+
instance.step_results.push(stepResult);
|
|
158
|
+
if (instance.status === "running") {
|
|
159
|
+
const nextStep = def.steps.find((s) => s.index > step.index);
|
|
160
|
+
if (nextStep) {
|
|
161
|
+
instance.current_step = nextStep.index;
|
|
162
|
+
} else {
|
|
163
|
+
instance.status = "completed";
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
167
|
+
return instance;
|
|
168
|
+
}
|
|
169
|
+
async function runWorkflow(instanceId) {
|
|
170
|
+
let instance = _instances.get(instanceId);
|
|
171
|
+
if (!instance) throw new Error(`Workflow instance "${instanceId}" not found`);
|
|
172
|
+
while (instance.status === "running") {
|
|
173
|
+
instance = await advanceWorkflow(instanceId);
|
|
174
|
+
}
|
|
175
|
+
return instance;
|
|
176
|
+
}
|
|
177
|
+
async function approveWorkflowStep(instanceId, approved = true) {
|
|
178
|
+
const instance = _instances.get(instanceId);
|
|
179
|
+
if (!instance) throw new Error(`Workflow instance "${instanceId}" not found`);
|
|
180
|
+
if (instance.status !== "waiting_approval") {
|
|
181
|
+
throw new Error(`Workflow "${instanceId}" is not waiting for approval (status: ${instance.status})`);
|
|
182
|
+
}
|
|
183
|
+
const pendingResult = instance.step_results.find(
|
|
184
|
+
(sr) => sr.step_index === instance.current_step && sr.status === "pending_approval"
|
|
185
|
+
);
|
|
186
|
+
if (pendingResult) {
|
|
187
|
+
pendingResult.status = approved ? "approved" : "failed";
|
|
188
|
+
pendingResult.completed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
189
|
+
pendingResult.result = { approved };
|
|
190
|
+
}
|
|
191
|
+
if (!approved) {
|
|
192
|
+
instance.status = "cancelled";
|
|
193
|
+
instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
194
|
+
return instance;
|
|
195
|
+
}
|
|
196
|
+
const def = _definitions.get(instance.definition_id);
|
|
197
|
+
if (!def) throw new Error(`Workflow definition "${instance.definition_id}" not found`);
|
|
198
|
+
const currentStep = def.steps.find((s) => s.index === instance.current_step);
|
|
199
|
+
const nextStep = currentStep ? def.steps.find((s) => s.index > currentStep.index) : void 0;
|
|
200
|
+
if (nextStep) {
|
|
201
|
+
instance.current_step = nextStep.index;
|
|
202
|
+
instance.status = "running";
|
|
203
|
+
} else {
|
|
204
|
+
instance.status = "completed";
|
|
205
|
+
}
|
|
206
|
+
instance.approval_task_id = void 0;
|
|
207
|
+
instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
208
|
+
if (instance.status === "running") {
|
|
209
|
+
return runWorkflow(instanceId);
|
|
210
|
+
}
|
|
211
|
+
return instance;
|
|
212
|
+
}
|
|
213
|
+
function buildActionFromConnector(step) {
|
|
214
|
+
if (!step.connector || !step.operation) return null;
|
|
215
|
+
const params = {};
|
|
216
|
+
if (step.payload) {
|
|
217
|
+
for (const [k, v] of Object.entries(step.payload)) {
|
|
218
|
+
params[k] = String(v);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
params._connector = step.connector;
|
|
222
|
+
params._operation = step.operation;
|
|
223
|
+
return {
|
|
224
|
+
type: "mcp_tool",
|
|
225
|
+
params
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
function evaluateSimpleExpression(expr) {
|
|
229
|
+
const operators = ["==", "!=", ">=", "<=", ">", "<"];
|
|
230
|
+
for (const op of operators) {
|
|
231
|
+
const idx = expr.indexOf(op);
|
|
232
|
+
if (idx === -1) continue;
|
|
233
|
+
const left = expr.slice(0, idx).trim();
|
|
234
|
+
const right = expr.slice(idx + op.length).trim();
|
|
235
|
+
switch (op) {
|
|
236
|
+
case "==":
|
|
237
|
+
return left === right;
|
|
238
|
+
case "!=":
|
|
239
|
+
return left !== right;
|
|
240
|
+
case ">":
|
|
241
|
+
return Number(left) > Number(right);
|
|
242
|
+
case "<":
|
|
243
|
+
return Number(left) < Number(right);
|
|
244
|
+
case ">=":
|
|
245
|
+
return Number(left) >= Number(right);
|
|
246
|
+
case "<=":
|
|
247
|
+
return Number(left) <= Number(right);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return expr.trim() !== "" && expr.trim() !== "false" && expr.trim() !== "0";
|
|
251
|
+
}
|
|
252
|
+
async function persistWorkflows() {
|
|
253
|
+
try {
|
|
254
|
+
const { getClient } = await import("./lib/database.js");
|
|
255
|
+
const client = getClient();
|
|
256
|
+
for (const def of _definitions.values()) {
|
|
257
|
+
await client.execute({
|
|
258
|
+
sql: `INSERT OR REPLACE INTO workflow_definitions (id, name, description, steps, trigger_event, created_at)
|
|
259
|
+
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
260
|
+
args: [def.id, def.name, def.description ?? null, JSON.stringify(def.steps), def.trigger_event ?? null, def.created_at]
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
for (const inst of _instances.values()) {
|
|
264
|
+
await client.execute({
|
|
265
|
+
sql: `INSERT OR REPLACE INTO workflow_instances
|
|
266
|
+
(id, definition_id, status, current_step, step_results, context, approval_task_id, created_at, updated_at)
|
|
267
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
268
|
+
args: [
|
|
269
|
+
inst.id,
|
|
270
|
+
inst.definition_id,
|
|
271
|
+
inst.status,
|
|
272
|
+
inst.current_step,
|
|
273
|
+
JSON.stringify(inst.step_results),
|
|
274
|
+
JSON.stringify(inst.context),
|
|
275
|
+
inst.approval_task_id ?? null,
|
|
276
|
+
inst.created_at,
|
|
277
|
+
inst.updated_at
|
|
278
|
+
]
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
} catch (e) {
|
|
282
|
+
process.stderr.write(`[workflow-engine] persist failed: ${e instanceof Error ? e.message : String(e)}
|
|
283
|
+
`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
async function loadWorkflows() {
|
|
287
|
+
try {
|
|
288
|
+
const { getClient } = await import("./lib/database.js");
|
|
289
|
+
const client = getClient();
|
|
290
|
+
const defs = await client.execute("SELECT * FROM workflow_definitions");
|
|
291
|
+
for (const row of defs.rows) {
|
|
292
|
+
const def = {
|
|
293
|
+
id: String(row.id),
|
|
294
|
+
name: String(row.name),
|
|
295
|
+
description: String(row.description),
|
|
296
|
+
steps: JSON.parse(String(row.steps)),
|
|
297
|
+
trigger_event: String(row.trigger_event),
|
|
298
|
+
created_at: String(row.created_at)
|
|
299
|
+
};
|
|
300
|
+
_definitions.set(def.id, def);
|
|
301
|
+
}
|
|
302
|
+
const insts = await client.execute("SELECT * FROM workflow_instances WHERE status NOT IN ('completed', 'cancelled')");
|
|
303
|
+
for (const row of insts.rows) {
|
|
304
|
+
const inst = {
|
|
305
|
+
id: String(row.id),
|
|
306
|
+
definition_id: String(row.definition_id),
|
|
307
|
+
status: String(row.status),
|
|
308
|
+
current_step: Number(row.current_step),
|
|
309
|
+
step_results: JSON.parse(String(row.step_results)),
|
|
310
|
+
context: JSON.parse(String(row.context)),
|
|
311
|
+
approval_task_id: row.approval_task_id ? String(row.approval_task_id) : void 0,
|
|
312
|
+
created_at: String(row.created_at),
|
|
313
|
+
updated_at: String(row.updated_at)
|
|
314
|
+
};
|
|
315
|
+
_instances.set(inst.id, inst);
|
|
316
|
+
}
|
|
317
|
+
} catch {
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export {
|
|
322
|
+
createWorkflowDefinition,
|
|
323
|
+
getWorkflowDefinition,
|
|
324
|
+
listWorkflowDefinitions,
|
|
325
|
+
startWorkflow,
|
|
326
|
+
getWorkflowInstance,
|
|
327
|
+
listWorkflowInstances,
|
|
328
|
+
advanceWorkflow,
|
|
329
|
+
runWorkflow,
|
|
330
|
+
approveWorkflowStep,
|
|
331
|
+
persistWorkflows,
|
|
332
|
+
loadWorkflows
|
|
333
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {
|
|
2
|
+
processCRMEvent
|
|
3
|
+
} from "./chunk-TVW7EDOJ.js";
|
|
4
|
+
|
|
5
|
+
// src/gateway/adapters/crm-webhook.ts
|
|
6
|
+
function parseTwentyWebhook(payload) {
|
|
7
|
+
if (!payload || typeof payload !== "object") return null;
|
|
8
|
+
const p = payload;
|
|
9
|
+
const eventName = p.eventName;
|
|
10
|
+
if (!eventName || typeof eventName !== "string") return null;
|
|
11
|
+
const dotIndex = eventName.indexOf(".");
|
|
12
|
+
if (dotIndex === -1) return null;
|
|
13
|
+
const objectType = eventName.slice(0, dotIndex);
|
|
14
|
+
const eventType = eventName.slice(dotIndex + 1);
|
|
15
|
+
if (!objectType || !eventType) return null;
|
|
16
|
+
const normalizedObjectType = objectType.charAt(0).toUpperCase() + objectType.slice(1);
|
|
17
|
+
const record = p.record ?? {};
|
|
18
|
+
if (typeof record !== "object") return null;
|
|
19
|
+
return {
|
|
20
|
+
eventType,
|
|
21
|
+
objectType: normalizedObjectType,
|
|
22
|
+
record
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function createCRMWebhookHandler(options) {
|
|
26
|
+
return async (body) => {
|
|
27
|
+
const event = parseTwentyWebhook(body);
|
|
28
|
+
if (!event) {
|
|
29
|
+
console.warn(
|
|
30
|
+
"[crm-webhook] Malformed CRM webhook payload \u2014 skipping"
|
|
31
|
+
);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
console.log(
|
|
35
|
+
`[crm-webhook] ${event.objectType}.${event.eventType} received`
|
|
36
|
+
);
|
|
37
|
+
try {
|
|
38
|
+
const logs = await processCRMEvent(event, options?.executor, options?.triggers);
|
|
39
|
+
if (logs.length > 0 && options?.onFired) {
|
|
40
|
+
options.onFired(logs);
|
|
41
|
+
}
|
|
42
|
+
} catch (err) {
|
|
43
|
+
console.error(
|
|
44
|
+
"[crm-webhook] Error processing CRM event:",
|
|
45
|
+
err instanceof Error ? err.message : err
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
parseTwentyWebhook,
|
|
53
|
+
createCRMWebhookHandler
|
|
54
|
+
};
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
// src/lib/agentic-ontology.ts
|
|
2
|
+
import { createHash } from "crypto";
|
|
3
|
+
function stableId(...parts) {
|
|
4
|
+
return createHash("sha256").update(parts.map((p) => String(p ?? "")).join("::")).digest("hex").slice(0, 32);
|
|
5
|
+
}
|
|
6
|
+
function clean(text, max = 240) {
|
|
7
|
+
return text.replace(/\u0000/g, "").replace(/```[\s\S]*?```/g, " ").replace(/\s+/g, " ").trim().slice(0, max);
|
|
8
|
+
}
|
|
9
|
+
function inferOntologyEventType(row) {
|
|
10
|
+
const lower = row.raw_text.toLowerCase();
|
|
11
|
+
if (row.has_error) return "error";
|
|
12
|
+
if (/\b(done|complete|completed|fixed|resolved|shipped|deployed|pushed|published)\b/.test(lower)) return "milestone";
|
|
13
|
+
if (/\b(blocked|failed|error|bug|regression|broken)\b/.test(lower)) return "problem";
|
|
14
|
+
if (/\b(decided|decision|adr|we chose|approved|rejected)\b/.test(lower)) return "decision";
|
|
15
|
+
if (/\b(goal|need to|we need|want to|trying to|objective)\b/.test(lower)) return "goal_signal";
|
|
16
|
+
if (["Bash", "Read", "Edit", "Write", "Grep", "Glob"].includes(row.tool_name)) return "tool_action";
|
|
17
|
+
if (row.tool_name.startsWith("memory_card")) return "memory_card";
|
|
18
|
+
return "memory_observation";
|
|
19
|
+
}
|
|
20
|
+
function inferIntention(row) {
|
|
21
|
+
if (row.intent) return clean(row.intent, 220);
|
|
22
|
+
const text = clean(row.raw_text, 1e3);
|
|
23
|
+
const patterns = [
|
|
24
|
+
/(?:we need to|need to|let'?s|i want to|we should|goal is to|objective is to|trying to)\s+([^.!?\n]{8,220})/i,
|
|
25
|
+
/(?:so that|in order to)\s+([^.!?\n]{8,220})/i,
|
|
26
|
+
/(?:task|plan):\s*([^.!?\n]{8,220})/i
|
|
27
|
+
];
|
|
28
|
+
for (const p of patterns) {
|
|
29
|
+
const m = text.match(p);
|
|
30
|
+
if (m?.[1]) return clean(m[1], 220);
|
|
31
|
+
}
|
|
32
|
+
if (["Bash", "Read", "Edit", "Write", "Grep", "Glob"].includes(row.tool_name)) {
|
|
33
|
+
return `${row.tool_name} during ${row.project_name}`;
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
function inferOutcome(row) {
|
|
38
|
+
if (row.outcome) return clean(row.outcome, 220);
|
|
39
|
+
if (row.has_error) return "error";
|
|
40
|
+
const lower = row.raw_text.toLowerCase();
|
|
41
|
+
if (/\b(done|complete|completed|fixed|resolved|shipped|deployed|pushed|published|passed)\b/.test(lower)) return "success_signal";
|
|
42
|
+
if (/\b(blocked|failed|error|regression|broken|not working|could not)\b/.test(lower)) return "failure_signal";
|
|
43
|
+
if (/\b(warning|risk|concern|caveat)\b/.test(lower)) return "risk_signal";
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
function extractGoalCandidates(row) {
|
|
47
|
+
const text = clean(row.raw_text, 1600);
|
|
48
|
+
const patterns = [
|
|
49
|
+
/(?:we need to|need to|i want to|we should|goal is to|objective is to|trying to|let'?s)\s+([^.!?\n]{12,220})/gi,
|
|
50
|
+
/(?:success means|success criteria|so that)\s+([^.!?\n]{12,220})/gi
|
|
51
|
+
];
|
|
52
|
+
const out = [];
|
|
53
|
+
for (const pattern of patterns) {
|
|
54
|
+
for (const m of text.matchAll(pattern)) {
|
|
55
|
+
const candidate = clean(m[1] ?? "", 220);
|
|
56
|
+
if (candidate.length >= 12 && !out.some((x) => x.toLowerCase() === candidate.toLowerCase())) out.push(candidate);
|
|
57
|
+
if (out.length >= 3) return out;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
function uniq(values, max = 6) {
|
|
63
|
+
const out = [];
|
|
64
|
+
for (const value of values.map((v) => clean(v, 220)).filter(Boolean)) {
|
|
65
|
+
if (!out.some((x) => x.toLowerCase() === value.toLowerCase())) out.push(value);
|
|
66
|
+
if (out.length >= max) break;
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
function extractMatches(text, patterns, max = 5) {
|
|
71
|
+
const out = [];
|
|
72
|
+
for (const pattern of patterns) {
|
|
73
|
+
for (const match of text.matchAll(pattern)) {
|
|
74
|
+
const value = match[1] ?? match[0];
|
|
75
|
+
if (value) out.push(value);
|
|
76
|
+
if (out.length >= max) return uniq(out, max);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return uniq(out, max);
|
|
80
|
+
}
|
|
81
|
+
function inferSemanticLabel(row) {
|
|
82
|
+
const text = clean(row.raw_text, 2400);
|
|
83
|
+
const eventType = inferOntologyEventType(row);
|
|
84
|
+
const intention = inferIntention(row);
|
|
85
|
+
const outcome = inferOutcome(row);
|
|
86
|
+
const goals = extractGoalCandidates(row);
|
|
87
|
+
const milestones = extractMatches(text, [
|
|
88
|
+
/\b(?:completed|finished|fixed|resolved|shipped|deployed|published|pushed|passed)\b([^.!?\n]{0,180})/gi,
|
|
89
|
+
/(?:milestone|done):\s*([^.!?\n]{8,220})/gi
|
|
90
|
+
]);
|
|
91
|
+
const problems = extractMatches(text, [
|
|
92
|
+
/\b(?:blocked by|failed because|bug|regression|broken|not working|error)\b([^.!?\n]{0,180})/gi,
|
|
93
|
+
/(?:problem|issue|risk):\s*([^.!?\n]{8,220})/gi
|
|
94
|
+
]);
|
|
95
|
+
const decisions = extractMatches(text, [
|
|
96
|
+
/(?:decided|decision|adr|we chose|approved|rejected)\s+([^.!?\n]{8,220})/gi
|
|
97
|
+
]);
|
|
98
|
+
const temporalAnchors = extractMatches(text, [
|
|
99
|
+
/\b(\d{4}-\d{2}-\d{2}(?:[T ][0-9:.+-Z]+)?)\b/g,
|
|
100
|
+
/\b(today|yesterday|tomorrow|this week|next week|last week|morning|afternoon|tonight)\b/gi
|
|
101
|
+
], 8);
|
|
102
|
+
const nextActions = extractMatches(text, [
|
|
103
|
+
/(?:next|todo|follow[- ]?up|remaining|need to)\s*:?\s*([^.!?\n]{8,220})/gi
|
|
104
|
+
]);
|
|
105
|
+
const actors = uniq([
|
|
106
|
+
row.agent_id,
|
|
107
|
+
...extractMatches(text, [/\b(?:agent|employee|owner|assignee)[:= ]+([a-zA-Z][a-zA-Z0-9_-]{1,40})/gi], 5)
|
|
108
|
+
], 6);
|
|
109
|
+
const successSignals = milestones.length ? milestones : outcome === "success_signal" ? [clean(text, 180)] : [];
|
|
110
|
+
const failureSignals = problems.length ? problems : outcome === "failure_signal" || row.has_error ? [clean(text, 180)] : [];
|
|
111
|
+
const impact = successSignals.length && failureSignals.length ? "mixed" : failureSignals.length ? "negative" : successSignals.length ? "positive" : "neutral";
|
|
112
|
+
const signalCount = goals.length + milestones.length + problems.length + decisions.length + nextActions.length;
|
|
113
|
+
return {
|
|
114
|
+
labeler: "deterministic",
|
|
115
|
+
schemaVersion: 1,
|
|
116
|
+
eventType,
|
|
117
|
+
intention,
|
|
118
|
+
outcome,
|
|
119
|
+
impact,
|
|
120
|
+
confidence: Math.min(0.95, 0.45 + signalCount * 0.08 + (intention ? 0.1 : 0) + (outcome ? 0.1 : 0)),
|
|
121
|
+
goals,
|
|
122
|
+
milestones,
|
|
123
|
+
problems,
|
|
124
|
+
decisions,
|
|
125
|
+
actors,
|
|
126
|
+
temporalAnchors,
|
|
127
|
+
successSignals,
|
|
128
|
+
failureSignals,
|
|
129
|
+
nextActions,
|
|
130
|
+
summary: clean(text, 280)
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function ontologyPayload(row) {
|
|
134
|
+
const semantic = inferSemanticLabel(row);
|
|
135
|
+
return {
|
|
136
|
+
tool_name: row.tool_name,
|
|
137
|
+
memory_version: row.version ?? null,
|
|
138
|
+
domain: row.domain ?? null,
|
|
139
|
+
trajectory: row.trajectory ? safeJson(row.trajectory) : null,
|
|
140
|
+
semantic
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function safeJson(value) {
|
|
144
|
+
try {
|
|
145
|
+
return JSON.parse(value);
|
|
146
|
+
} catch {
|
|
147
|
+
return value.slice(0, 1e3);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async function resolveClient(client) {
|
|
151
|
+
if (client) return client;
|
|
152
|
+
const { getClient } = await import("./lib/database.js");
|
|
153
|
+
return getClient();
|
|
154
|
+
}
|
|
155
|
+
async function insertOntologyForMemory(row, client) {
|
|
156
|
+
const db = await resolveClient(client);
|
|
157
|
+
const occurredAt = row.timestamp;
|
|
158
|
+
const sequence = Number(row.version ?? 0) || Math.floor(new Date(occurredAt).getTime() / 1e3);
|
|
159
|
+
const eventType = inferOntologyEventType(row);
|
|
160
|
+
const intention = inferIntention(row);
|
|
161
|
+
const outcome = inferOutcome(row);
|
|
162
|
+
const eventId = stableId("event", row.id);
|
|
163
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
164
|
+
await db.execute({
|
|
165
|
+
sql: `INSERT INTO agent_sessions (id, agent_id, project_name, started_at, last_event_at, event_count, properties)
|
|
166
|
+
VALUES (?, ?, ?, ?, ?, 1, ?)
|
|
167
|
+
ON CONFLICT(id) DO UPDATE SET last_event_at = MAX(last_event_at, excluded.last_event_at),
|
|
168
|
+
event_count = event_count + 1`,
|
|
169
|
+
args: [row.session_id, row.agent_id, row.project_name, occurredAt, occurredAt, JSON.stringify({ agent_role: row.agent_role })]
|
|
170
|
+
});
|
|
171
|
+
await db.execute({
|
|
172
|
+
sql: `INSERT OR IGNORE INTO agent_events
|
|
173
|
+
(id, event_type, occurred_at, sequence_index, actor_agent_id, agent_role, project_name,
|
|
174
|
+
session_id, task_id, goal_id, parent_event_id, intention, outcome, evidence_memory_id,
|
|
175
|
+
impact, payload, created_at)
|
|
176
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, NULL, ?, ?, ?, ?, ?, ?)`,
|
|
177
|
+
args: [
|
|
178
|
+
eventId,
|
|
179
|
+
eventType,
|
|
180
|
+
occurredAt,
|
|
181
|
+
sequence,
|
|
182
|
+
row.agent_id,
|
|
183
|
+
row.agent_role,
|
|
184
|
+
row.project_name,
|
|
185
|
+
row.session_id,
|
|
186
|
+
row.task_id ?? null,
|
|
187
|
+
intention,
|
|
188
|
+
outcome,
|
|
189
|
+
row.id,
|
|
190
|
+
row.has_error ? "negative" : outcome === "success_signal" ? "positive" : "neutral",
|
|
191
|
+
JSON.stringify(ontologyPayload(row)),
|
|
192
|
+
now
|
|
193
|
+
]
|
|
194
|
+
});
|
|
195
|
+
const semantic = inferSemanticLabel(row);
|
|
196
|
+
await db.execute({
|
|
197
|
+
sql: `INSERT INTO agent_semantic_labels
|
|
198
|
+
(id, source_memory_id, event_id, labeler, schema_version, confidence, labels, created_at, updated_at)
|
|
199
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
200
|
+
ON CONFLICT(id) DO UPDATE SET confidence = excluded.confidence,
|
|
201
|
+
labels = excluded.labels, updated_at = excluded.updated_at`,
|
|
202
|
+
args: [
|
|
203
|
+
stableId("semantic", row.id, semantic.labeler, semantic.schemaVersion),
|
|
204
|
+
row.id,
|
|
205
|
+
eventId,
|
|
206
|
+
semantic.labeler,
|
|
207
|
+
semantic.schemaVersion,
|
|
208
|
+
semantic.confidence,
|
|
209
|
+
JSON.stringify(semantic),
|
|
210
|
+
now,
|
|
211
|
+
now
|
|
212
|
+
]
|
|
213
|
+
});
|
|
214
|
+
for (const statement of extractGoalCandidates(row)) {
|
|
215
|
+
const goalId = stableId("goal", row.project_name, statement.toLowerCase());
|
|
216
|
+
await db.execute({
|
|
217
|
+
sql: `INSERT INTO agent_goals
|
|
218
|
+
(id, statement, owner_agent_id, project_name, status, priority, success_criteria,
|
|
219
|
+
parent_goal_id, due_at, achieved_at, supersedes_id, created_at, updated_at, source_memory_id)
|
|
220
|
+
VALUES (?, ?, ?, ?, 'open', 5, NULL, NULL, NULL, NULL, NULL, ?, ?, ?)
|
|
221
|
+
ON CONFLICT(id) DO UPDATE SET updated_at = excluded.updated_at`,
|
|
222
|
+
args: [goalId, statement, row.agent_id, row.project_name, now, now, row.id]
|
|
223
|
+
});
|
|
224
|
+
await db.execute({
|
|
225
|
+
sql: `INSERT OR IGNORE INTO agent_goal_links
|
|
226
|
+
(id, goal_id, link_type, target_id, target_type, created_at)
|
|
227
|
+
VALUES (?, ?, 'evidence', ?, 'memory', ?)`,
|
|
228
|
+
args: [stableId("goal_link", goalId, row.id, "memory"), goalId, row.id, now]
|
|
229
|
+
});
|
|
230
|
+
await db.execute({
|
|
231
|
+
sql: `INSERT OR IGNORE INTO agent_goal_links
|
|
232
|
+
(id, goal_id, link_type, target_id, target_type, created_at)
|
|
233
|
+
VALUES (?, ?, 'event', ?, 'event', ?)`,
|
|
234
|
+
args: [stableId("goal_link", goalId, eventId, "event"), goalId, eventId, now]
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
async function insertOntologyForBatch(rows, client) {
|
|
239
|
+
const db = await resolveClient(client);
|
|
240
|
+
let count = 0;
|
|
241
|
+
for (const row of rows) {
|
|
242
|
+
try {
|
|
243
|
+
await insertOntologyForMemory(row, db);
|
|
244
|
+
count++;
|
|
245
|
+
} catch {
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return count;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export {
|
|
252
|
+
stableId,
|
|
253
|
+
clean,
|
|
254
|
+
inferOntologyEventType,
|
|
255
|
+
inferIntention,
|
|
256
|
+
inferOutcome,
|
|
257
|
+
extractGoalCandidates,
|
|
258
|
+
inferSemanticLabel,
|
|
259
|
+
ontologyPayload,
|
|
260
|
+
insertOntologyForMemory,
|
|
261
|
+
insertOntologyForBatch
|
|
262
|
+
};
|