mcp-efficiency-engine 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/.githooks/post-commit +20 -0
  2. package/.github/workflows/autodocs-sync.yml +2 -15
  3. package/.github/workflows/release-npm.yml +111 -0
  4. package/FINAL_USAGE_GUIDE.md +78 -0
  5. package/README.md +231 -0
  6. package/autodocs/README.md +6 -0
  7. package/bin/install-host.js +26 -1
  8. package/observability/metrics.md +33 -0
  9. package/observability/scoring-rubric.md +20 -0
  10. package/orchestrator/wiki/graph_consolidator.py +60 -1
  11. package/orchestrator/wiki/incremental_engine.py +23 -1
  12. package/orchestrator/wiki/plugin_manager.py +87 -22
  13. package/package.json +10 -2
  14. package/requirements.txt +2 -0
  15. package/scripts/intake/resolve-routing.py +124 -87
  16. package/scripts/intake/validate-database-routing.py +13 -4
  17. package/scripts/intake/validate-rag-routing.py +4 -3
  18. package/scripts/learning/learning-loop-report.py +28 -10
  19. package/scripts/ops/bye.ps1 +30 -0
  20. package/scripts/ops/hi.ps1 +13 -0
  21. package/scripts/ops/llm-token-probe.py +103 -39
  22. package/scripts/ops/post-commit-refresh.ps1 +110 -0
  23. package/scripts/ops/publish-langsmith-kpis.py +302 -0
  24. package/scripts/ops/telemetry-benchmark.py +184 -0
  25. package/scripts/setup/install-project-hooks.ps1 +33 -0
  26. package/scripts/setup/setup-prerequisites.ps1 +42 -15
  27. package/scripts/wiki/compiler_main.py +108 -76
  28. package/scripts/wiki/providers/repo_content_provider.py +51 -0
  29. package/scripts/wiki/validator.py +40 -15
  30. package/telemetry/__init__.py +4 -0
  31. package/telemetry/bootstrap.py +47 -0
  32. package/telemetry/collector/engine.py +261 -0
  33. package/telemetry/config.json +20 -0
  34. package/telemetry/config.py +131 -0
  35. package/telemetry/context/propagation.py +85 -0
  36. package/telemetry/events/catalog.py +24 -0
  37. package/telemetry/events/factory.py +42 -0
  38. package/telemetry/exporters/base.py +16 -0
  39. package/telemetry/exporters/console/exporter.py +30 -0
  40. package/telemetry/exporters/json/exporter.py +34 -0
  41. package/telemetry/exporters/langsmith/exporter.py +415 -0
  42. package/telemetry/metrics/aggregator.py +60 -0
  43. package/telemetry/scoring/efficiency.py +68 -0
  44. package/telemetry/tracing/span.py +43 -0
  45. package/observability/evals/chat-token-usage-report.json +0 -64
  46. package/observability/evals/chat-token-usage-report.md +0 -33
  47. package/observability/evals/iteration-value-report.json +0 -76
  48. package/observability/evals/iteration-value-report.md +0 -39
  49. package/observability/evals/learning-loop-report.json +0 -268
  50. package/observability/evals/learning-loop-report.md +0 -37
  51. package/observability/evals/repo-intake-eval-cases.md +0 -23
  52. package/observability/evals/routing-eval-cases.json +0 -68
  53. package/observability/evals/routing-eval-cases.md +0 -25
  54. package/observability/evals/routing-eval-report.json +0 -72
  55. package/observability/logs/copilot-usage-ingest-report.json +0 -13
  56. package/observability/logs/iteration-metrics.jsonl +0 -75
  57. package/observability/logs/learning-feedback.jsonl +0 -152
  58. package/observability/logs/routing-decisions.jsonl +0 -333
  59. package/observability/logs/session/agent-pipeline-preflight-20260701-004146.log +0 -8
  60. package/observability/logs/session/agent-pipeline-preflight-20260701-005554.log +0 -8
  61. package/observability/logs/session/agent-pipeline-preflight-20260701-010351.log +0 -8
  62. package/observability/logs/session/agent-pipeline-preflight-20260704-145829.log +0 -8
  63. package/observability/logs/session/agent-pipeline-preflight-20260704-150021.log +0 -8
  64. package/observability/logs/session/agent-pipeline-preflight-20260704-154328.log +0 -8
  65. package/observability/logs/session/bye-20260629-221513.json +0 -39
  66. package/observability/logs/session/bye-20260629-221545.json +0 -59
  67. package/observability/logs/session/bye-20260629-222007.json +0 -52
  68. package/observability/logs/session/bye-20260629-222133.json +0 -59
  69. package/observability/logs/session/bye-20260629-222412.json +0 -45
  70. package/observability/logs/session/bye-20260629-223224.json +0 -52
  71. package/observability/logs/session/bye-20260629-224050.json +0 -59
  72. package/observability/logs/session/bye-20260630-105732.json +0 -24
  73. package/observability/logs/session/bye-20260630-211536.json +0 -87
  74. package/observability/logs/session/bye-20260630-223423.json +0 -87
  75. package/observability/logs/session/bye-20260630-232534.json +0 -87
  76. package/observability/logs/session/bye-20260701-003638.json +0 -126
  77. package/observability/logs/session/bye-20260701-003849.json +0 -126
  78. package/observability/logs/session/bye-20260701-004315.json +0 -138
  79. package/observability/logs/session/bye-20260701-004559.json +0 -76
  80. package/observability/logs/session/bye-20260701-005913.json +0 -138
  81. package/observability/logs/session/bye-20260701-010753.json +0 -138
  82. package/observability/logs/session/bye-20260703-194106.json +0 -24
  83. package/observability/logs/session/bye-20260703-233443.json +0 -76
  84. package/observability/logs/session/bye-20260703-233653.json +0 -76
  85. package/observability/logs/session/bye-20260704-150317.json +0 -152
  86. package/observability/logs/session/bye-20260704-150929.json +0 -75
  87. package/observability/logs/session/bye-20260704-151050.json +0 -75
  88. package/observability/logs/session/bye-20260705-115458.json +0 -165
  89. package/observability/logs/session/codegraph-status-20260701-004228.log +0 -39
  90. package/observability/logs/session/codegraph-status-20260701-004310.log +0 -39
  91. package/observability/logs/session/codegraph-status-20260701-005637.log +0 -39
  92. package/observability/logs/session/codegraph-status-20260701-005908.log +0 -39
  93. package/observability/logs/session/codegraph-status-20260701-010444.log +0 -39
  94. package/observability/logs/session/codegraph-status-20260701-010747.log +0 -39
  95. package/observability/logs/session/codegraph-status-20260704-150137.log +0 -26
  96. package/observability/logs/session/codegraph-status-20260704-150313.log +0 -28
  97. package/observability/logs/session/codegraph-status-20260704-154445.log +0 -26
  98. package/observability/logs/session/codegraph-status-20260705-115454.log +0 -27
  99. package/observability/logs/session/codegraph-sync-20260701-004211.log +0 -88
  100. package/observability/logs/session/codegraph-sync-20260701-004241.log +0 -82
  101. package/observability/logs/session/codegraph-sync-20260701-005620.log +0 -89
  102. package/observability/logs/session/codegraph-sync-20260701-005840.log +0 -88
  103. package/observability/logs/session/codegraph-sync-20260701-010419.log +0 -93
  104. package/observability/logs/session/codegraph-sync-20260701-010609.log +0 -90
  105. package/observability/logs/session/codegraph-sync-20260704-145856.log +0 -70
  106. package/observability/logs/session/codegraph-sync-20260704-150047.log +0 -53
  107. package/observability/logs/session/codegraph-sync-20260704-150204.log +0 -44
  108. package/observability/logs/session/codegraph-sync-20260704-154353.log +0 -26
  109. package/observability/logs/session/codegraph-sync-20260705-115337.log +0 -32
  110. package/observability/logs/session/hi-20260629-221459.json +0 -38
  111. package/observability/logs/session/hi-20260629-221945.json +0 -59
  112. package/observability/logs/session/hi-20260629-222108.json +0 -66
  113. package/observability/logs/session/hi-20260629-222352.json +0 -45
  114. package/observability/logs/session/hi-20260629-225719.json +0 -59
  115. package/observability/logs/session/hi-20260629-233722.json +0 -52
  116. package/observability/logs/session/hi-20260629-233913.json +0 -198
  117. package/observability/logs/session/hi-20260630-110156.json +0 -177
  118. package/observability/logs/session/hi-20260630-191243.json +0 -184
  119. package/observability/logs/session/hi-20260630-230050.json +0 -234
  120. package/observability/logs/session/hi-20260630-230523.json +0 -227
  121. package/observability/logs/session/hi-20260630-230855.json +0 -227
  122. package/observability/logs/session/hi-20260630-231638.json +0 -227
  123. package/observability/logs/session/hi-20260630-231756.json +0 -219
  124. package/observability/logs/session/hi-20260701-002842.json +0 -234
  125. package/observability/logs/session/hi-20260701-003458.json +0 -282
  126. package/observability/logs/session/hi-20260701-004233.json +0 -290
  127. package/observability/logs/session/hi-20260701-004554.json +0 -236
  128. package/observability/logs/session/hi-20260701-005641.json +0 -290
  129. package/observability/logs/session/hi-20260701-010450.json +0 -290
  130. package/observability/logs/session/hi-20260703-233854.json +0 -312
  131. package/observability/logs/session/hi-20260703-234448.json +0 -318
  132. package/observability/logs/session/hi-20260704-145907.json +0 -353
  133. package/observability/logs/session/hi-20260704-150141.json +0 -392
  134. package/observability/logs/session/hi-20260704-154448.json +0 -392
  135. package/observability/logs/session/iteration-value-refresh-20260701-004309.log +0 -3
  136. package/observability/logs/session/iteration-value-refresh-20260701-005907.log +0 -3
  137. package/observability/logs/session/iteration-value-refresh-20260701-010747.log +0 -3
  138. package/observability/logs/session/iteration-value-refresh-20260704-150312.log +0 -3
  139. package/observability/logs/session/iteration-value-refresh-20260705-115453.log +0 -3
  140. package/observability/logs/session/learning-loop-refresh-20260701-004309.log +0 -3
  141. package/observability/logs/session/learning-loop-refresh-20260701-005906.log +0 -3
  142. package/observability/logs/session/learning-loop-refresh-20260701-010745.log +0 -3
  143. package/observability/logs/session/learning-loop-refresh-20260704-150309.log +0 -3
  144. package/observability/logs/session/learning-loop-refresh-20260705-115450.log +0 -3
  145. package/observability/logs/session/project-notes-refresh-20260701-004227.log +0 -1
  146. package/observability/logs/session/project-notes-refresh-20260701-004308.log +0 -1
  147. package/observability/logs/session/project-notes-refresh-20260701-005636.log +0 -1
  148. package/observability/logs/session/project-notes-refresh-20260701-005906.log +0 -1
  149. package/observability/logs/session/project-notes-refresh-20260701-010443.log +0 -1
  150. package/observability/logs/session/project-notes-refresh-20260701-010744.log +0 -1
  151. package/observability/logs/session/project-notes-refresh-20260704-150133.log +0 -1
  152. package/observability/logs/session/project-notes-refresh-20260704-150309.log +0 -1
  153. package/observability/logs/session/project-notes-refresh-20260704-154442.log +0 -1
  154. package/observability/logs/session/project-notes-refresh-20260705-115449.log +0 -1
  155. package/observability/logs/session/repo-intake-20260701-004218.log +0 -6
  156. package/observability/logs/session/repo-intake-20260701-005626.log +0 -6
  157. package/observability/logs/session/repo-intake-20260701-010433.log +0 -6
  158. package/observability/logs/session/repo-intake-20260704-150053.log +0 -6
  159. package/observability/logs/session/repo-intake-20260704-154404.log +0 -6
  160. package/observability/logs/session/repo-intake-refresh-20260701-004247.log +0 -6
  161. package/observability/logs/session/repo-intake-refresh-20260701-005847.log +0 -6
  162. package/observability/logs/session/repo-intake-refresh-20260701-010615.log +0 -6
  163. package/observability/logs/session/repo-intake-refresh-20260704-150209.log +0 -6
  164. package/observability/logs/session/repo-intake-refresh-20260705-115342.log +0 -6
  165. package/observability/logs/session/repo-registry-validation-20260701-004234.log +0 -2
  166. package/observability/logs/session/repo-registry-validation-20260701-004556.log +0 -2
  167. package/observability/logs/session/repo-registry-validation-20260701-005833.log +0 -2
  168. package/observability/logs/session/repo-registry-validation-20260701-010601.log +0 -2
  169. package/observability/logs/session/repo-registry-validation-20260704-150155.log +0 -2
  170. package/observability/logs/session/repo-registry-validation-20260705-115323.log +0 -2
  171. package/observability/logs/session/repomix-refresh-20260701-003823.log +0 -4236
  172. package/observability/logs/session/repomix-refresh-20260701-004251.log +0 -4275
  173. package/observability/logs/session/repomix-refresh-20260701-005850.log +0 -4248
  174. package/observability/logs/session/repomix-refresh-20260701-010619.log +0 -6531
  175. package/observability/logs/session/repomix-refresh-20260704-150239.log +0 -652
  176. package/observability/logs/session/repomix-refresh-20260705-115419.log +0 -178
  177. package/observability/logs/session/routing-evals-20260701-004221.log +0 -2
  178. package/observability/logs/session/routing-evals-20260701-004235.log +0 -2
  179. package/observability/logs/session/routing-evals-20260701-005629.log +0 -2
  180. package/observability/logs/session/routing-evals-20260701-005834.log +0 -2
  181. package/observability/logs/session/routing-evals-20260701-010437.log +0 -2
  182. package/observability/logs/session/routing-evals-20260701-010603.log +0 -2
  183. package/observability/logs/session/routing-evals-20260704-150125.log +0 -2
  184. package/observability/logs/session/routing-evals-20260704-150157.log +0 -2
  185. package/observability/logs/session/routing-evals-20260704-154434.log +0 -2
  186. package/observability/logs/session/routing-evals-20260705-115327.log +0 -2
  187. package/observability/logs/session/sibling-discovery-refresh-20260701-004250.log +0 -3
  188. package/observability/logs/session/sibling-discovery-refresh-20260701-005850.log +0 -3
  189. package/observability/logs/session/sibling-discovery-refresh-20260701-010618.log +0 -3
  190. package/observability/logs/session/sibling-discovery-refresh-20260704-150238.log +0 -3
  191. package/observability/logs/session/sibling-discovery-refresh-20260705-115418.log +0 -3
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env sh
2
+ set -eu
3
+
4
+ REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || true)
5
+ if [ -z "$REPO_ROOT" ]; then
6
+ exit 0
7
+ fi
8
+
9
+ if command -v pwsh >/dev/null 2>&1; then
10
+ pwsh -NoProfile -ExecutionPolicy Bypass -File "$REPO_ROOT/scripts/ops/post-commit-refresh.ps1"
11
+ exit 0
12
+ fi
13
+
14
+ if command -v powershell >/dev/null 2>&1; then
15
+ powershell -NoProfile -ExecutionPolicy Bypass -File "$REPO_ROOT/scripts/ops/post-commit-refresh.ps1"
16
+ exit 0
17
+ fi
18
+
19
+ # No PowerShell available; skip silently to avoid blocking commits.
20
+ exit 0
@@ -3,22 +3,8 @@ name: AutoDocs Sync
3
3
  on:
4
4
  push:
5
5
  branches: [ main, develop ]
6
- paths:
7
- - 'repo-intake/generated/**'
8
- - 'autodocs/**'
9
- - 'scripts/wiki/**'
10
- - 'orchestrator/wiki/**'
11
- - '.github/skills/wiki-tools.json'
12
- - '.github/agents/wiki-agent.agent.md'
13
6
  pull_request:
14
7
  branches: [ main, develop ]
15
- paths:
16
- - 'repo-intake/generated/**'
17
- - 'autodocs/**'
18
- - 'scripts/wiki/**'
19
- - 'orchestrator/wiki/**'
20
- - '.github/skills/wiki-tools.json'
21
- - '.github/agents/wiki-agent.agent.md'
22
8
  workflow_dispatch:
23
9
 
24
10
  permissions:
@@ -68,7 +54,7 @@ jobs:
68
54
  echo "- Required artifacts: autodocs/generated + autodocs/site" >> $env:GITHUB_STEP_SUMMARY
69
55
 
70
56
  autodocs-sync:
71
- if: github.event_name != 'pull_request' && github.actor != 'github-actions[bot]'
57
+ if: github.actor != 'github-actions[bot]'
72
58
  permissions:
73
59
  contents: write
74
60
  runs-on: windows-latest
@@ -89,6 +75,7 @@ jobs:
89
75
  shell: pwsh
90
76
 
91
77
  - name: Commit projected docs and unified graph
78
+ if: github.event_name != 'pull_request'
92
79
  shell: pwsh
93
80
  run: |
94
81
  git config user.name "github-actions[bot]"
@@ -0,0 +1,111 @@
1
+ name: Release & Publish NPM
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ workflow_dispatch:
7
+ inputs:
8
+ npm_version:
9
+ description: "Version especifica a publicar (ej. 0.2.0). Si se omite, se autoajusta."
10
+ required: false
11
+ type: string
12
+
13
+ permissions:
14
+ contents: write
15
+
16
+ jobs:
17
+ release-and-publish:
18
+ runs-on: ubuntu-latest
19
+
20
+ steps:
21
+ - name: Checkout
22
+ uses: actions/checkout@v5
23
+ with:
24
+ fetch-depth: 0
25
+
26
+ - name: Setup Node.js
27
+ uses: actions/setup-node@v4
28
+ with:
29
+ node-version: 20
30
+ registry-url: https://registry.npmjs.org
31
+
32
+ - name: Resolve publish version
33
+ id: version
34
+ run: |
35
+ PACKAGE_NAME=$(node -p "require('./package.json').name")
36
+ BASE_VERSION=$(node -p "require('./package.json').version")
37
+ REQUESTED_VERSION="${{ github.event.inputs.npm_version || '' }}"
38
+
39
+ version_exists() {
40
+ npm view "$PACKAGE_NAME@$1" version >/dev/null 2>&1
41
+ }
42
+
43
+ if [ -n "$REQUESTED_VERSION" ]; then
44
+ TARGET_VERSION="$REQUESTED_VERSION"
45
+ MODE="explicit"
46
+ else
47
+ TARGET_VERSION="$BASE_VERSION"
48
+ MODE="auto"
49
+ fi
50
+
51
+ if [ "$MODE" = "explicit" ]; then
52
+ if version_exists "$TARGET_VERSION"; then
53
+ echo "Requested version $TARGET_VERSION is already published in npm."
54
+ exit 1
55
+ fi
56
+ else
57
+ CANDIDATE="$TARGET_VERSION"
58
+ while version_exists "$CANDIDATE"; do
59
+ CANDIDATE=$(node -e "const parts = process.argv[1].split('.').map(Number); if (parts.length !== 3 || parts.some(Number.isNaN)) { process.exit(2); } parts[2] += 1; process.stdout.write(parts.join('.'));" "$CANDIDATE") || {
60
+ echo "Cannot auto-bump non x.y.z version: $CANDIDATE"
61
+ exit 1
62
+ }
63
+ done
64
+ TARGET_VERSION="$CANDIDATE"
65
+ fi
66
+
67
+ CHANGED=false
68
+ if [ "$TARGET_VERSION" != "$BASE_VERSION" ]; then
69
+ npm version "$TARGET_VERSION" --no-git-tag-version
70
+ CHANGED=true
71
+ fi
72
+
73
+ echo "version=$TARGET_VERSION" >> "$GITHUB_OUTPUT"
74
+ echo "tag=v$TARGET_VERSION" >> "$GITHUB_OUTPUT"
75
+ echo "changed=$CHANGED" >> "$GITHUB_OUTPUT"
76
+ echo "mode=$MODE" >> "$GITHUB_OUTPUT"
77
+
78
+ - name: Ensure NPM token is configured
79
+ run: |
80
+ if [ -z "${NODE_AUTH_TOKEN}" ]; then
81
+ echo "Missing NODE_AUTH_TOKEN/NPM_TOKEN secret. Configure repository secret NPM_TOKEN."
82
+ exit 1
83
+ fi
84
+ env:
85
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
86
+
87
+ - name: Remove Python cache artifacts from workspace
88
+ run: |
89
+ find . -type d -name "__pycache__" -prune -exec rm -rf {} +
90
+ find . -type f -name "*.pyc" -delete
91
+
92
+ - name: Publish to npm
93
+ run: npm publish --access public
94
+ env:
95
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
96
+
97
+ - name: Sync package.json version to repository
98
+ if: steps.version.outputs.changed == 'true'
99
+ run: |
100
+ git config user.name "github-actions[bot]"
101
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
102
+ git add package.json
103
+ git commit -m "chore(release): sync npm version to ${{ steps.version.outputs.tag }} [skip ci]"
104
+ git push
105
+
106
+ - name: Create GitHub release
107
+ uses: softprops/action-gh-release@v2
108
+ with:
109
+ tag_name: ${{ steps.version.outputs.tag }}
110
+ name: ${{ steps.version.outputs.tag }}
111
+ generate_release_notes: true
@@ -85,6 +85,84 @@ Esto significa:
85
85
  - las fuentes se conservan cuando sean obligatorias,
86
86
  - el sistema solo aumenta detalle si el usuario o el caso lo requiere.
87
87
 
88
+ ## 7. Telemetry Engine
89
+
90
+ El sistema incluye un engine de telemetría desacoplado con collector único.
91
+
92
+ Flujo:
93
+
94
+ ```txt
95
+ Componente -> TelemetryCollector -> Pipeline -> Exporters
96
+ ```
97
+
98
+ Exporters soportados:
99
+
100
+ - `console` (siempre disponible)
101
+ - `json` (persistencia local en `.telemetry/`)
102
+ - `langsmith` (opcional, solo con configuración válida)
103
+
104
+ Si un exporter falla:
105
+
106
+ - se registra warning,
107
+ - los demás exporters continúan,
108
+ - la ejecución principal no se detiene.
109
+
110
+ ### Configuración rápida
111
+
112
+ Archivo `telemetry/config.json`:
113
+
114
+ ```json
115
+ {
116
+ "telemetry": {
117
+ "enabled": true,
118
+ "batch_size": 25,
119
+ "telemetry_dir": ".telemetry",
120
+ "exporters": ["console", "json", "langsmith"]
121
+ },
122
+ "langsmith": {
123
+ "enabled": false,
124
+ "api_key": "",
125
+ "project": "",
126
+ "endpoint": ""
127
+ }
128
+ }
129
+ ```
130
+
131
+ ### Cómo activar LangSmith
132
+
133
+ 1. Configurar `LANGSMITH_ENABLED=true`.
134
+ 2. Definir `LANGSMITH_API_KEY` y `LANGSMITH_PROJECT`.
135
+ 3. Mantener `langsmith` en `telemetry.exporters`.
136
+
137
+ Si falta configuración, se omite automáticamente.
138
+
139
+ ## Flujo post-commit para proyectos consumidores
140
+
141
+ El install host configura hooks git locales (`core.hooksPath=.githooks`).
142
+
143
+ Hook incluido:
144
+
145
+ - `post-commit` -> `scripts/ops/post-commit-refresh.ps1`
146
+
147
+ Regla:
148
+
149
+ - Solo actua cuando el commit toca rutas bajo `projects/`.
150
+
151
+ Pipeline ejecutado en ese caso:
152
+
153
+ 1. AutoDocs incremental (`scripts/wiki/compiler_main.py`)
154
+ 2. Refresh de reportes de learning/value (`scripts/learning/*.py`)
155
+ 3. Publicacion de snapshots KPI a LangSmith (`scripts/ops/publish-langsmith-kpis.py`)
156
+
157
+ Log de ejecucion:
158
+
159
+ - `observability/logs/session/post-commit-refresh-*.json`
160
+
161
+ ### Cómo deshabilitar exporters
162
+
163
+ - Desactivar todo: `TELEMETRY_ENABLED=false`
164
+ - Solo algunos: `TELEMETRY_EXPORTERS=console,json`
165
+
88
166
  ## Diagrama Visual De Uso Diario
89
167
 
90
168
  ```mermaid
package/README.md CHANGED
@@ -192,6 +192,16 @@ Comportamiento esperado:
192
192
  - si no existe `repo-registry/repos.yml`, pregunta por owner/prefix y si quieres registrar un repo inicial para intake
193
193
  - si no añades repos en ese momento, deja el registry plantilla listo para añadirlos despues y rerun de intake
194
194
 
195
+ Nota npm (entornos con politicas de scripts):
196
+
197
+ - si `npm` bloquea `install`/`postinstall` (por ejemplo con `allow-scripts`), el scaffold/bootstrapping puede no ejecutarse automaticamente
198
+ - en ese caso, aprueba scripts (`npm approve-scripts`) o ejecuta manualmente:
199
+
200
+ ```powershell
201
+ npx mcp-efficiency-engine install
202
+ npx mcp-efficiency-engine validate -PortableMode
203
+ ```
204
+
195
205
  Tambien puedes relanzar la instalacion manualmente sobre el proyecto actual:
196
206
 
197
207
  ```powershell
@@ -229,6 +239,32 @@ py -3 .\scripts\intake\agent-pipeline-preflight.py
229
239
  py -3 .\scripts\intake\validate-repo-registry.py --strict
230
240
  ```
231
241
 
242
+ ### Flujo automatico al hacer commit en projects/
243
+
244
+ Cuando instalas el engine en un proyecto host (`mcpee install`), se configura `core.hooksPath=.githooks` con un `post-commit` que ejecuta `scripts/ops/post-commit-refresh.ps1`.
245
+
246
+ Comportamiento del hook:
247
+
248
+ - si el ultimo commit no toca `projects/`, no hace nada
249
+ - si detecta cambios en `projects/`, ejecuta:
250
+ - `scripts/wiki/compiler_main.py` (AutoDocs incremental)
251
+ - `scripts/learning/learning-loop-report.py`
252
+ - `scripts/learning/iteration-value-report.py`
253
+ - `scripts/ops/publish-langsmith-kpis.py` (best effort)
254
+
255
+ Artefactos/resultados:
256
+
257
+ - AutoDocs actualizado en `autodocs/generated` y `autodocs/site`
258
+ - reportes de observabilidad actualizados en `observability/evals`
259
+ - snapshots KPI publicados a LangSmith para dashboards
260
+ - resumen local en `observability/logs/session/post-commit-refresh-*.json`
261
+
262
+ Instalacion manual de hooks (si necesitas reprovisionar):
263
+
264
+ ```powershell
265
+ .\scripts\setup\install-project-hooks.ps1
266
+ ```
267
+
232
268
  ## Flujo De Intake
233
269
 
234
270
  `repo-intake` soporta dos modos:
@@ -245,6 +281,201 @@ Artefactos canónicos:
245
281
 
246
282
  ## Observabilidad
247
283
 
284
+ ### Telemetry Engine (desacoplado y extensible)
285
+
286
+ La observabilidad ahora se soporta mediante un engine propio en `telemetry/`.
287
+
288
+ Principios:
289
+
290
+ - Telemetría siempre activa a nivel de modelo de datos.
291
+ - Exporters opcionales (`console`, `json`, `langsmith`).
292
+ - Ningún flujo de negocio depende de LangSmith.
293
+ - Si un exporter falla, la ejecución principal continua.
294
+
295
+ Arquitectura:
296
+
297
+ ```mermaid
298
+ flowchart TD
299
+ T[Tool/Flow] --> C[TelemetryCollector]
300
+ C --> P[Telemetry Pipeline]
301
+ P --> EX1[Console Exporter]
302
+ P --> EX2[JSON Exporter]
303
+ P --> EX3[LangSmith Exporter]
304
+ P --> EXN[Future Exporters]
305
+ ```
306
+
307
+ Trazas jerárquicas:
308
+
309
+ - Cada ejecución genera `execution_id`, `trace_id`, `span_id`, `parent_span_id`.
310
+ - Se propaga contexto con `contextvars` (sin variables globales).
311
+ - Spans soportan `events`, `status`, `duration_ms` y error asociado.
312
+
313
+ Configuración base (`telemetry/config.json`):
314
+
315
+ ```json
316
+ {
317
+ "telemetry": {
318
+ "enabled": true,
319
+ "batch_size": 100,
320
+ "telemetry_dir": ".telemetry",
321
+ "exporters": ["console", "json"]
322
+ },
323
+ "langsmith": {
324
+ "enabled": false,
325
+ "api_key": "",
326
+ "project": "",
327
+ "endpoint": "",
328
+ "high_signal_only": true,
329
+ "min_span_duration_ms": 100,
330
+ "emit_execution_summary": true
331
+ }
332
+ }
333
+ ```
334
+
335
+ Conexión segura a LangSmith (sin subir token al repo/npm):
336
+
337
+ 1. No guardes el token en `telemetry/config.json`.
338
+ 2. Define variables de entorno locales (usuario o sesión).
339
+ 3. Activa exporter por entorno con `TELEMETRY_EXPORTERS=console,json,langsmith`.
340
+ 4. Verifica que `.env` y variantes están ignorados por Git y npm.
341
+
342
+ Ejemplo (PowerShell, solo sesión actual):
343
+
344
+ ```powershell
345
+ $env:LANGSMITH_ENABLED='true'
346
+ $env:LANGSMITH_API_KEY='tu_token'
347
+ $env:LANGSMITH_PROJECT='mcpee-local'
348
+ $env:LANGSMITH_ENDPOINT='https://api.smith.langchain.com'
349
+ $env:LANGSMITH_HIGH_SIGNAL_ONLY='true'
350
+ $env:LANGSMITH_MIN_SPAN_DURATION_MS='100'
351
+ $env:LANGSMITH_EMIT_EXECUTION_SUMMARY='true'
352
+ $env:TELEMETRY_EXPORTERS='console,json,langsmith'
353
+ ```
354
+
355
+ Persistente para tu usuario Windows:
356
+
357
+ ```powershell
358
+ [System.Environment]::SetEnvironmentVariable('LANGSMITH_ENABLED','true','User')
359
+ [System.Environment]::SetEnvironmentVariable('LANGSMITH_API_KEY','tu_token','User')
360
+ [System.Environment]::SetEnvironmentVariable('LANGSMITH_PROJECT','mcpee-local','User')
361
+ [System.Environment]::SetEnvironmentVariable('LANGSMITH_ENDPOINT','https://api.smith.langchain.com','User')
362
+ [System.Environment]::SetEnvironmentVariable('LANGSMITH_HIGH_SIGNAL_ONLY','true','User')
363
+ [System.Environment]::SetEnvironmentVariable('LANGSMITH_MIN_SPAN_DURATION_MS','100','User')
364
+ [System.Environment]::SetEnvironmentVariable('LANGSMITH_EMIT_EXECUTION_SUMMARY','true','User')
365
+ [System.Environment]::SetEnvironmentVariable('TELEMETRY_EXPORTERS','console,json,langsmith','User')
366
+
367
+ Modo high-signal recomendado en LangSmith:
368
+
369
+ - `LANGSMITH_HIGH_SIGNAL_ONLY=true` (default): prioriza trazas útiles y reduce ruido.
370
+ - `LANGSMITH_MIN_SPAN_DURATION_MS=100` (default): solo mantiene spans rápidos cuando fallan; los de éxito deben superar el umbral.
371
+ - `LANGSMITH_EMIT_EXECUTION_SUMMARY=true` (default): añade un resumen consolidado por ejecución (duración, estado, warnings/errors, tokens/coste).
372
+ - Mantiene eventos clave (`ExecutionStarted`, `ExecutionFinished`, `RoutingResolved`, warnings/errores) y resumen `UsageSummary` con modelo/tokens/coste.
373
+ - Omite eventos de bajo valor para la UI de LangSmith, pero conserva debug detallado en exporters locales (`console`, `json`).
374
+ ```
375
+
376
+ Para volver al modo local sin LangSmith:
377
+
378
+ ```powershell
379
+ $env:LANGSMITH_ENABLED='false'
380
+ $env:TELEMETRY_EXPORTERS='console,json'
381
+ ```
382
+
383
+ Troubleshooting rapido: no aparecen dashboards/runs en LangSmith
384
+
385
+ Importante: en LangSmith, los runs se validan primero en `Tracing` (y opcionalmente `Monitoring`). La seccion `Custom Dashboards` no se autogenera por defecto; puede aparecer vacia aunque la telemetria este funcionando correctamente.
386
+
387
+ Checklist minimo (debe cumplirse todo):
388
+
389
+ - `LANGSMITH_ENABLED=true`
390
+ - `LANGSMITH_API_KEY` definido
391
+ - `LANGSMITH_PROJECT` definido
392
+ - `TELEMETRY_EXPORTERS=console,json,langsmith`
393
+ - el flujo que ejecutas realmente emite telemetria (por ejemplo `hi.ps1`, intake o routing-evals)
394
+
395
+ Comprobacion en PowerShell:
396
+
397
+ ```powershell
398
+ Write-Host "LANGSMITH_ENABLED=$env:LANGSMITH_ENABLED"
399
+ Write-Host "LANGSMITH_PROJECT=$env:LANGSMITH_PROJECT"
400
+ Write-Host "TELEMETRY_EXPORTERS=$env:TELEMETRY_EXPORTERS"
401
+ ```
402
+
403
+ Si `LANGSMITH_WORKSPACE_ID` no coincide con tu workspace real, los runs pueden quedar en otro workspace y "no verse" en la UI esperada.
404
+
405
+ Verificacion local (aunque LangSmith falle):
406
+
407
+ - revisa que se siguen generando logs en `observability/logs/` (la app no debe romperse por un fallo del exporter)
408
+ - si hay trazas locales pero no runs remotos, el problema es de configuracion/conectividad de LangSmith y no del flujo principal
409
+
410
+ ### Alinear KPIs locales con LangSmith
411
+
412
+ Para enviar a LangSmith los KPIs que ya calcula el engine en local (`learning-loop-report.json` e `iteration-value-report.json`) y poder construir dashboards con esa señal:
413
+
414
+ ```powershell
415
+ npm run langsmith:kpis
416
+ ```
417
+
418
+ Este comando publica runs de resumen con tags `mcpee`, `kpi`, `dashboard` y nombres:
419
+
420
+ - `KPI::LearningLoop`
421
+ - `KPI::IterationValue`
422
+ - `KPI::AlignmentSnapshot`
423
+
424
+ Con eso puedes filtrar en `Tracing` por `tag:kpi` y montar dashboards manuales en `Custom Dashboards` sobre esos runs.
425
+
426
+ Separacion plataforma vs proyecto consumidor:
427
+
428
+ - los runs KPI incluyen metadata y tags de scope automaticamente
429
+ - metadata: `host_project`, `host_project_slug`, `telemetry_scope` (`platform` o `consumer`)
430
+ - tags: `scope:<valor>` y `host:<slug>`
431
+
432
+ Ejemplos de filtro para un dashboard de proyecto consumidor:
433
+
434
+ - `Tag contains kpi`
435
+ - `Tag contains scope:consumer`
436
+ - `Tag contains host:<slug-del-proyecto>`
437
+
438
+ Si quieres forzar nombre de proyecto host (por ejemplo en CI):
439
+
440
+ ```powershell
441
+ $env:MCPEE_HOST_PROJECT='mi-proyecto-app'
442
+ npm run langsmith:kpis
443
+ ```
444
+
445
+ Variables de entorno soportadas:
446
+
447
+ - `TELEMETRY_ENABLED`
448
+ - `TELEMETRY_EXPORTERS`
449
+ - `TELEMETRY_BATCH_SIZE`
450
+ - `TELEMETRY_DIR`
451
+ - `LANGSMITH_ENABLED`
452
+ - `LANGSMITH_API_KEY`
453
+ - `LANGSMITH_PROJECT`
454
+ - `LANGSMITH_ENDPOINT`
455
+ - `LANGSMITH_WORKSPACE_ID` (opcional, recomendado para cuentas con multiples workspaces)
456
+
457
+ Nota: el engine carga automáticamente `.env` en la raíz del repo. Si también existe variable en el entorno del sistema/proceso, esa tiene prioridad.
458
+
459
+ Dependencia runtime: `langsmith` está incluida en `requirements.txt` para que `scripts/setup/setup-prerequisites.ps1` la instale automáticamente cuando prepares el entorno Python.
460
+
461
+ Cómo crear un exporter nuevo:
462
+
463
+ 1. Implementar contrato `export/flush/shutdown` en `telemetry/exporters/<nuevo>/exporter.py`.
464
+ 2. Registrar el exporter en `telemetry/bootstrap.py`.
465
+ 3. Añadirlo en `telemetry/config.json` o `TELEMETRY_EXPORTERS`.
466
+
467
+ Si LangSmith no está configurado correctamente, el exporter se omite y el engine sigue funcionando con `console/json`.
468
+
469
+ Benchmark de overhead on/off:
470
+
471
+ ```powershell
472
+ py -3 .\scripts\ops\telemetry-benchmark.py --iterations 10
473
+ ```
474
+
475
+ Salida:
476
+
477
+ - `observability/evals/telemetry-overhead-benchmark.json`
478
+
248
479
  Registros principales:
249
480
 
250
481
  - `observability/logs/routing-decisions.jsonl`
@@ -14,6 +14,12 @@ AutoDocs es la wiki interna nativa de `mcp-efficiency-engine`.
14
14
  py -3 -m scripts.wiki.wiki_compiler
15
15
  ```
16
16
 
17
+ ## Sincronizacion automatica
18
+
19
+ - En CI, el workflow `autodocs-sync` valida en PR y sincroniza en `main`/`develop`.
20
+ - La ejecucion ya no depende de filtros de path: cualquier cambio potencialmente relevante recompila AutoDocs.
21
+ - Si hay drift, CI exige regenerar y commitear `autodocs/generated` y `autodocs/site`.
22
+
17
23
  ## Artefactos clave
18
24
 
19
25
  - `autodocs/generated/unified-graph.json`
@@ -6,6 +6,7 @@ const { spawnSync } = require("node:child_process");
6
6
 
7
7
  const packageRoot = path.resolve(__dirname, "..");
8
8
  const scaffoldEntries = [
9
+ ".githooks",
9
10
  ".github",
10
11
  ".vscode",
11
12
  "autodocs/README.md",
@@ -260,6 +261,15 @@ function runBootstrap(targetRoot) {
260
261
  return runPowerShell(bootstrapScript, [], targetRoot);
261
262
  }
262
263
 
264
+ function installProjectHooks(targetRoot) {
265
+ const hookScript = path.join(targetRoot, "scripts", "setup", "install-project-hooks.ps1");
266
+ if (!fs.existsSync(hookScript)) {
267
+ return 0;
268
+ }
269
+
270
+ return runPowerShell(hookScript, [], targetRoot);
271
+ }
272
+
263
273
  function runHostInstall(rawOptions) {
264
274
  const options = rawOptions;
265
275
  const targetRoot = normalizePath(options.targetDir);
@@ -284,6 +294,11 @@ function runHostInstall(rawOptions) {
284
294
  return initStatus;
285
295
  }
286
296
 
297
+ const hookStatus = installProjectHooks(targetRoot);
298
+ if (hookStatus !== 0) {
299
+ return hookStatus;
300
+ }
301
+
287
302
  process.stdout.write("[mcpee] Bootstrap omitido. Puedes ejecutar .\\scripts\\bootstrap-portable.cmd mas tarde.\n");
288
303
  return 0;
289
304
  }
@@ -294,11 +309,21 @@ function runHostInstall(rawOptions) {
294
309
  return initStatus;
295
310
  }
296
311
 
312
+ const hookStatus = installProjectHooks(targetRoot);
313
+ if (hookStatus !== 0) {
314
+ return hookStatus;
315
+ }
316
+
297
317
  process.stdout.write("[mcpee] Modo no interactivo detectado. Se inicializo el registry plantilla y se omitio bootstrap interactivo.\n");
298
318
  return 0;
299
319
  }
300
320
 
301
- return runBootstrap(targetRoot);
321
+ const bootstrapStatus = runBootstrap(targetRoot);
322
+ if (bootstrapStatus !== 0) {
323
+ return bootstrapStatus;
324
+ }
325
+
326
+ return installProjectHooks(targetRoot);
302
327
  }
303
328
 
304
329
  function runHostInstallFromCli(argv = process.argv.slice(2)) {
@@ -28,6 +28,39 @@ Métricas: routing accuracy, tool usage, tool misuse, tool switching, grounding
28
28
  - token_efficiency: tendencia estable o mejorando
29
29
  - caveman_effectiveness: `>= 85%`
30
30
 
31
+ ## Telemetry Engine native metrics
32
+
33
+ El engine expone métricas propias y no depende de proveedores externos:
34
+
35
+ - execution_time_ms
36
+ - tool_duration_ms
37
+ - average_duration_ms
38
+ - parallel_tasks
39
+ - sequential_tasks
40
+ - retry_count
41
+ - error_count
42
+ - warning_count
43
+ - llm_calls
44
+ - provider_calls
45
+ - mcp_calls
46
+ - tool_invocations
47
+ - tokens_input
48
+ - tokens_output
49
+ - total_tokens
50
+ - estimated_cost
51
+ - cache_hits
52
+ - cache_misses
53
+ - compression_ratio
54
+ - parallel_efficiency
55
+ - prompt_reduction
56
+ - context_reduction
57
+ - efficiency_score (0-100)
58
+
59
+ Los cálculos viven en:
60
+
61
+ - `telemetry/metrics/aggregator.py`
62
+ - `telemetry/scoring/efficiency.py`
63
+
31
64
  ## Semaforo
32
65
 
33
66
  - `OK`: todos los umbrales en rango.
@@ -1,5 +1,7 @@
1
1
  # Scoring Rubric
2
2
 
3
+ > El score de eficiencia es nativo del Telemetry Engine y no depende de LangSmith.
4
+
3
5
  ## Componentes y pesos
4
6
 
5
7
  - Routing score: 40%
@@ -36,3 +38,21 @@
36
38
  - `80-89`: Aceptable
37
39
  - `70-79`: Mejorable
38
40
  - `< 70`: No apto
41
+
42
+ ## Efficiency Score (Telemetry Engine)
43
+
44
+ Salida: `0..100`.
45
+
46
+ Factores por defecto:
47
+
48
+ - time
49
+ - cost
50
+ - tokens
51
+ - cache
52
+ - parallelism
53
+ - reuse
54
+ - calls
55
+ - compression
56
+
57
+ Implementación base en `telemetry/scoring/efficiency.py`.
58
+ Los pesos son configurables y el algoritmo se puede ajustar sin tocar exporters.