triflux 10.4.0 → 10.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.
- package/.claude-plugin/marketplace.json +34 -0
- package/.claude-plugin/plugin.json +22 -0
- package/bin/tfx-doctor-tui.mjs +1 -1
- package/bin/tfx-doctor.mjs +6 -1
- package/bin/tfx-profile.mjs +1 -1
- package/bin/tfx-setup-tui.mjs +1 -1
- package/bin/tfx-setup.mjs +6 -1
- package/bin/triflux.mjs +2396 -1140
- package/config/mcp-registry.json +29 -0
- package/hooks/agent-route-guard.mjs +12 -8
- package/hooks/cross-review-tracker.mjs +21 -8
- package/hooks/error-context.mjs +19 -7
- package/hooks/hook-adaptive-collector.mjs +18 -16
- package/hooks/hook-manager.mjs +93 -32
- package/hooks/hook-orchestrator.mjs +108 -24
- package/hooks/hook-registry.json +267 -256
- package/hooks/keyword-rules.json +6 -10
- package/hooks/lib/resolve-root.mjs +1 -1
- package/hooks/mcp-config-watcher.mjs +6 -2
- package/hooks/pipeline-stop.mjs +3 -6
- package/hooks/safety-guard.mjs +99 -28
- package/hooks/session-start-fast.mjs +143 -0
- package/hooks/subagent-verifier.mjs +5 -4
- package/hub/account-broker.mjs +256 -60
- package/hub/adaptive-diagnostic.mjs +75 -48
- package/hub/adaptive-inject.mjs +96 -58
- package/hub/adaptive-memory.mjs +156 -42
- package/hub/adaptive.mjs +60 -31
- package/hub/assign-callbacks.mjs +163 -126
- package/hub/bridge.mjs +0 -1
- package/hub/cli-adapter-base.mjs +200 -48
- package/hub/codex-adapter.mjs +76 -96
- package/hub/codex-compat.mjs +3 -3
- package/hub/codex-preflight.mjs +63 -37
- package/hub/delegator/contracts.mjs +19 -23
- package/hub/delegator/index.mjs +14 -14
- package/hub/delegator/service.mjs +88 -64
- package/hub/delegator/tool-definitions.mjs +35 -35
- package/hub/fullcycle.mjs +33 -17
- package/hub/gemini-adapter.mjs +69 -94
- package/hub/hitl.mjs +202 -143
- package/hub/intent.mjs +161 -38
- package/hub/lib/cache-guard.mjs +43 -17
- package/hub/lib/mcp-response-cache.mjs +66 -32
- package/hub/lib/memory-store.mjs +285 -111
- package/hub/lib/path-utils.mjs +35 -37
- package/hub/lib/process-utils.mjs +106 -37
- package/hub/lib/spawn-trace.mjs +527 -0
- package/hub/lib/ssh-command.mjs +34 -4
- package/hub/lib/ssh-retry.mjs +5 -1
- package/hub/lib/uuidv7.mjs +4 -3
- package/hub/memory-doctor.mjs +266 -106
- package/hub/middleware/request-logger.mjs +61 -34
- package/hub/paths.mjs +9 -9
- package/hub/pipeline/gates/confidence.mjs +34 -15
- package/hub/pipeline/gates/consensus.mjs +27 -15
- package/hub/pipeline/gates/index.mjs +7 -3
- package/hub/pipeline/gates/selfcheck.mjs +57 -19
- package/hub/pipeline/index.mjs +77 -42
- package/hub/pipeline/state.mjs +10 -10
- package/hub/pipeline/transitions.mjs +40 -23
- package/hub/platform.mjs +57 -48
- package/hub/promote-penalties.mjs +25 -7
- package/hub/quality/deslop.mjs +70 -49
- package/hub/research.mjs +32 -25
- package/hub/router.mjs +924 -791
- package/hub/routing/complexity.mjs +132 -29
- package/hub/routing/index.mjs +17 -12
- package/hub/routing/q-learning.mjs +76 -28
- package/hub/server.mjs +4 -4
- package/hub/session-fingerprint.mjs +127 -61
- package/hub/state.mjs +84 -43
- package/hub/store-adapter.mjs +59 -26
- package/hub/store.mjs +356 -153
- package/hub/team/agent-map.json +22 -7
- package/hub/team/ansi.mjs +186 -122
- package/hub/team/backend.mjs +28 -10
- package/hub/team/cli/commands/attach.mjs +57 -37
- package/hub/team/cli/commands/control.mjs +29 -8
- package/hub/team/cli/commands/debug.mjs +95 -74
- package/hub/team/cli/commands/focus.mjs +80 -53
- package/hub/team/cli/commands/interrupt.mjs +18 -6
- package/hub/team/cli/commands/kill.mjs +16 -5
- package/hub/team/cli/commands/list.mjs +31 -24
- package/hub/team/cli/commands/send.mjs +19 -6
- package/hub/team/cli/commands/start/index.mjs +154 -31
- package/hub/team/cli/commands/start/parse-args.mjs +38 -11
- package/hub/team/cli/commands/start/start-headless.mjs +112 -36
- package/hub/team/cli/commands/start/start-in-process.mjs +50 -40
- package/hub/team/cli/commands/start/start-mux.mjs +122 -73
- package/hub/team/cli/commands/start/start-wt.mjs +86 -69
- package/hub/team/cli/commands/status.mjs +43 -14
- package/hub/team/cli/commands/stop.mjs +11 -4
- package/hub/team/cli/commands/task.mjs +8 -3
- package/hub/team/cli/commands/tasks.mjs +13 -13
- package/hub/team/cli/index.mjs +2 -2
- package/hub/team/cli/manifest.mjs +38 -8
- package/hub/team/cli/render.mjs +52 -30
- package/hub/team/cli/services/attach-fallback.mjs +74 -54
- package/hub/team/cli/services/hub-client.mjs +42 -14
- package/hub/team/cli/services/member-selector.mjs +37 -30
- package/hub/team/cli/services/native-control.mjs +143 -116
- package/hub/team/cli/services/runtime-mode.mjs +2 -1
- package/hub/team/cli/services/state-store.mjs +25 -8
- package/hub/team/cli/services/task-model.mjs +40 -30
- package/hub/team/conductor-mesh-bridge.mjs +24 -23
- package/hub/team/conductor.mjs +8 -4
- package/hub/team/dashboard-anchor.mjs +4 -5
- package/hub/team/dashboard-layout.mjs +3 -1
- package/hub/team/dashboard-open.mjs +41 -21
- package/hub/team/dashboard.mjs +76 -28
- package/hub/team/event-log.mjs +18 -10
- package/hub/team/handoff.mjs +31 -15
- package/hub/team/headless.mjs +2 -1
- package/hub/team/health-probe.mjs +69 -54
- package/hub/team/launcher-template.mjs +16 -13
- package/hub/team/native-supervisor.mjs +65 -21
- package/hub/team/native.mjs +74 -35
- package/hub/team/nativeProxy.mjs +184 -113
- package/hub/team/notify.mjs +120 -77
- package/hub/team/orchestrator.mjs +166 -161
- package/hub/team/pane.mjs +12 -7
- package/hub/team/process-cleanup.mjs +25 -16
- package/hub/team/psmux.mjs +491 -201
- package/hub/team/remote-probe.mjs +68 -52
- package/hub/team/remote-session.mjs +117 -59
- package/hub/team/remote-watcher.mjs +61 -33
- package/hub/team/routing.mjs +51 -25
- package/hub/team/runtime-strategy.mjs +3 -1
- package/hub/team/session.mjs +675 -611
- package/hub/team/shared.mjs +13 -13
- package/hub/team/staleState.mjs +72 -30
- package/hub/team/swarm-locks.mjs +15 -13
- package/hub/team/swarm-planner.mjs +32 -21
- package/hub/team/swarm-reconciler.mjs +48 -23
- package/hub/team/tui-lite.mjs +266 -68
- package/hub/team/tui-remote-adapter.mjs +14 -10
- package/hub/team/tui-viewer.mjs +99 -43
- package/hub/team/tui.mjs +708 -271
- package/hub/team/worktree-lifecycle.mjs +152 -58
- package/hub/team/wt-manager.mjs +24 -14
- package/hub/token-mode.mjs +71 -71
- package/hub/tray.mjs +411 -368
- package/hub/workers/claude-worker.mjs +162 -118
- package/hub/workers/codex-mcp.mjs +558 -507
- package/hub/workers/delegator-mcp.mjs +507 -333
- package/hub/workers/factory.mjs +21 -21
- package/hub/workers/gemini-worker.mjs +115 -84
- package/hub/workers/interface.mjs +6 -1
- package/hub/workers/worker-utils.mjs +21 -14
- package/hud/colors.mjs +27 -9
- package/hud/constants.mjs +162 -26
- package/hud/context-monitor.mjs +82 -41
- package/hud/hud-qos-status.mjs +129 -49
- package/hud/mission-board.mjs +6 -3
- package/hud/providers/claude.mjs +226 -115
- package/hud/providers/codex.mjs +62 -22
- package/hud/providers/gemini.mjs +168 -56
- package/hud/renderers.mjs +384 -119
- package/hud/terminal.mjs +101 -31
- package/hud/utils.mjs +78 -38
- package/mesh/index.mjs +11 -5
- package/mesh/mesh-budget.mjs +18 -9
- package/mesh/mesh-heartbeat.mjs +1 -1
- package/mesh/mesh-queue.mjs +3 -5
- package/mesh/mesh-router.mjs +5 -4
- package/package.json +56 -21
- package/scripts/__tests__/gen-skill-docs.test.mjs +36 -7
- package/scripts/__tests__/keyword-detector.test.mjs +77 -28
- package/scripts/__tests__/mcp-guard-engine.test.mjs +58 -20
- package/scripts/__tests__/remote-spawn-transfer.test.mjs +30 -19
- package/scripts/__tests__/remote-spawn.test.mjs +10 -4
- package/scripts/__tests__/session-start-fast.test.mjs +36 -0
- package/scripts/__tests__/skill-template.test.mjs +98 -50
- package/scripts/__tests__/smoke.test.mjs +1 -1
- package/scripts/__tests__/spawn-trace.test.mjs +102 -0
- package/scripts/__tests__/tfx-doctor-diagnose.test.mjs +48 -0
- package/scripts/cache-doctor.mjs +11 -4
- package/scripts/cache-warmup.mjs +96 -37
- package/scripts/claudemd-sync.mjs +27 -17
- package/scripts/codex-gateway-preflight.mjs +52 -37
- package/scripts/codex-mcp-gateway-sync.mjs +59 -39
- package/scripts/config-audit.mjs +232 -0
- package/scripts/convert-to-tmpl.mjs +54 -0
- package/scripts/cross-review-gate.mjs +35 -12
- package/scripts/cross-review-tracker.mjs +21 -8
- package/scripts/demo.mjs +35 -17
- package/scripts/doctor-diagnose.mjs +284 -0
- package/scripts/gen-skill-docs.mjs +7 -2
- package/scripts/gen-skill-manifest.mjs +2 -1
- package/scripts/headless-guard.mjs +86 -48
- package/scripts/hub-ensure.mjs +139 -120
- package/scripts/keyword-detector.mjs +293 -272
- package/scripts/keyword-rules-expander.mjs +538 -521
- package/scripts/lib/claudemd-scanner.mjs +6 -1
- package/scripts/lib/context.mjs +3 -3
- package/scripts/lib/cross-review-utils.mjs +6 -3
- package/scripts/lib/env-probe.mjs +47 -28
- package/scripts/lib/gemini-profiles.mjs +44 -10
- package/scripts/lib/handoff.mjs +33 -17
- package/scripts/lib/hook-utils.mjs +8 -6
- package/scripts/lib/keyword-rules.mjs +43 -19
- package/scripts/lib/logger.mjs +24 -24
- package/scripts/lib/mcp-filter.mjs +377 -239
- package/scripts/lib/mcp-guard-engine.mjs +194 -79
- package/scripts/lib/mcp-manifest.mjs +23 -13
- package/scripts/lib/mcp-server-catalog.mjs +355 -118
- package/scripts/lib/psmux-info.mjs +11 -6
- package/scripts/lib/remote-spawn-transfer.mjs +44 -14
- package/scripts/lib/skill-template.mjs +30 -7
- package/scripts/mcp-check.mjs +58 -39
- package/scripts/mcp-gateway-config.mjs +83 -39
- package/scripts/mcp-gateway-ensure.mjs +43 -35
- package/scripts/mcp-gateway-integration-test.mjs +70 -58
- package/scripts/mcp-gateway-start.mjs +126 -60
- package/scripts/mcp-gateway-verify.mjs +24 -22
- package/scripts/mcp-safety-guard.mjs +44 -11
- package/scripts/notion-read.mjs +669 -554
- package/scripts/pack.mjs +94 -89
- package/scripts/preflight-cache.mjs +27 -10
- package/scripts/preinstall.mjs +42 -13
- package/scripts/remote-spawn.mjs +309 -94
- package/scripts/run.cjs +8 -5
- package/scripts/session-spawn-helper.mjs +130 -39
- package/scripts/session-stale-cleanup.mjs +123 -0
- package/scripts/setup.mjs +941 -492
- package/scripts/test-lock.mjs +20 -7
- package/scripts/test-tfx-route-no-claude-native.mjs +61 -57
- package/scripts/tfx-batch-stats.mjs +117 -96
- package/scripts/tfx-gate-activate.mjs +11 -4
- package/scripts/tfx-route-post.mjs +87 -20
- package/scripts/tfx-route-worker.mjs +57 -51
- package/scripts/tfx-route.sh +41 -124
- package/scripts/tmp-cleanup.mjs +21 -7
- package/scripts/token-snapshot.mjs +204 -85
- package/skills/.omc/state/idle-notif-cooldown.json +1 -1
- package/skills/.omc/state/last-tool-error.json +1 -1
- package/skills/.omc/state/subagent-tracking.json +1 -1
- package/skills/_templates/base.md +1 -6
- package/skills/merge-worktree/SKILL.md.tmpl +144 -0
- package/skills/shared/telemetry-segment.md +6 -0
- package/skills/star-prompt/SKILL.md.tmpl +222 -0
- package/skills/tfx-analysis/SKILL.md.tmpl +107 -0
- package/skills/tfx-analysis/skill.json +1 -6
- package/skills/tfx-auto/SKILL.md +1 -0
- package/skills/{tfx-workspace/skill-snapshot/tfx-auto-codex/SKILL.md → tfx-auto-codex/SKILL.md.tmpl} +33 -4
- package/skills/tfx-auto-codex/skill.json +1 -3
- package/skills/tfx-autopilot/SKILL.md.tmpl +116 -0
- package/skills/tfx-autopilot/skill.json +1 -5
- package/skills/tfx-autoresearch/SKILL.md.tmpl +136 -0
- package/skills/tfx-autoroute/SKILL.md.tmpl +189 -0
- package/skills/tfx-autoroute/skill.json +1 -7
- package/skills/tfx-codex/SKILL.md +1 -0
- package/skills/tfx-codex/skill.json +1 -3
- package/skills/tfx-codex-swarm/SKILL.md.tmpl +16 -0
- package/skills/tfx-codex-swarm/evals/evals.json +1 -1
- package/skills/tfx-codex-swarm/skill.json +1 -4
- package/skills/tfx-codex-swarm-workspace/iteration-1/benchmark.json +54 -12
- package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/with_skill/grading.json +35 -7
- package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/without_skill/grading.json +35 -7
- package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/with_skill/grading.json +25 -5
- package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/without_skill/grading.json +25 -5
- package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/with_skill/grading.json +20 -4
- package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/without_skill/grading.json +16 -4
- package/skills/tfx-consensus/SKILL.md.tmpl +146 -0
- package/skills/tfx-debate/SKILL.md.tmpl +192 -0
- package/skills/tfx-debate/skill.json +1 -7
- package/skills/tfx-deep-analysis/SKILL.md.tmpl +228 -0
- package/skills/tfx-deep-analysis/skill.json +1 -5
- package/skills/tfx-deep-interview/SKILL.md.tmpl +203 -0
- package/skills/tfx-deep-plan/SKILL.md.tmpl +282 -0
- package/skills/tfx-deep-qa/SKILL.md.tmpl +165 -0
- package/skills/tfx-deep-qa/skill.json +1 -6
- package/skills/tfx-deep-research/SKILL.md.tmpl +217 -0
- package/skills/tfx-deep-review/SKILL.md.tmpl +179 -0
- package/skills/tfx-doctor/SKILL.md +21 -0
- package/skills/tfx-doctor/SKILL.md.tmpl +172 -0
- package/skills/tfx-doctor/skill.json +1 -3
- package/skills/tfx-find/SKILL.md +1 -0
- package/skills/tfx-forge/SKILL.md.tmpl +187 -0
- package/skills/tfx-fullcycle/SKILL.md.tmpl +286 -0
- package/skills/tfx-fullcycle/skill.json +1 -6
- package/skills/{tfx-workspace/skill-snapshot/tfx-gemini/SKILL.md → tfx-gemini/SKILL.md.tmpl} +16 -7
- package/skills/tfx-gemini/skill.json +1 -3
- package/skills/tfx-hooks/SKILL.md.tmpl +216 -0
- package/skills/tfx-hooks/skill.json +1 -3
- package/skills/tfx-hub/SKILL.md.tmpl +212 -0
- package/skills/tfx-hub/skill.json +1 -3
- package/skills/tfx-index/SKILL.md +1 -0
- package/skills/tfx-index/skill.json +1 -6
- package/skills/tfx-interview/SKILL.md.tmpl +285 -0
- package/skills/tfx-multi/SKILL.md.tmpl +183 -0
- package/skills/tfx-multi/skill.json +1 -3
- package/skills/tfx-panel/SKILL.md.tmpl +189 -0
- package/skills/tfx-panel/skill.json +1 -7
- package/skills/tfx-persist/SKILL.md.tmpl +270 -0
- package/skills/tfx-persist/skill.json +1 -7
- package/skills/tfx-plan/SKILL.md +1 -0
- package/skills/tfx-plan/skill.json +1 -6
- package/skills/tfx-profile/SKILL.md.tmpl +239 -0
- package/skills/tfx-profile/skill.json +1 -3
- package/skills/tfx-prune/SKILL.md.tmpl +200 -0
- package/skills/tfx-prune/skill.json +1 -7
- package/skills/tfx-psmux-rules/SKILL.md.tmpl +326 -0
- package/skills/tfx-psmux-rules/skill.json +1 -4
- package/skills/tfx-qa/SKILL.md +1 -0
- package/skills/tfx-qa/skill.json +1 -6
- package/skills/tfx-ralph/SKILL.md.tmpl +28 -0
- package/skills/tfx-ralph/skill.json +1 -4
- package/skills/tfx-remote-setup/SKILL.md.tmpl +576 -0
- package/skills/tfx-remote-setup/skill.json +1 -3
- package/skills/tfx-remote-spawn/SKILL.md.tmpl +263 -0
- package/skills/tfx-remote-spawn/references/hosts.json +16 -16
- package/skills/tfx-remote-spawn/skill.json +1 -4
- package/skills/tfx-research/SKILL.md +1 -0
- package/skills/tfx-review/SKILL.md +1 -0
- package/skills/tfx-review/skill.json +1 -6
- package/skills/tfx-setup/SKILL.md.tmpl +504 -0
- package/skills/tfx-setup/skill.json +1 -3
- package/skills/tfx-swarm/SKILL.md +22 -0
- package/skills/tfx-swarm/SKILL.md.tmpl +218 -0
- package/tui/codex-profile.mjs +457 -0
- package/tui/core.mjs +266 -0
- package/tui/doctor.mjs +375 -0
- package/tui/gemini-profile.mjs +299 -0
- package/tui/monitor-data.mjs +152 -0
- package/tui/monitor.mjs +339 -0
- package/tui/setup.mjs +533 -0
- package/CLAUDE.md +0 -193
- package/references/hosts.json +0 -33
- package/skills/tfx-workspace/async-tests/run-tests.sh +0 -203
- package/skills/tfx-workspace/evals/evals.json +0 -79
- package/skills/tfx-workspace/iteration-1/benchmark.json +0 -162
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/eval_metadata.json +0 -11
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/grading.json +0 -9
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/outputs/analysis.md +0 -154
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/grading.json +0 -9
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/outputs/analysis.md +0 -126
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/eval_metadata.json +0 -11
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/grading.json +0 -9
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/outputs/analysis.md +0 -119
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/grading.json +0 -9
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/outputs/analysis.md +0 -115
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/eval_metadata.json +0 -10
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/grading.json +0 -8
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/outputs/analysis.md +0 -86
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/grading.json +0 -8
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/outputs/analysis.md +0 -81
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/multi-team-creation/eval_metadata.json +0 -12
- package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/grading.json +0 -10
- package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/outputs/analysis.md +0 -316
- package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/grading.json +0 -10
- package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/outputs/analysis.md +0 -352
- package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/review.html +0 -1325
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/eval_metadata.json +0 -12
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/grading.json +0 -10
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/outputs/analysis.md +0 -97
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/grading.json +0 -10
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/outputs/analysis.md +0 -94
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/eval_metadata.json +0 -12
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/grading.json +0 -10
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/outputs/analysis.md +0 -209
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/grading.json +0 -10
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/outputs/analysis.md +0 -193
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-2/benchmark.json +0 -62
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/eval_metadata.json +0 -13
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/grading.json +0 -11
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/outputs/analysis.md +0 -382
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/grading.json +0 -11
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/outputs/analysis.md +0 -333
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-2/review.html +0 -1325
- package/skills/tfx-workspace/skill-snapshot/tfx-auto/SKILL.md +0 -217
- package/skills/tfx-workspace/skill-snapshot/tfx-codex/SKILL.md +0 -65
- package/skills/tfx-workspace/skill-snapshot/tfx-doctor/SKILL.md +0 -94
- package/skills/tfx-workspace/skill-snapshot/tfx-hub/SKILL.md +0 -133
- package/skills/tfx-workspace/skill-snapshot/tfx-multi/SKILL.md +0 -426
- package/skills/tfx-workspace/skill-snapshot/tfx-setup/SKILL.md +0 -101
package/hub/lib/memory-store.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// hub/lib/memory-store.mjs — In-memory store (SQLite-free fallback for @triflux/core)
|
|
2
|
-
|
|
3
|
-
import { recalcConfidence } from
|
|
2
|
+
|
|
3
|
+
import { recalcConfidence } from "../reflexion.mjs";
|
|
4
|
+
import { uuidv7 } from "./uuidv7.mjs";
|
|
4
5
|
|
|
5
6
|
export function clone(value) {
|
|
6
7
|
return value == null ? value : JSON.parse(JSON.stringify(value));
|
|
@@ -55,8 +56,8 @@ export function clampRetentionMs(value, fallback = 30 * 24 * 3600 * 1000) {
|
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
export function normalizeAdaptiveRuleIdentity(projectSlug, pattern) {
|
|
58
|
-
const normalizedProject = String(projectSlug ||
|
|
59
|
-
const normalizedPattern = String(pattern ||
|
|
59
|
+
const normalizedProject = String(projectSlug || "");
|
|
60
|
+
const normalizedPattern = String(pattern || "");
|
|
60
61
|
if (!normalizedProject || !normalizedPattern) return null;
|
|
61
62
|
return { project_slug: normalizedProject, pattern: normalizedPattern };
|
|
62
63
|
}
|
|
@@ -75,16 +76,19 @@ export function buildAdaptiveRuleRow({
|
|
|
75
76
|
const identity = normalizeAdaptiveRuleIdentity(project_slug, pattern);
|
|
76
77
|
if (!identity) return null;
|
|
77
78
|
const createdAt = coerceTimestamp(created_ms);
|
|
78
|
-
const lastSeenAt = Math.max(
|
|
79
|
+
const lastSeenAt = Math.max(
|
|
80
|
+
createdAt,
|
|
81
|
+
coerceTimestamp(last_seen_ms, createdAt),
|
|
82
|
+
);
|
|
79
83
|
return {
|
|
80
84
|
...identity,
|
|
81
85
|
confidence: clampConfidence(confidence, 0.5),
|
|
82
86
|
hit_count: clampHitCount(hit_count, 1),
|
|
83
87
|
last_seen_ms: lastSeenAt,
|
|
84
88
|
created_ms: createdAt,
|
|
85
|
-
error_message: typeof error_message ===
|
|
86
|
-
solution: typeof solution ===
|
|
87
|
-
context: typeof context ===
|
|
89
|
+
error_message: typeof error_message === "string" ? error_message : null,
|
|
90
|
+
solution: typeof solution === "string" ? solution : null,
|
|
91
|
+
context: typeof context === "string" ? context : null,
|
|
88
92
|
};
|
|
89
93
|
}
|
|
90
94
|
|
|
@@ -100,7 +104,7 @@ function buildAssignCallbackEvent(row) {
|
|
|
100
104
|
/**
|
|
101
105
|
* 인메모리 방식의 데이터 저장소를 생성합니다.
|
|
102
106
|
* SQLite를 사용할 수 없는 환경에서 폴백(fallback)으로 사용됩니다.
|
|
103
|
-
*
|
|
107
|
+
*
|
|
104
108
|
* @returns {object} 인메모리 스토어 객체
|
|
105
109
|
*/
|
|
106
110
|
export function createMemoryStore() {
|
|
@@ -120,12 +124,16 @@ export function createMemoryStore() {
|
|
|
120
124
|
function notifyAssignStatusListeners(row) {
|
|
121
125
|
const event = buildAssignCallbackEvent(row);
|
|
122
126
|
for (const listener of Array.from(assignStatusListeners)) {
|
|
123
|
-
try {
|
|
127
|
+
try {
|
|
128
|
+
listener(event, clone(row));
|
|
129
|
+
} catch {}
|
|
124
130
|
}
|
|
125
131
|
}
|
|
126
132
|
|
|
127
133
|
function getRecentMessages() {
|
|
128
|
-
return Array.from(messages.values()).sort(
|
|
134
|
+
return Array.from(messages.values()).sort(
|
|
135
|
+
(left, right) => right.created_at_ms - left.created_at_ms,
|
|
136
|
+
);
|
|
129
137
|
}
|
|
130
138
|
|
|
131
139
|
function upsertMessage(message) {
|
|
@@ -134,13 +142,21 @@ export function createMemoryStore() {
|
|
|
134
142
|
}
|
|
135
143
|
|
|
136
144
|
const store = {
|
|
137
|
-
type:
|
|
145
|
+
type: "memory",
|
|
138
146
|
db: null,
|
|
139
147
|
uuidv7,
|
|
140
148
|
|
|
141
149
|
close() {},
|
|
142
150
|
|
|
143
|
-
registerAgent({
|
|
151
|
+
registerAgent({
|
|
152
|
+
agent_id,
|
|
153
|
+
cli,
|
|
154
|
+
pid,
|
|
155
|
+
capabilities = [],
|
|
156
|
+
topics = [],
|
|
157
|
+
heartbeat_ttl_ms = 30000,
|
|
158
|
+
metadata = {},
|
|
159
|
+
}) {
|
|
144
160
|
const now = Date.now();
|
|
145
161
|
const current = agents.get(agent_id) || {};
|
|
146
162
|
const next = {
|
|
@@ -152,11 +168,16 @@ export function createMemoryStore() {
|
|
|
152
168
|
topics: clone(topics),
|
|
153
169
|
last_seen_ms: now,
|
|
154
170
|
lease_expires_ms: now + heartbeat_ttl_ms,
|
|
155
|
-
status:
|
|
171
|
+
status: "online",
|
|
156
172
|
metadata: clone(metadata),
|
|
157
173
|
};
|
|
158
174
|
agents.set(agent_id, next);
|
|
159
|
-
return {
|
|
175
|
+
return {
|
|
176
|
+
agent_id,
|
|
177
|
+
lease_id: uuidv7(),
|
|
178
|
+
lease_expires_ms: next.lease_expires_ms,
|
|
179
|
+
server_time_ms: now,
|
|
180
|
+
};
|
|
160
181
|
},
|
|
161
182
|
|
|
162
183
|
getAgent(id) {
|
|
@@ -165,12 +186,21 @@ export function createMemoryStore() {
|
|
|
165
186
|
|
|
166
187
|
refreshLease(agentId, ttlMs = 30000) {
|
|
167
188
|
const current = agents.get(agentId);
|
|
168
|
-
if (!current)
|
|
189
|
+
if (!current)
|
|
190
|
+
return {
|
|
191
|
+
agent_id: agentId,
|
|
192
|
+
lease_expires_ms: Date.now() + ttlMs,
|
|
193
|
+
server_time_ms: Date.now(),
|
|
194
|
+
};
|
|
169
195
|
const now = Date.now();
|
|
170
196
|
current.last_seen_ms = now;
|
|
171
197
|
current.lease_expires_ms = now + ttlMs;
|
|
172
|
-
current.status =
|
|
173
|
-
return {
|
|
198
|
+
current.status = "online";
|
|
199
|
+
return {
|
|
200
|
+
agent_id: agentId,
|
|
201
|
+
lease_expires_ms: current.lease_expires_ms,
|
|
202
|
+
server_time_ms: now,
|
|
203
|
+
};
|
|
174
204
|
},
|
|
175
205
|
|
|
176
206
|
updateAgentTopics(agentId, topics = []) {
|
|
@@ -183,7 +213,7 @@ export function createMemoryStore() {
|
|
|
183
213
|
|
|
184
214
|
listOnlineAgents() {
|
|
185
215
|
return Array.from(agents.values())
|
|
186
|
-
.filter((agent) => agent.status !==
|
|
216
|
+
.filter((agent) => agent.status !== "offline")
|
|
187
217
|
.map((agent) => clone(agent));
|
|
188
218
|
},
|
|
189
219
|
|
|
@@ -193,7 +223,12 @@ export function createMemoryStore() {
|
|
|
193
223
|
|
|
194
224
|
getAgentsByTopic(topic) {
|
|
195
225
|
return Array.from(agents.values())
|
|
196
|
-
.filter(
|
|
226
|
+
.filter(
|
|
227
|
+
(agent) =>
|
|
228
|
+
agent.status !== "offline" &&
|
|
229
|
+
Array.isArray(agent.topics) &&
|
|
230
|
+
agent.topics.includes(topic),
|
|
231
|
+
)
|
|
197
232
|
.map((agent) => clone(agent));
|
|
198
233
|
},
|
|
199
234
|
|
|
@@ -202,11 +237,14 @@ export function createMemoryStore() {
|
|
|
202
237
|
let stale = 0;
|
|
203
238
|
let offline = 0;
|
|
204
239
|
for (const agent of agents.values()) {
|
|
205
|
-
if (agent.status ===
|
|
206
|
-
agent.status =
|
|
240
|
+
if (agent.status === "online" && agent.lease_expires_ms < now) {
|
|
241
|
+
agent.status = "stale";
|
|
207
242
|
stale += 1;
|
|
208
|
-
} else if (
|
|
209
|
-
agent.status
|
|
243
|
+
} else if (
|
|
244
|
+
agent.status === "stale" &&
|
|
245
|
+
agent.lease_expires_ms < now - 300000
|
|
246
|
+
) {
|
|
247
|
+
agent.status = "offline";
|
|
210
248
|
offline += 1;
|
|
211
249
|
}
|
|
212
250
|
}
|
|
@@ -220,7 +258,18 @@ export function createMemoryStore() {
|
|
|
220
258
|
return true;
|
|
221
259
|
},
|
|
222
260
|
|
|
223
|
-
auditLog({
|
|
261
|
+
auditLog({
|
|
262
|
+
type,
|
|
263
|
+
from,
|
|
264
|
+
to,
|
|
265
|
+
topic,
|
|
266
|
+
priority = 5,
|
|
267
|
+
ttl_ms = 300000,
|
|
268
|
+
payload = {},
|
|
269
|
+
trace_id,
|
|
270
|
+
correlation_id,
|
|
271
|
+
status = "queued",
|
|
272
|
+
}) {
|
|
224
273
|
const now = Date.now();
|
|
225
274
|
const row = {
|
|
226
275
|
id: uuidv7(),
|
|
@@ -249,7 +298,12 @@ export function createMemoryStore() {
|
|
|
249
298
|
},
|
|
250
299
|
|
|
251
300
|
getResponseByCorrelation(cid) {
|
|
252
|
-
return
|
|
301
|
+
return (
|
|
302
|
+
getRecentMessages().find(
|
|
303
|
+
(message) =>
|
|
304
|
+
message.correlation_id === cid && message.type === "response",
|
|
305
|
+
) || null
|
|
306
|
+
);
|
|
253
307
|
},
|
|
254
308
|
|
|
255
309
|
getMessagesByTrace(tid) {
|
|
@@ -266,17 +320,23 @@ export function createMemoryStore() {
|
|
|
266
320
|
return true;
|
|
267
321
|
},
|
|
268
322
|
|
|
269
|
-
getAuditMessagesForAgent(
|
|
323
|
+
getAuditMessagesForAgent(
|
|
324
|
+
agentId,
|
|
325
|
+
{ max_messages = 20, include_topics = null } = {},
|
|
326
|
+
) {
|
|
270
327
|
const limit = clampMaxMessages(max_messages);
|
|
271
|
-
const topics =
|
|
272
|
-
|
|
273
|
-
|
|
328
|
+
const topics =
|
|
329
|
+
Array.isArray(include_topics) && include_topics.length
|
|
330
|
+
? include_topics
|
|
331
|
+
: agents.get(agentId)?.topics || [];
|
|
274
332
|
const topicSet = new Set(topics);
|
|
275
333
|
return getRecentMessages()
|
|
276
|
-
.filter(
|
|
277
|
-
message
|
|
278
|
-
|
|
279
|
-
|
|
334
|
+
.filter(
|
|
335
|
+
(message) =>
|
|
336
|
+
message.to_agent === agentId ||
|
|
337
|
+
(String(message.to_agent || "").startsWith("topic:") &&
|
|
338
|
+
topicSet.has(message.topic)),
|
|
339
|
+
)
|
|
280
340
|
.slice(0, limit)
|
|
281
341
|
.map((message) => clone(message));
|
|
282
342
|
},
|
|
@@ -291,14 +351,26 @@ export function createMemoryStore() {
|
|
|
291
351
|
},
|
|
292
352
|
|
|
293
353
|
pollForAgent(agentId, { max_messages = 20, include_topics = null } = {}) {
|
|
294
|
-
return store.getAuditMessagesForAgent(agentId, {
|
|
354
|
+
return store.getAuditMessagesForAgent(agentId, {
|
|
355
|
+
max_messages,
|
|
356
|
+
include_topics,
|
|
357
|
+
});
|
|
295
358
|
},
|
|
296
359
|
|
|
297
360
|
ackMessages() {
|
|
298
361
|
return 0;
|
|
299
362
|
},
|
|
300
363
|
|
|
301
|
-
insertHumanRequest({
|
|
364
|
+
insertHumanRequest({
|
|
365
|
+
requester_agent,
|
|
366
|
+
kind,
|
|
367
|
+
prompt,
|
|
368
|
+
requested_schema = {},
|
|
369
|
+
deadline_ms,
|
|
370
|
+
default_action,
|
|
371
|
+
correlation_id,
|
|
372
|
+
trace_id,
|
|
373
|
+
}) {
|
|
302
374
|
const requestId = uuidv7();
|
|
303
375
|
const now = Date.now();
|
|
304
376
|
const row = {
|
|
@@ -307,7 +379,7 @@ export function createMemoryStore() {
|
|
|
307
379
|
kind,
|
|
308
380
|
prompt,
|
|
309
381
|
schema: clone(requested_schema),
|
|
310
|
-
state:
|
|
382
|
+
state: "pending",
|
|
311
383
|
deadline_ms: now + deadline_ms,
|
|
312
384
|
default_action,
|
|
313
385
|
correlation_id: correlation_id || uuidv7(),
|
|
@@ -315,7 +387,11 @@ export function createMemoryStore() {
|
|
|
315
387
|
response: null,
|
|
316
388
|
};
|
|
317
389
|
humanRequests.set(requestId, row);
|
|
318
|
-
return {
|
|
390
|
+
return {
|
|
391
|
+
request_id: requestId,
|
|
392
|
+
state: "pending",
|
|
393
|
+
deadline_ms: row.deadline_ms,
|
|
394
|
+
};
|
|
319
395
|
},
|
|
320
396
|
|
|
321
397
|
getHumanRequest(id) {
|
|
@@ -332,7 +408,7 @@ export function createMemoryStore() {
|
|
|
332
408
|
|
|
333
409
|
getPendingHumanRequests() {
|
|
334
410
|
return Array.from(humanRequests.values())
|
|
335
|
-
.filter((request) => request.state ===
|
|
411
|
+
.filter((request) => request.state === "pending")
|
|
336
412
|
.map((request) => clone(request));
|
|
337
413
|
},
|
|
338
414
|
|
|
@@ -340,8 +416,8 @@ export function createMemoryStore() {
|
|
|
340
416
|
let changed = 0;
|
|
341
417
|
const now = Date.now();
|
|
342
418
|
for (const request of humanRequests.values()) {
|
|
343
|
-
if (request.state ===
|
|
344
|
-
request.state =
|
|
419
|
+
if (request.state === "pending" && request.deadline_ms < now) {
|
|
420
|
+
request.state = "timed_out";
|
|
345
421
|
changed += 1;
|
|
346
422
|
}
|
|
347
423
|
}
|
|
@@ -350,7 +426,7 @@ export function createMemoryStore() {
|
|
|
350
426
|
|
|
351
427
|
moveToDeadLetter(messageId, reason, lastError = null) {
|
|
352
428
|
const current = messages.get(messageId);
|
|
353
|
-
if (current) current.status =
|
|
429
|
+
if (current) current.status = "dead_letter";
|
|
354
430
|
deadLetters.set(messageId, {
|
|
355
431
|
message_id: messageId,
|
|
356
432
|
reason,
|
|
@@ -371,10 +447,10 @@ export function createMemoryStore() {
|
|
|
371
447
|
job_id,
|
|
372
448
|
supervisor_agent,
|
|
373
449
|
worker_agent,
|
|
374
|
-
topic =
|
|
375
|
-
task =
|
|
450
|
+
topic = "assign.job",
|
|
451
|
+
task = "",
|
|
376
452
|
payload = {},
|
|
377
|
-
status =
|
|
453
|
+
status = "queued",
|
|
378
454
|
attempt = 1,
|
|
379
455
|
retry_count = 0,
|
|
380
456
|
max_retries = 0,
|
|
@@ -394,8 +470,8 @@ export function createMemoryStore() {
|
|
|
394
470
|
job_id: job_id || uuidv7(),
|
|
395
471
|
supervisor_agent,
|
|
396
472
|
worker_agent,
|
|
397
|
-
topic: String(topic ||
|
|
398
|
-
task: String(task ||
|
|
473
|
+
topic: String(topic || "assign.job"),
|
|
474
|
+
task: String(task || ""),
|
|
399
475
|
payload: clone(payload || {}),
|
|
400
476
|
status,
|
|
401
477
|
attempt: Math.max(1, Number(attempt) || 1),
|
|
@@ -414,8 +490,10 @@ export function createMemoryStore() {
|
|
|
414
490
|
error: error == null ? null : clone(error),
|
|
415
491
|
created_at_ms: now,
|
|
416
492
|
updated_at_ms: now,
|
|
417
|
-
started_at_ms: status ===
|
|
418
|
-
completed_at_ms: [
|
|
493
|
+
started_at_ms: status === "running" ? now : null,
|
|
494
|
+
completed_at_ms: ["succeeded", "failed", "timed_out"].includes(status)
|
|
495
|
+
? now
|
|
496
|
+
: null,
|
|
419
497
|
last_retry_at_ms: retry_count > 0 ? now : null,
|
|
420
498
|
};
|
|
421
499
|
assignJobs.set(row.job_id, row);
|
|
@@ -434,8 +512,13 @@ export function createMemoryStore() {
|
|
|
434
512
|
const snapshot = clone(current);
|
|
435
513
|
const now = Date.now();
|
|
436
514
|
const nextStatus = status || current.status;
|
|
437
|
-
const isTerminal = [
|
|
438
|
-
|
|
515
|
+
const isTerminal = ["succeeded", "failed", "timed_out"].includes(
|
|
516
|
+
nextStatus,
|
|
517
|
+
);
|
|
518
|
+
const nextTimeout = clampDuration(
|
|
519
|
+
patch.timeout_ms ?? current.timeout_ms,
|
|
520
|
+
current.timeout_ms,
|
|
521
|
+
);
|
|
439
522
|
const nextRow = {
|
|
440
523
|
...current,
|
|
441
524
|
supervisor_agent: patch.supervisor_agent ?? current.supervisor_agent,
|
|
@@ -444,39 +527,65 @@ export function createMemoryStore() {
|
|
|
444
527
|
task: patch.task ?? current.task,
|
|
445
528
|
payload: clone(patch.payload ?? current.payload ?? {}),
|
|
446
529
|
status: nextStatus,
|
|
447
|
-
attempt: Math.max(
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
530
|
+
attempt: Math.max(
|
|
531
|
+
1,
|
|
532
|
+
Number(patch.attempt ?? current.attempt) || current.attempt || 1,
|
|
533
|
+
),
|
|
534
|
+
retry_count: Math.max(
|
|
535
|
+
0,
|
|
536
|
+
Number(patch.retry_count ?? current.retry_count) || 0,
|
|
537
|
+
),
|
|
538
|
+
max_retries: Math.max(
|
|
539
|
+
0,
|
|
540
|
+
Number(patch.max_retries ?? current.max_retries) || 0,
|
|
541
|
+
),
|
|
542
|
+
priority: clampPriority(
|
|
543
|
+
patch.priority ?? current.priority,
|
|
544
|
+
current.priority || 5,
|
|
545
|
+
),
|
|
546
|
+
ttl_ms: clampDuration(
|
|
547
|
+
patch.ttl_ms ?? current.ttl_ms,
|
|
548
|
+
current.ttl_ms || nextTimeout,
|
|
549
|
+
),
|
|
452
550
|
timeout_ms: nextTimeout,
|
|
453
551
|
deadline_ms: (() => {
|
|
454
|
-
if (Object.hasOwn(patch,
|
|
455
|
-
return patch.deadline_ms == null
|
|
552
|
+
if (Object.hasOwn(patch, "deadline_ms")) {
|
|
553
|
+
return patch.deadline_ms == null
|
|
554
|
+
? null
|
|
555
|
+
: Math.trunc(Number(patch.deadline_ms));
|
|
456
556
|
}
|
|
457
557
|
if (isTerminal) return null;
|
|
458
|
-
if (nextStatus ===
|
|
558
|
+
if (nextStatus === "running" && !current.deadline_ms)
|
|
559
|
+
return now + nextTimeout;
|
|
459
560
|
return current.deadline_ms;
|
|
460
561
|
})(),
|
|
461
562
|
trace_id: patch.trace_id ?? current.trace_id,
|
|
462
563
|
correlation_id: patch.correlation_id ?? current.correlation_id,
|
|
463
|
-
last_message_id: Object.hasOwn(patch,
|
|
564
|
+
last_message_id: Object.hasOwn(patch, "last_message_id")
|
|
464
565
|
? patch.last_message_id
|
|
465
566
|
: current.last_message_id,
|
|
466
|
-
result: Object.hasOwn(patch,
|
|
467
|
-
?
|
|
567
|
+
result: Object.hasOwn(patch, "result")
|
|
568
|
+
? patch.result == null
|
|
569
|
+
? null
|
|
570
|
+
: clone(patch.result)
|
|
468
571
|
: current.result,
|
|
469
|
-
error: Object.hasOwn(patch,
|
|
470
|
-
?
|
|
572
|
+
error: Object.hasOwn(patch, "error")
|
|
573
|
+
? patch.error == null
|
|
574
|
+
? null
|
|
575
|
+
: clone(patch.error)
|
|
471
576
|
: current.error,
|
|
472
577
|
updated_at_ms: now,
|
|
473
|
-
started_at_ms: Object.hasOwn(patch,
|
|
578
|
+
started_at_ms: Object.hasOwn(patch, "started_at_ms")
|
|
474
579
|
? patch.started_at_ms
|
|
475
|
-
:
|
|
476
|
-
|
|
580
|
+
: nextStatus === "running"
|
|
581
|
+
? current.started_at_ms || now
|
|
582
|
+
: current.started_at_ms,
|
|
583
|
+
completed_at_ms: Object.hasOwn(patch, "completed_at_ms")
|
|
477
584
|
? patch.completed_at_ms
|
|
478
|
-
:
|
|
479
|
-
|
|
585
|
+
: isTerminal
|
|
586
|
+
? current.completed_at_ms || now
|
|
587
|
+
: current.completed_at_ms,
|
|
588
|
+
last_retry_at_ms: Object.hasOwn(patch, "last_retry_at_ms")
|
|
480
589
|
? patch.last_retry_at_ms
|
|
481
590
|
: current.last_retry_at_ms,
|
|
482
591
|
};
|
|
@@ -497,17 +606,29 @@ export function createMemoryStore() {
|
|
|
497
606
|
active_before_ms,
|
|
498
607
|
limit = 50,
|
|
499
608
|
} = {}) {
|
|
500
|
-
const statusList =
|
|
501
|
-
|
|
502
|
-
|
|
609
|
+
const statusList =
|
|
610
|
+
Array.isArray(statuses) && statuses.length
|
|
611
|
+
? statuses
|
|
612
|
+
: status
|
|
613
|
+
? [status]
|
|
614
|
+
: [];
|
|
503
615
|
return Array.from(assignJobs.values())
|
|
504
|
-
.filter(
|
|
616
|
+
.filter(
|
|
617
|
+
(job) =>
|
|
618
|
+
!supervisor_agent || job.supervisor_agent === supervisor_agent,
|
|
619
|
+
)
|
|
505
620
|
.filter((job) => !worker_agent || job.worker_agent === worker_agent)
|
|
506
621
|
.filter((job) => !trace_id || job.trace_id === trace_id)
|
|
507
|
-
.filter(
|
|
622
|
+
.filter(
|
|
623
|
+
(job) => !correlation_id || job.correlation_id === correlation_id,
|
|
624
|
+
)
|
|
508
625
|
.filter((job) => !statusList.length || statusList.includes(job.status))
|
|
509
|
-
.filter(
|
|
510
|
-
|
|
626
|
+
.filter(
|
|
627
|
+
(job) =>
|
|
628
|
+
!Number.isFinite(Number(active_before_ms)) ||
|
|
629
|
+
(job.deadline_ms != null &&
|
|
630
|
+
job.deadline_ms <= Number(active_before_ms)),
|
|
631
|
+
)
|
|
511
632
|
.sort((left, right) => right.updated_at_ms - left.updated_at_ms)
|
|
512
633
|
.slice(0, clampMaxMessages(limit, 50))
|
|
513
634
|
.map((job) => clone(job));
|
|
@@ -516,10 +637,19 @@ export function createMemoryStore() {
|
|
|
516
637
|
retryAssign(jobId, patch = {}) {
|
|
517
638
|
const current = assignJobs.get(jobId);
|
|
518
639
|
if (!current) return null;
|
|
519
|
-
const nextRetryCount = Math.max(
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
640
|
+
const nextRetryCount = Math.max(
|
|
641
|
+
0,
|
|
642
|
+
Number(patch.retry_count ?? current.retry_count + 1) || 0,
|
|
643
|
+
);
|
|
644
|
+
const nextAttempt = Math.max(
|
|
645
|
+
current.attempt + 1,
|
|
646
|
+
Number(patch.attempt ?? current.attempt + 1) || 1,
|
|
647
|
+
);
|
|
648
|
+
const nextTimeout = clampDuration(
|
|
649
|
+
patch.timeout_ms ?? current.timeout_ms,
|
|
650
|
+
current.timeout_ms,
|
|
651
|
+
);
|
|
652
|
+
return store.updateAssignStatus(jobId, "queued", {
|
|
523
653
|
retry_count: nextRetryCount,
|
|
524
654
|
attempt: nextAttempt,
|
|
525
655
|
timeout_ms: nextTimeout,
|
|
@@ -529,7 +659,7 @@ export function createMemoryStore() {
|
|
|
529
659
|
started_at_ms: null,
|
|
530
660
|
last_retry_at_ms: Date.now(),
|
|
531
661
|
result: patch.result ?? null,
|
|
532
|
-
error: Object.hasOwn(patch,
|
|
662
|
+
error: Object.hasOwn(patch, "error") ? patch.error : current.error,
|
|
533
663
|
last_message_id: null,
|
|
534
664
|
});
|
|
535
665
|
},
|
|
@@ -538,11 +668,11 @@ export function createMemoryStore() {
|
|
|
538
668
|
const now = Date.now();
|
|
539
669
|
let expiredMessages = 0;
|
|
540
670
|
for (const message of messages.values()) {
|
|
541
|
-
if (message.status ===
|
|
542
|
-
message.status =
|
|
671
|
+
if (message.status === "queued" && message.expires_at_ms < now) {
|
|
672
|
+
message.status = "dead_letter";
|
|
543
673
|
deadLetters.set(message.id, {
|
|
544
674
|
message_id: message.id,
|
|
545
|
-
reason:
|
|
675
|
+
reason: "ttl_expired",
|
|
546
676
|
failed_at_ms: now,
|
|
547
677
|
last_error: null,
|
|
548
678
|
});
|
|
@@ -550,14 +680,18 @@ export function createMemoryStore() {
|
|
|
550
680
|
}
|
|
551
681
|
}
|
|
552
682
|
const humanRequestsExpired = store.expireHumanRequests();
|
|
553
|
-
return {
|
|
683
|
+
return {
|
|
684
|
+
messages: expiredMessages,
|
|
685
|
+
human_requests: humanRequestsExpired,
|
|
686
|
+
};
|
|
554
687
|
},
|
|
555
688
|
|
|
556
689
|
getQueueDepths() {
|
|
557
690
|
const depths = { urgent: 0, normal: 0, dlq: deadLetters.size };
|
|
558
691
|
const now = Date.now();
|
|
559
692
|
for (const message of messages.values()) {
|
|
560
|
-
if (message.status !==
|
|
693
|
+
if (message.status !== "queued" || message.expires_at_ms < now)
|
|
694
|
+
continue;
|
|
561
695
|
if (message.priority >= 7) depths.urgent += 1;
|
|
562
696
|
else depths.normal += 1;
|
|
563
697
|
}
|
|
@@ -565,7 +699,7 @@ export function createMemoryStore() {
|
|
|
565
699
|
},
|
|
566
700
|
|
|
567
701
|
onAssignStatusChange(listener) {
|
|
568
|
-
if (typeof listener !==
|
|
702
|
+
if (typeof listener !== "function") {
|
|
569
703
|
return () => {};
|
|
570
704
|
}
|
|
571
705
|
assignStatusListeners.add(listener);
|
|
@@ -574,36 +708,46 @@ export function createMemoryStore() {
|
|
|
574
708
|
|
|
575
709
|
getDeliveryStats() {
|
|
576
710
|
const cutoff = Date.now() - 300000;
|
|
577
|
-
const totalDeliveries = Array.from(messages.values())
|
|
578
|
-
|
|
579
|
-
|
|
711
|
+
const totalDeliveries = Array.from(messages.values()).filter(
|
|
712
|
+
(message) =>
|
|
713
|
+
message.status === "acked" && message.created_at_ms > cutoff,
|
|
714
|
+
).length;
|
|
580
715
|
return { total_deliveries: totalDeliveries, avg_delivery_ms: 0 };
|
|
581
716
|
},
|
|
582
717
|
|
|
583
718
|
getHubStats() {
|
|
584
719
|
return {
|
|
585
|
-
online_agents: Array.from(agents.values()).filter(
|
|
720
|
+
online_agents: Array.from(agents.values()).filter(
|
|
721
|
+
(agent) => agent.status === "online",
|
|
722
|
+
).length,
|
|
586
723
|
total_messages: messages.size,
|
|
587
|
-
active_assign_jobs: Array.from(assignJobs.values()).filter((job) =>
|
|
724
|
+
active_assign_jobs: Array.from(assignJobs.values()).filter((job) =>
|
|
725
|
+
["queued", "running"].includes(job.status),
|
|
726
|
+
).length,
|
|
588
727
|
...store.getQueueDepths(),
|
|
589
728
|
};
|
|
590
729
|
},
|
|
591
730
|
|
|
592
731
|
getAuditStats() {
|
|
593
|
-
const countByStatus = (targetStatus) =>
|
|
732
|
+
const countByStatus = (targetStatus) =>
|
|
733
|
+
Array.from(assignJobs.values()).filter(
|
|
734
|
+
(job) => job.status === targetStatus,
|
|
735
|
+
).length;
|
|
594
736
|
return {
|
|
595
|
-
online_agents: Array.from(agents.values()).filter(
|
|
737
|
+
online_agents: Array.from(agents.values()).filter(
|
|
738
|
+
(agent) => agent.status === "online",
|
|
739
|
+
).length,
|
|
596
740
|
total_messages: messages.size,
|
|
597
741
|
dlq: deadLetters.size,
|
|
598
|
-
assign_queued: countByStatus(
|
|
599
|
-
assign_running: countByStatus(
|
|
600
|
-
assign_failed: countByStatus(
|
|
601
|
-
assign_timed_out: countByStatus(
|
|
742
|
+
assign_queued: countByStatus("queued"),
|
|
743
|
+
assign_running: countByStatus("running"),
|
|
744
|
+
assign_failed: countByStatus("failed"),
|
|
745
|
+
assign_timed_out: countByStatus("timed_out"),
|
|
602
746
|
};
|
|
603
747
|
},
|
|
604
748
|
|
|
605
749
|
addReflexion({
|
|
606
|
-
type =
|
|
750
|
+
type = "reflexion",
|
|
607
751
|
error_pattern,
|
|
608
752
|
error_message,
|
|
609
753
|
context = {},
|
|
@@ -644,8 +788,17 @@ export function createMemoryStore() {
|
|
|
644
788
|
|
|
645
789
|
findReflexion(errorPattern, context = {}) {
|
|
646
790
|
const entries = Array.from(reflexionEntries.values())
|
|
647
|
-
.filter(
|
|
648
|
-
|
|
791
|
+
.filter(
|
|
792
|
+
(entry) =>
|
|
793
|
+
entry.error_pattern === errorPattern ||
|
|
794
|
+
entry.error_pattern.includes(errorPattern) ||
|
|
795
|
+
errorPattern.includes(entry.error_pattern),
|
|
796
|
+
)
|
|
797
|
+
.filter((entry) =>
|
|
798
|
+
Object.entries(context).every(
|
|
799
|
+
([key, value]) => value == null || entry.context?.[key] === value,
|
|
800
|
+
),
|
|
801
|
+
)
|
|
649
802
|
.sort((left, right) => right.confidence - left.confidence);
|
|
650
803
|
return entries.map((entry) => clone(entry));
|
|
651
804
|
},
|
|
@@ -663,11 +816,18 @@ export function createMemoryStore() {
|
|
|
663
816
|
},
|
|
664
817
|
|
|
665
818
|
listReflexion(filters = {}) {
|
|
666
|
-
const {
|
|
819
|
+
const {
|
|
820
|
+
type,
|
|
821
|
+
minConfidence = Number.NEGATIVE_INFINITY,
|
|
822
|
+
projectSlug,
|
|
823
|
+
} = filters;
|
|
667
824
|
return Array.from(reflexionEntries.values())
|
|
668
825
|
.filter((entry) => !type || entry.type === type)
|
|
669
826
|
.filter((entry) => entry.confidence >= minConfidence)
|
|
670
|
-
.filter(
|
|
827
|
+
.filter(
|
|
828
|
+
(entry) =>
|
|
829
|
+
!projectSlug || entry.adaptive_state?.project_slug === projectSlug,
|
|
830
|
+
)
|
|
671
831
|
.sort((left, right) => right.confidence - left.confidence)
|
|
672
832
|
.map((entry) => clone(entry));
|
|
673
833
|
},
|
|
@@ -679,7 +839,9 @@ export function createMemoryStore() {
|
|
|
679
839
|
...current,
|
|
680
840
|
...clone(patch),
|
|
681
841
|
context: patch.context ? clone(patch.context) : current.context,
|
|
682
|
-
adaptive_state: patch.adaptive_state
|
|
842
|
+
adaptive_state: patch.adaptive_state
|
|
843
|
+
? clone(patch.adaptive_state)
|
|
844
|
+
: current.adaptive_state,
|
|
683
845
|
updated_at_ms: patch.updated_at_ms ?? Date.now(),
|
|
684
846
|
};
|
|
685
847
|
reflexionEntries.set(id, next);
|
|
@@ -709,7 +871,9 @@ export function createMemoryStore() {
|
|
|
709
871
|
const current = adaptiveRules.get(key);
|
|
710
872
|
adaptiveRules.set(key, {
|
|
711
873
|
...next,
|
|
712
|
-
created_ms: current
|
|
874
|
+
created_ms: current
|
|
875
|
+
? Math.min(current.created_ms, next.created_ms)
|
|
876
|
+
: next.created_ms,
|
|
713
877
|
});
|
|
714
878
|
return clone(adaptiveRules.get(key));
|
|
715
879
|
},
|
|
@@ -717,7 +881,11 @@ export function createMemoryStore() {
|
|
|
717
881
|
findAdaptiveRule(projectSlug, pattern) {
|
|
718
882
|
const identity = normalizeAdaptiveRuleIdentity(projectSlug, pattern);
|
|
719
883
|
if (!identity) return null;
|
|
720
|
-
return clone(
|
|
884
|
+
return clone(
|
|
885
|
+
adaptiveRules.get(
|
|
886
|
+
getAdaptiveRuleKey(identity.project_slug, identity.pattern),
|
|
887
|
+
) || null,
|
|
888
|
+
);
|
|
721
889
|
},
|
|
722
890
|
|
|
723
891
|
updateRuleConfidence(projectSlug, pattern, confidence, options = {}) {
|
|
@@ -726,18 +894,23 @@ export function createMemoryStore() {
|
|
|
726
894
|
const next = {
|
|
727
895
|
...current,
|
|
728
896
|
confidence: clampConfidence(confidence, current.confidence),
|
|
729
|
-
hit_count:
|
|
897
|
+
hit_count:
|
|
898
|
+
current.hit_count + clampHitIncrement(options.hit_count_increment, 1),
|
|
730
899
|
last_seen_ms: Math.max(
|
|
731
900
|
current.last_seen_ms,
|
|
732
901
|
coerceTimestamp(options.last_seen_ms, Date.now()),
|
|
733
902
|
),
|
|
734
903
|
};
|
|
735
|
-
adaptiveRules.set(
|
|
904
|
+
adaptiveRules.set(
|
|
905
|
+
getAdaptiveRuleKey(current.project_slug, current.pattern),
|
|
906
|
+
next,
|
|
907
|
+
);
|
|
736
908
|
return clone(next);
|
|
737
909
|
},
|
|
738
910
|
|
|
739
911
|
pruneStaleRules(maxAge_ms = 30 * 24 * 3600 * 1000, minConfidence = 0.2) {
|
|
740
|
-
const cutoff =
|
|
912
|
+
const cutoff =
|
|
913
|
+
Date.now() - clampRetentionMs(maxAge_ms, 30 * 24 * 3600 * 1000);
|
|
741
914
|
let removed = 0;
|
|
742
915
|
for (const [key, rule] of Array.from(adaptiveRules.entries())) {
|
|
743
916
|
if (rule.last_seen_ms < cutoff && rule.confidence < minConfidence) {
|
|
@@ -761,10 +934,11 @@ export function createMemoryStore() {
|
|
|
761
934
|
deleteAdaptiveRule(projectSlug, pattern) {
|
|
762
935
|
const identity = normalizeAdaptiveRuleIdentity(projectSlug, pattern);
|
|
763
936
|
if (!identity) return false;
|
|
764
|
-
return adaptiveRules.delete(
|
|
937
|
+
return adaptiveRules.delete(
|
|
938
|
+
getAdaptiveRuleKey(identity.project_slug, identity.pattern),
|
|
939
|
+
);
|
|
765
940
|
},
|
|
766
941
|
};
|
|
767
942
|
|
|
768
943
|
return store;
|
|
769
944
|
}
|
|
770
|
-
|