elasticdash-sdk 0.2.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/LICENSE +21 -0
- package/README.md +775 -0
- package/dist/browser-ui.d.ts +43 -0
- package/dist/browser-ui.d.ts.map +1 -0
- package/dist/browser-ui.js +246 -0
- package/dist/browser-ui.js.map +1 -0
- package/dist/capture/event.d.ts +33 -0
- package/dist/capture/event.d.ts.map +1 -0
- package/dist/capture/event.js +2 -0
- package/dist/capture/event.js.map +1 -0
- package/dist/capture/index.d.ts +4 -0
- package/dist/capture/index.d.ts.map +1 -0
- package/dist/capture/index.js +4 -0
- package/dist/capture/index.js.map +1 -0
- package/dist/capture/recorder.d.ts +24 -0
- package/dist/capture/recorder.d.ts.map +1 -0
- package/dist/capture/recorder.js +46 -0
- package/dist/capture/recorder.js.map +1 -0
- package/dist/capture/replay.d.ts +20 -0
- package/dist/capture/replay.d.ts.map +1 -0
- package/dist/capture/replay.js +47 -0
- package/dist/capture/replay.js.map +1 -0
- package/dist/ci/api-client.d.ts +38 -0
- package/dist/ci/api-client.d.ts.map +1 -0
- package/dist/ci/api-client.js +96 -0
- package/dist/ci/api-client.js.map +1 -0
- package/dist/ci/benchmark.d.ts +33 -0
- package/dist/ci/benchmark.d.ts.map +1 -0
- package/dist/ci/benchmark.js +213 -0
- package/dist/ci/benchmark.js.map +1 -0
- package/dist/ci/ed-runner.d.ts +48 -0
- package/dist/ci/ed-runner.d.ts.map +1 -0
- package/dist/ci/ed-runner.js +260 -0
- package/dist/ci/ed-runner.js.map +1 -0
- package/dist/ci/executor.d.ts +13 -0
- package/dist/ci/executor.d.ts.map +1 -0
- package/dist/ci/executor.js +542 -0
- package/dist/ci/executor.js.map +1 -0
- package/dist/ci/git-info.d.ts +17 -0
- package/dist/ci/git-info.d.ts.map +1 -0
- package/dist/ci/git-info.js +102 -0
- package/dist/ci/git-info.js.map +1 -0
- package/dist/ci/index.d.ts +6 -0
- package/dist/ci/index.d.ts.map +1 -0
- package/dist/ci/index.js +4 -0
- package/dist/ci/index.js.map +1 -0
- package/dist/ci/measurement.d.ts +9 -0
- package/dist/ci/measurement.d.ts.map +1 -0
- package/dist/ci/measurement.js +15 -0
- package/dist/ci/measurement.js.map +1 -0
- package/dist/ci/replay.d.ts +31 -0
- package/dist/ci/replay.d.ts.map +1 -0
- package/dist/ci/replay.js +96 -0
- package/dist/ci/replay.js.map +1 -0
- package/dist/ci/reporters/default.d.ts +8 -0
- package/dist/ci/reporters/default.d.ts.map +1 -0
- package/dist/ci/reporters/default.js +46 -0
- package/dist/ci/reporters/default.js.map +1 -0
- package/dist/ci/reporters/index.d.ts +8 -0
- package/dist/ci/reporters/index.d.ts.map +1 -0
- package/dist/ci/reporters/index.js +14 -0
- package/dist/ci/reporters/index.js.map +1 -0
- package/dist/ci/reporters/json.d.ts +8 -0
- package/dist/ci/reporters/json.d.ts.map +1 -0
- package/dist/ci/reporters/json.js +14 -0
- package/dist/ci/reporters/json.js.map +1 -0
- package/dist/ci/reporters/junit.d.ts +8 -0
- package/dist/ci/reporters/junit.d.ts.map +1 -0
- package/dist/ci/reporters/junit.js +48 -0
- package/dist/ci/reporters/junit.js.map +1 -0
- package/dist/ci/runner.d.ts +3 -0
- package/dist/ci/runner.d.ts.map +1 -0
- package/dist/ci/runner.js +187 -0
- package/dist/ci/runner.js.map +1 -0
- package/dist/ci/test-discovery.d.ts +5 -0
- package/dist/ci/test-discovery.d.ts.map +1 -0
- package/dist/ci/test-discovery.js +11 -0
- package/dist/ci/test-discovery.js.map +1 -0
- package/dist/ci/test-loader.d.ts +19 -0
- package/dist/ci/test-loader.d.ts.map +1 -0
- package/dist/ci/test-loader.js +149 -0
- package/dist/ci/test-loader.js.map +1 -0
- package/dist/ci/test-registry.d.ts +42 -0
- package/dist/ci/test-registry.d.ts.map +1 -0
- package/dist/ci/test-registry.js +18 -0
- package/dist/ci/test-registry.js.map +1 -0
- package/dist/ci/trace-schema.d.ts +30 -0
- package/dist/ci/trace-schema.d.ts.map +1 -0
- package/dist/ci/trace-schema.js +66 -0
- package/dist/ci/trace-schema.js.map +1 -0
- package/dist/ci/trace-writer.d.ts +16 -0
- package/dist/ci/trace-writer.d.ts.map +1 -0
- package/dist/ci/trace-writer.js +108 -0
- package/dist/ci/trace-writer.js.map +1 -0
- package/dist/ci/types.d.ts +108 -0
- package/dist/ci/types.d.ts.map +1 -0
- package/dist/ci/types.js +3 -0
- package/dist/ci/types.js.map +1 -0
- package/dist/ci/upload-client.d.ts +74 -0
- package/dist/ci/upload-client.d.ts.map +1 -0
- package/dist/ci/upload-client.js +195 -0
- package/dist/ci/upload-client.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +716 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/agent-state.d.ts +47 -0
- package/dist/core/agent-state.d.ts.map +1 -0
- package/dist/core/agent-state.js +137 -0
- package/dist/core/agent-state.js.map +1 -0
- package/dist/core/judge-utils.d.ts +22 -0
- package/dist/core/judge-utils.d.ts.map +1 -0
- package/dist/core/judge-utils.js +211 -0
- package/dist/core/judge-utils.js.map +1 -0
- package/dist/core/registry.d.ts +28 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +52 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/dashboard-server.d.ts +65 -0
- package/dist/dashboard-server.d.ts.map +1 -0
- package/dist/dashboard-server.js +3940 -0
- package/dist/dashboard-server.js.map +1 -0
- package/dist/execution/tool-runner.d.ts +26 -0
- package/dist/execution/tool-runner.d.ts.map +1 -0
- package/dist/execution/tool-runner.js +316 -0
- package/dist/execution/tool-runner.js.map +1 -0
- package/dist/html/dashboard.html +2218 -0
- package/dist/http.d.ts +14 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +13 -0
- package/dist/http.js.map +1 -0
- package/dist/index.cjs +8102 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +67 -0
- package/dist/index.js.map +1 -0
- package/dist/interceptors/ai-interceptor.d.ts +26 -0
- package/dist/interceptors/ai-interceptor.d.ts.map +1 -0
- package/dist/interceptors/ai-interceptor.js +756 -0
- package/dist/interceptors/ai-interceptor.js.map +1 -0
- package/dist/interceptors/db-auto.d.ts +8 -0
- package/dist/interceptors/db-auto.d.ts.map +1 -0
- package/dist/interceptors/db-auto.js +217 -0
- package/dist/interceptors/db-auto.js.map +1 -0
- package/dist/interceptors/db.d.ts +23 -0
- package/dist/interceptors/db.d.ts.map +1 -0
- package/dist/interceptors/db.js +137 -0
- package/dist/interceptors/db.js.map +1 -0
- package/dist/interceptors/http.d.ts +28 -0
- package/dist/interceptors/http.d.ts.map +1 -0
- package/dist/interceptors/http.js +356 -0
- package/dist/interceptors/http.js.map +1 -0
- package/dist/interceptors/side-effects.d.ts +7 -0
- package/dist/interceptors/side-effects.d.ts.map +1 -0
- package/dist/interceptors/side-effects.js +72 -0
- package/dist/interceptors/side-effects.js.map +1 -0
- package/dist/interceptors/telemetry-push.d.ts +142 -0
- package/dist/interceptors/telemetry-push.d.ts.map +1 -0
- package/dist/interceptors/telemetry-push.js +463 -0
- package/dist/interceptors/telemetry-push.js.map +1 -0
- package/dist/interceptors/tool.d.ts +2 -0
- package/dist/interceptors/tool.d.ts.map +1 -0
- package/dist/interceptors/tool.js +274 -0
- package/dist/interceptors/tool.js.map +1 -0
- package/dist/interceptors/workflow-ai.d.ts +5 -0
- package/dist/interceptors/workflow-ai.d.ts.map +1 -0
- package/dist/interceptors/workflow-ai.js +382 -0
- package/dist/interceptors/workflow-ai.js.map +1 -0
- package/dist/internals/conditional-recorder.d.ts +21 -0
- package/dist/internals/conditional-recorder.d.ts.map +1 -0
- package/dist/internals/conditional-recorder.js +54 -0
- package/dist/internals/conditional-recorder.js.map +1 -0
- package/dist/internals/mock-resolver.d.ts +146 -0
- package/dist/internals/mock-resolver.d.ts.map +1 -0
- package/dist/internals/mock-resolver.js +427 -0
- package/dist/internals/mock-resolver.js.map +1 -0
- package/dist/matchers/index.d.ts +96 -0
- package/dist/matchers/index.d.ts.map +1 -0
- package/dist/matchers/index.js +668 -0
- package/dist/matchers/index.js.map +1 -0
- package/dist/observability.d.ts +82 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +471 -0
- package/dist/observability.js.map +1 -0
- package/dist/portal-executor.d.ts +30 -0
- package/dist/portal-executor.d.ts.map +1 -0
- package/dist/portal-executor.js +324 -0
- package/dist/portal-executor.js.map +1 -0
- package/dist/portal-server.d.ts +3 -0
- package/dist/portal-server.d.ts.map +1 -0
- package/dist/portal-server.js +279 -0
- package/dist/portal-server.js.map +1 -0
- package/dist/proxy/llm-capture.d.ts +14 -0
- package/dist/proxy/llm-capture.d.ts.map +1 -0
- package/dist/proxy/llm-capture.js +264 -0
- package/dist/proxy/llm-capture.js.map +1 -0
- package/dist/reporter.d.ts +3 -0
- package/dist/reporter.d.ts.map +1 -0
- package/dist/reporter.js +72 -0
- package/dist/reporter.js.map +1 -0
- package/dist/runWorkflowSubprocess.d.ts +14 -0
- package/dist/runWorkflowSubprocess.d.ts.map +1 -0
- package/dist/runWorkflowSubprocess.js +66 -0
- package/dist/runWorkflowSubprocess.js.map +1 -0
- package/dist/runner.d.ts +16 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +138 -0
- package/dist/runner.js.map +1 -0
- package/dist/socket-connector.d.ts +22 -0
- package/dist/socket-connector.d.ts.map +1 -0
- package/dist/socket-connector.js +104 -0
- package/dist/socket-connector.js.map +1 -0
- package/dist/telemetry-batcher.d.ts +56 -0
- package/dist/telemetry-batcher.d.ts.map +1 -0
- package/dist/telemetry-batcher.js +143 -0
- package/dist/telemetry-batcher.js.map +1 -0
- package/dist/test-setup.d.ts +12 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +13 -0
- package/dist/test-setup.js.map +1 -0
- package/dist/tool-registry.d.ts +31 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +73 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tool-runner-worker.d.ts +2 -0
- package/dist/tool-runner-worker.d.ts.map +1 -0
- package/dist/tool-runner-worker.js +215 -0
- package/dist/tool-runner-worker.js.map +1 -0
- package/dist/trace-adapter/context.d.ts +72 -0
- package/dist/trace-adapter/context.d.ts.map +1 -0
- package/dist/trace-adapter/context.js +80 -0
- package/dist/trace-adapter/context.js.map +1 -0
- package/dist/tracing.d.ts +2 -0
- package/dist/tracing.d.ts.map +1 -0
- package/dist/tracing.js +59 -0
- package/dist/tracing.js.map +1 -0
- package/dist/trigger-executor.d.ts +12 -0
- package/dist/trigger-executor.d.ts.map +1 -0
- package/dist/trigger-executor.js +130 -0
- package/dist/trigger-executor.js.map +1 -0
- package/dist/types/portal.d.ts +76 -0
- package/dist/types/portal.d.ts.map +1 -0
- package/dist/types/portal.js +2 -0
- package/dist/types/portal.js.map +1 -0
- package/dist/utils/debug.d.ts +3 -0
- package/dist/utils/debug.d.ts.map +1 -0
- package/dist/utils/debug.js +8 -0
- package/dist/utils/debug.js.map +1 -0
- package/dist/utils/license-error.d.ts +23 -0
- package/dist/utils/license-error.d.ts.map +1 -0
- package/dist/utils/license-error.js +42 -0
- package/dist/utils/license-error.js.map +1 -0
- package/dist/utils/redact.d.ts +7 -0
- package/dist/utils/redact.d.ts.map +1 -0
- package/dist/utils/redact.js +26 -0
- package/dist/utils/redact.js.map +1 -0
- package/dist/workflow-runner-worker.d.ts +2 -0
- package/dist/workflow-runner-worker.d.ts.map +1 -0
- package/dist/workflow-runner-worker.js +329 -0
- package/dist/workflow-runner-worker.js.map +1 -0
- package/dist/workflow-runner.d.ts +14 -0
- package/dist/workflow-runner.d.ts.map +1 -0
- package/dist/workflow-runner.js +34 -0
- package/dist/workflow-runner.js.map +1 -0
- package/docs/agent-coding-instructions.md +138 -0
- package/docs/agent-integration-guide.md +564 -0
- package/docs/agents.md +140 -0
- package/docs/dashboard.md +394 -0
- package/docs/deno.md +69 -0
- package/docs/instrumentation.md +424 -0
- package/docs/langfuse-trace-structure.md +145 -0
- package/docs/matchers.md +173 -0
- package/docs/observability_contract.md +192 -0
- package/docs/observability_mode.md +195 -0
- package/docs/quickstart.md +621 -0
- package/docs/security-compliance.md +566 -0
- package/docs/test-writing-guidelines.md +444 -0
- package/docs/tools.md +165 -0
- package/docs/workflow-modes.md +253 -0
- package/package.json +76 -0
- package/src/browser-ui.ts +281 -0
- package/src/capture/event.ts +30 -0
- package/src/capture/index.ts +3 -0
- package/src/capture/recorder.ts +62 -0
- package/src/capture/replay.ts +55 -0
- package/src/ci/api-client.ts +136 -0
- package/src/ci/benchmark.ts +257 -0
- package/src/ci/ed-runner.ts +351 -0
- package/src/ci/executor.ts +671 -0
- package/src/ci/git-info.ts +127 -0
- package/src/ci/index.ts +5 -0
- package/src/ci/measurement.ts +25 -0
- package/src/ci/replay.ts +127 -0
- package/src/ci/reporters/default.ts +50 -0
- package/src/ci/reporters/index.ts +21 -0
- package/src/ci/reporters/json.ts +18 -0
- package/src/ci/reporters/junit.ts +61 -0
- package/src/ci/runner.ts +208 -0
- package/src/ci/test-discovery.ts +16 -0
- package/src/ci/test-loader.ts +187 -0
- package/src/ci/test-registry.ts +62 -0
- package/src/ci/trace-schema.ts +96 -0
- package/src/ci/trace-writer.ts +107 -0
- package/src/ci/types.ts +115 -0
- package/src/ci/upload-client.ts +300 -0
- package/src/cli.ts +811 -0
- package/src/core/agent-state.ts +162 -0
- package/src/core/judge-utils.ts +232 -0
- package/src/core/registry.ts +92 -0
- package/src/dashboard-server.ts +2047 -0
- package/src/execution/tool-runner.ts +352 -0
- package/src/html/dashboard.html +2218 -0
- package/src/http.ts +13 -0
- package/src/index.ts +138 -0
- package/src/interceptors/ai-interceptor.ts +798 -0
- package/src/interceptors/db-auto.ts +243 -0
- package/src/interceptors/db.ts +156 -0
- package/src/interceptors/http.ts +393 -0
- package/src/interceptors/side-effects.ts +83 -0
- package/src/interceptors/telemetry-push.ts +537 -0
- package/src/interceptors/tool.ts +287 -0
- package/src/interceptors/workflow-ai.ts +419 -0
- package/src/internals/conditional-recorder.ts +63 -0
- package/src/internals/mock-resolver.ts +492 -0
- package/src/matchers/index.ts +824 -0
- package/src/observability.ts +501 -0
- package/src/portal-executor.ts +355 -0
- package/src/portal-server.ts +304 -0
- package/src/proxy/llm-capture.ts +301 -0
- package/src/reporter.ts +81 -0
- package/src/runWorkflowSubprocess.ts +74 -0
- package/src/runner.ts +178 -0
- package/src/socket-connector.ts +117 -0
- package/src/telemetry-batcher.ts +191 -0
- package/src/test-setup.ts +16 -0
- package/src/tool-registry.ts +94 -0
- package/src/tool-runner-worker.ts +244 -0
- package/src/trace-adapter/context.ts +156 -0
- package/src/tracing.ts +62 -0
- package/src/trigger-executor.ts +171 -0
- package/src/types/agent.d.ts +63 -0
- package/src/types/expect.d.ts +81 -0
- package/src/types/modules.d.ts +2 -0
- package/src/types/portal.ts +69 -0
- package/src/utils/debug.ts +8 -0
- package/src/utils/license-error.ts +43 -0
- package/src/utils/redact.ts +25 -0
- package/src/workflow-runner-worker.ts +386 -0
- package/src/workflow-runner.ts +58 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-runner.js","sourceRoot":"","sources":["../src/workflow-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACjH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAgBxD,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,UAA4B,EAC5B,UAA8B,EAAE;IAEhC,MAAM,EACJ,UAAU,GAAG,KAAK,EAClB,UAAU,GAAG,CAAC,EACd,OAAO,GAAG,EAAE,EACZ,aAAa,GAAG,IAAI,EACpB,oBAAoB,GAAG,IAAI,GAC5B,GAAG,OAAO,CAAA;IAEX,MAAM,QAAQ,GAAG,IAAI,aAAa,EAAE,CAAA;IACpC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;IAEpE,iBAAiB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;IAEvC,IAAI,aAAa;QAAE,cAAc,EAAE,CAAA;IACnC,IAAI,oBAAoB,EAAE,CAAC;QACzB,eAAe,EAAE,CAAA;QACjB,gBAAgB,EAAE,CAAA;IACpB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAA;QACjC,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAA;QACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAA;QAChC,MAAM,iBAAiB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;QACpD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;IAC1B,CAAC;YAAS,CAAC;QACT,IAAI,aAAa;YAAE,YAAY,EAAE,CAAA;QACjC,IAAI,oBAAoB,EAAE,CAAC;YACzB,aAAa,EAAE,CAAA;YACf,cAAc,EAAE,CAAA;QAClB,CAAC;QACD,iBAAiB,CAAC,SAAS,CAAC,CAAA;IAC9B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# ElasticDash SDK — AI Coding Agent Instructions
|
|
2
|
+
|
|
3
|
+
> **Audience**: Coding agents (Claude Code, Cursor, Copilot, Codex, Windsurf, etc.) integrating `elasticdash-sdk` into a user's project.
|
|
4
|
+
>
|
|
5
|
+
> **When to use**: Follow these instructions when a user asks you to "integrate ElasticDash", "set up ElasticDash testing", "implement elasticdash-sdk", or similar.
|
|
6
|
+
>
|
|
7
|
+
> **Technical reference**: All templates, code patterns, and step-by-step implementation details are in the companion doc: [Integration Guide](./agent-integration-guide.md) (`node_modules/elasticdash-sdk/docs/agent-integration-guide.md`). Read it alongside these instructions.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## How to start
|
|
12
|
+
|
|
13
|
+
Tell your coding agent this prompt to begin:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
Integrate elasticdash-sdk into this project.
|
|
17
|
+
Read node_modules/elasticdash-sdk/docs/agent-coding-instructions.md for how to proceed,
|
|
18
|
+
and node_modules/elasticdash-sdk/docs/agent-integration-guide.md for technical reference.
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or if you used `npx elasticdash init-guide`:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Read AGENTS.md and follow it to integrate elasticdash-sdk into this project.
|
|
25
|
+
Also read node_modules/elasticdash-sdk/docs/agent-integration-guide.md for technical reference.
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Behavioral rules
|
|
31
|
+
|
|
32
|
+
- **Automation level**: Automatically implement all steps unless you are not confident about a specific change (e.g., unclear which function is a tool vs. a utility, or ambiguous workflow boundaries). In those cases, ask the user before proceeding. For straightforward tool/workflow functions, proceed without asking.
|
|
33
|
+
- **No placeholders**: Do NOT leave `YOUR_TOOL_NAME` / `YOUR_WORKFLOW_NAME` placeholders in generated files. Scan the codebase first and use real function names, imports, and types.
|
|
34
|
+
- **Modify source files**: The integration requires updating existing source files (route handlers, executors) to import tools from `ed_tools` and add trace hooks. This is expected — do not skip it.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Execution order
|
|
39
|
+
|
|
40
|
+
### Phase 1: Pre-flight checks
|
|
41
|
+
|
|
42
|
+
**1. Check `.env` for `ELASTICDASH_API_URL`**
|
|
43
|
+
|
|
44
|
+
- If present: use the existing value.
|
|
45
|
+
- If missing: add `ELASTICDASH_API_URL=https://server.elasticdash.com` to `.env`.
|
|
46
|
+
|
|
47
|
+
**2. Check `.env` for `ELASTICDASH_API_KEY`**
|
|
48
|
+
|
|
49
|
+
- If present: proceed.
|
|
50
|
+
- If missing: **STOP and ask the user**:
|
|
51
|
+
|
|
52
|
+
> "Your project needs an ElasticDash API key. Please complete the onboarding at https://app.elasticdash.com to get your project API key, then add `ELASTICDASH_API_KEY=ed_your_key_here` to your `.env` file. Let me know when it's ready."
|
|
53
|
+
|
|
54
|
+
**Do not continue until `ELASTICDASH_API_KEY` is set.** The SDK cannot connect to the backend without it.
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### Phase 2: Scan the codebase
|
|
58
|
+
|
|
59
|
+
Before creating any files, identify:
|
|
60
|
+
|
|
61
|
+
- **Tool functions**: Exported async functions that call external services (APIs, databases, search, etc.). Look for functions that use `fetch`, database clients, SDK calls, or any external I/O. These go in `ed_tools.ts`.
|
|
62
|
+
- **Workflow functions**: Exported async functions that orchestrate an AI pipeline — typically calling an LLM and one or more tools. Look for functions that call OpenAI, Anthropic, Gemini, or similar SDKs. These go in `ed_workflows.ts`.
|
|
63
|
+
- **Route handlers / entry points**: Files that call the tool and workflow functions above. These need import updates in Phase 3.
|
|
64
|
+
|
|
65
|
+
If the project has no clear tool or workflow functions yet, ask the user:
|
|
66
|
+
|
|
67
|
+
> "Which functions in your codebase make external API/service calls (tools), and which functions orchestrate your AI workflow? I need to know so I can set up ElasticDash instrumentation."
|
|
68
|
+
|
|
69
|
+
Also detect the project type (see [Integration Guide — Prerequisites](./agent-integration-guide.md#detect-project-type-before-starting)) to choose the right patterns.
|
|
70
|
+
|
|
71
|
+
### Phase 3: Implement
|
|
72
|
+
|
|
73
|
+
Follow the [Integration Guide](./agent-integration-guide.md) steps 1–7 in order, using real function names from Phase 2:
|
|
74
|
+
|
|
75
|
+
1. **Install** — `npm install elasticdash-sdk`, update `.gitignore`
|
|
76
|
+
2. **Create `ed_tools.ts`** — wrap each identified tool function with `wrapTool()`
|
|
77
|
+
3. **Create `ed_workflows.ts`** — add trace hooks (`edStartTrace`/`edEndTrace`) and workflow exports
|
|
78
|
+
4. **Update existing source files** — change imports from original sources to `ed_tools`, add trace hooks to route handlers
|
|
79
|
+
5. **Add config and scripts** — `elasticdash.config.ts`, `package.json` scripts
|
|
80
|
+
6. **Environment variables** — verify all required vars are in `.env`
|
|
81
|
+
7. **Write a test** (optional) — create a sample `.ai.test.ts` file if the user wants tests
|
|
82
|
+
|
|
83
|
+
**When modifying existing files (Step 4):**
|
|
84
|
+
|
|
85
|
+
- Search the codebase for every file that imports the original tool functions
|
|
86
|
+
- Update imports to come from `ed_tools` instead
|
|
87
|
+
- Add `edStartTrace`/`edEndTrace` to route handlers
|
|
88
|
+
- Do NOT modify `ed_tools.ts` imports (they must still reference original sources)
|
|
89
|
+
- Do NOT modify the original tool implementation files
|
|
90
|
+
- If unsure whether a function is a tool, ask the user
|
|
91
|
+
|
|
92
|
+
### Phase 4: Validate
|
|
93
|
+
|
|
94
|
+
Run the `observe` command to establish a socket.io connection to the ElasticDash backend:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npx elasticdash observe
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Expected output on success:**
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
[elasticdash] Observability active
|
|
104
|
+
Session ID : <uuid>
|
|
105
|
+
Server : https://server.elasticdash.com
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This confirms:
|
|
109
|
+
|
|
110
|
+
- `ELASTICDASH_API_URL` and `ELASTICDASH_API_KEY` are valid (backend authenticates the API key and returns `auth:ok`)
|
|
111
|
+
- The socket.io connection to the backend is established
|
|
112
|
+
- The SDK discovered and registered tools from `ed_tools.ts` and workflows from `ed_workflows.ts` (pushed to `POST /api/observability/catalog`)
|
|
113
|
+
|
|
114
|
+
**If it fails:** Check that `.env` has valid values. If the API key is rejected, the user needs to get a new one from https://app.elasticdash.com.
|
|
115
|
+
|
|
116
|
+
After validation, stop the observe process (Ctrl+C) and inform the user that ElasticDash is integrated. Provide these commands for ongoing use:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npx elasticdash test # Run aiTest tests
|
|
120
|
+
npx ed ed-test --no-upload # Run defineTest benchmarks
|
|
121
|
+
npx elasticdash dashboard # Open the dashboard
|
|
122
|
+
npx elasticdash observe # Start live tracing
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Decision guidance
|
|
128
|
+
|
|
129
|
+
When the integration guide offers multiple patterns, use these rules:
|
|
130
|
+
|
|
131
|
+
| Decision | Choose this | When |
|
|
132
|
+
|----------|-------------|------|
|
|
133
|
+
| Subprocess vs HTTP mode | HTTP mode | Project uses Next.js, Remix, SvelteKit, or similar framework |
|
|
134
|
+
| Subprocess vs HTTP mode | Subprocess (default) | Plain Node.js project, no framework |
|
|
135
|
+
| `wrapTool` vs manual pattern | `wrapTool` | Always prefer unless the project specifically needs mock support via `resolveMock` |
|
|
136
|
+
| Path alias handling | Advanced dashboard script | `tsconfig.json` has a `"paths"` field |
|
|
137
|
+
| `ed_agents.ts` | Create it | Project has a planner/executor agent pattern |
|
|
138
|
+
| `ed_agents.ts` | Skip it | No multi-step agent |
|
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
# ElasticDash SDK — Integration Guide
|
|
2
|
+
|
|
3
|
+
Technical reference for integrating `elasticdash-sdk` into a project. Contains all templates, code patterns, and step-by-step details.
|
|
4
|
+
|
|
5
|
+
> **For AI coding agents**: See [Agent Coding Instructions](./agent-coding-instructions.md) for behavioral rules, automation guidance, and execution order.
|
|
6
|
+
|
|
7
|
+
## How to start with a coding agent
|
|
8
|
+
|
|
9
|
+
Tell your coding agent this prompt:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Integrate elasticdash-sdk into this project.
|
|
13
|
+
Read node_modules/elasticdash-sdk/docs/agent-coding-instructions.md for how to proceed,
|
|
14
|
+
and node_modules/elasticdash-sdk/docs/agent-integration-guide.md for technical reference.
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
- Node.js >= 20
|
|
22
|
+
- npm, yarn, or pnpm
|
|
23
|
+
- At least one AI workflow function (a callable async function that makes LLM/tool calls)
|
|
24
|
+
- LLM provider API keys for providers used in workflows (e.g., `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`)
|
|
25
|
+
|
|
26
|
+
### Detect project type before starting
|
|
27
|
+
|
|
28
|
+
Check these before choosing patterns:
|
|
29
|
+
|
|
30
|
+
| Check | How | Result |
|
|
31
|
+
|-------|-----|--------|
|
|
32
|
+
| Module system | `package.json` → `"type"` field | `"module"` = ESM, `"commonjs"` or missing = CJS |
|
|
33
|
+
| Framework | Look for `next.config.*`, `remix.config.*`, `svelte.config.*` | Present = framework project, use HTTP mode |
|
|
34
|
+
| Path aliases | `tsconfig.json` → `"paths"` field | Present = need advanced dashboard script |
|
|
35
|
+
| Tool architecture | Does the project use a central `dispatchTool(name, args)` function? | Yes = Pattern A, No = Pattern B |
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Step 1: Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install elasticdash-sdk
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Add to `.gitignore`:
|
|
46
|
+
|
|
47
|
+
```gitignore
|
|
48
|
+
.temp/
|
|
49
|
+
.ed_traces/
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Step 2: Create `ed_tools.ts`
|
|
55
|
+
|
|
56
|
+
Create `ed_tools.ts` in the project root. This file wraps each tool function with `wrapTool()` for automatic tracing, mocking, and telemetry.
|
|
57
|
+
|
|
58
|
+
### Template
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
// ed_tools.ts
|
|
62
|
+
import { setElasticDashModule } from './ed_workflows'
|
|
63
|
+
|
|
64
|
+
// Import original tool implementations from the actual source files
|
|
65
|
+
import { originalTool1 } from './services/YOUR_SOURCE_1'
|
|
66
|
+
import { originalTool2 } from './utils/YOUR_SOURCE_2'
|
|
67
|
+
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
// Load elasticdash-sdk and share the module with ed_workflows.ts
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
73
|
+
type WrapToolFn = <T extends (...args: any[]) => any>(name: string, fn: T) => T
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
75
|
+
let wrapTool: WrapToolFn = (_name: string, fn: any) => fn
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
79
|
+
const _edModule = (eval('require') as (id: string) => any)('elasticdash-sdk')
|
|
80
|
+
wrapTool = _edModule.wrapTool ?? wrapTool
|
|
81
|
+
// Share the module instance with ed_workflows.ts so trace hooks use the same context
|
|
82
|
+
setElasticDashModule(_edModule)
|
|
83
|
+
} catch {
|
|
84
|
+
// elasticdash-sdk not available — all wrappers pass through to original functions
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Wrapped tools — one export per tool
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
export const myTool1 = wrapTool('myTool1', async (input: any) => {
|
|
92
|
+
return await originalTool1(input)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
export const myTool2 = wrapTool('myTool2', async (input: any) => {
|
|
96
|
+
const { someField } = input as { someField: string }
|
|
97
|
+
return await originalTool2(someField)
|
|
98
|
+
})
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Key patterns
|
|
102
|
+
|
|
103
|
+
- **`wrapTool(name, fn)`** wraps the function with automatic tracing, mocking, and telemetry. Falls back to a passthrough if `elasticdash-sdk` is not installed.
|
|
104
|
+
- **`eval('require')`** is used instead of `import()` to share the same module instance across `ed_tools.ts` and `ed_workflows.ts`. This avoids ESM/CJS dual-instance issues.
|
|
105
|
+
- **`setElasticDashModule`** shares the loaded module with `ed_workflows.ts` so `edStartTrace`/`edEndTrace` use the same tracing context as `wrapTool`.
|
|
106
|
+
- The exported name (e.g., `myTool1`) can differ from the original function name (e.g., `originalTool1`). The call sites in existing source files will be updated to use the new name in Step 4.
|
|
107
|
+
|
|
108
|
+
### Important rules
|
|
109
|
+
|
|
110
|
+
- The string name passed to `wrapTool()` **must match** the exported function name exactly.
|
|
111
|
+
- Each tool function must accept a single input object and return a plain value (JSON-serializable).
|
|
112
|
+
- Tool functions must not close over HTTP context, framework state, or database clients — extract pure logic first.
|
|
113
|
+
|
|
114
|
+
### Next.js only
|
|
115
|
+
|
|
116
|
+
Add `elasticdash-sdk` to `serverExternalPackages` in `next.config.ts`:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
// next.config.ts
|
|
120
|
+
const nextConfig = {
|
|
121
|
+
serverExternalPackages: ['elasticdash-sdk'],
|
|
122
|
+
}
|
|
123
|
+
export default nextConfig
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Step 3: Create `ed_workflows.ts`
|
|
129
|
+
|
|
130
|
+
Create `ed_workflows.ts` in the project root. This file serves two purposes:
|
|
131
|
+
|
|
132
|
+
1. **Trace lifecycle hooks** (`edStartTrace`, `edEndTrace`) — called from route handlers to mark workflow boundaries
|
|
133
|
+
2. **Workflow exports** — callable functions for the ElasticDash dashboard and test runner
|
|
134
|
+
|
|
135
|
+
### Trace lifecycle hooks
|
|
136
|
+
|
|
137
|
+
Every `ed_workflows.ts` should export `edStartTrace` and `edEndTrace`. These are called from route handlers (Step 4) to mark when a workflow starts and ends:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
// ed_workflows.ts — trace hooks (copy as-is)
|
|
141
|
+
|
|
142
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
143
|
+
let _ed: any = null
|
|
144
|
+
|
|
145
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
146
|
+
export function setElasticDashModule(mod: any): void {
|
|
147
|
+
_ed = mod
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export const edStartTrace = async (workflowName: string): Promise<void> => {
|
|
151
|
+
if (!_ed) return
|
|
152
|
+
try {
|
|
153
|
+
await _ed.tryAutoInitHttpContext()
|
|
154
|
+
_ed.startTrace(workflowName)
|
|
155
|
+
} catch (err) {
|
|
156
|
+
console.error('[ed_workflows] edStartTrace error:', err)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export const edEndTrace = (): void => {
|
|
161
|
+
if (!_ed) return
|
|
162
|
+
try {
|
|
163
|
+
_ed.endTrace()
|
|
164
|
+
} catch (err) {
|
|
165
|
+
console.error('[ed_workflows] edEndTrace error:', err)
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Workflow exports — simple case
|
|
171
|
+
|
|
172
|
+
For non-framework projects where the workflow can be imported directly:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
// ed_workflows.ts
|
|
176
|
+
export { YOUR_WORKFLOW } from './YOUR_SOURCE_PATH'
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Workflow exports — HTTP mode (Next.js / Remix / framework projects)
|
|
180
|
+
|
|
181
|
+
For framework projects, the workflow calls the running dev server instead of importing the route handler:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
// ed_workflows.ts
|
|
185
|
+
|
|
186
|
+
const APP_URL = process.env.APP_URL ?? 'http://localhost:3000'
|
|
187
|
+
|
|
188
|
+
export const YOUR_WORKFLOW = async (input: {
|
|
189
|
+
messages: Array<{ role: string; content: string }>
|
|
190
|
+
sessionId?: string
|
|
191
|
+
}): Promise<unknown> => {
|
|
192
|
+
const response = await fetch(`${APP_URL}/api/YOUR_ENDPOINT`, {
|
|
193
|
+
method: 'POST',
|
|
194
|
+
headers: { 'Content-Type': 'application/json' },
|
|
195
|
+
body: JSON.stringify(input),
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
if (!response.ok) {
|
|
199
|
+
const text = await response.text()
|
|
200
|
+
throw new Error(`HTTP ${response.status}: ${text}`)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return response.json()
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Requirements for all workflow exports
|
|
208
|
+
|
|
209
|
+
- Accept only JSON-serializable inputs (strings, numbers, arrays, plain objects)
|
|
210
|
+
- Return only JSON-serializable outputs
|
|
211
|
+
- Must not depend on framework runtime APIs, HTTP request context, or live service clients
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Step 4: Update existing source files to use `ed_tools`
|
|
216
|
+
|
|
217
|
+
> **This step modifies the user's existing source files.** The files that call tool functions must import from `ed_tools` instead of the original source, so that all tool calls go through the ElasticDash tracing layer. Similarly, workflow entry points (route handlers, etc.) must call `edStartTrace` / `edEndTrace` from `ed_workflows`.
|
|
218
|
+
|
|
219
|
+
### Architecture after integration
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
ed_tools.ts
|
|
223
|
+
├── imports original functions from services/utils
|
|
224
|
+
├── wraps each with wrapTool() for tracing
|
|
225
|
+
└── exports wrapped versions with the SAME or similar names
|
|
226
|
+
|
|
227
|
+
ed_workflows.ts
|
|
228
|
+
├── exports edStartTrace / edEndTrace for workflow-level tracing
|
|
229
|
+
└── exports workflow functions (for dashboard/test runner)
|
|
230
|
+
|
|
231
|
+
Existing source files (MODIFIED):
|
|
232
|
+
app/api/chat/route.ts
|
|
233
|
+
├── BEFORE: import { myTool } from '@/services/myService'
|
|
234
|
+
├── AFTER: import { myTool } from '@/ed_tools'
|
|
235
|
+
├── ADDED: import { edStartTrace, edEndTrace } from '@/ed_workflows'
|
|
236
|
+
└── ADDED: await edStartTrace('workflowName') at handler entry
|
|
237
|
+
edEndTrace() at handler exit
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### What to do
|
|
241
|
+
|
|
242
|
+
**1. Find every file that calls a tool function and update its imports:**
|
|
243
|
+
|
|
244
|
+
For each tool exported from `ed_tools.ts`, search the codebase for files that import the original function. Update the import to come from `ed_tools` instead.
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
// BEFORE — app/api/chat/route.ts
|
|
248
|
+
import { clarifyAndRefineUserInput } from '@/utils/queryRefinement'
|
|
249
|
+
import { dynamicApiRequest } from '@/services/apiService'
|
|
250
|
+
|
|
251
|
+
// AFTER — app/api/chat/route.ts
|
|
252
|
+
import { queryRefinement } from '@/ed_tools'
|
|
253
|
+
import { apiService } from '@/ed_tools'
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
// BEFORE — app/api/chat/executor.ts
|
|
258
|
+
import { dynamicApiRequest } from '@/services/apiService'
|
|
259
|
+
|
|
260
|
+
// AFTER — app/api/chat/executor.ts
|
|
261
|
+
import { apiService } from '@/ed_tools'
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**2. Add trace hooks to route handlers / workflow entry points:**
|
|
265
|
+
|
|
266
|
+
At the top of each route handler or workflow entry function, add `edStartTrace` and `edEndTrace`:
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
// app/api/chat/route.ts
|
|
270
|
+
import { edStartTrace, edEndTrace } from '@/ed_workflows'
|
|
271
|
+
|
|
272
|
+
export async function POST(req: Request) {
|
|
273
|
+
await edStartTrace('chatHandler')
|
|
274
|
+
try {
|
|
275
|
+
// ... existing handler logic, now using tools from ed_tools
|
|
276
|
+
} finally {
|
|
277
|
+
edEndTrace()
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**3. Update call sites if the wrapped function has a different name:**
|
|
283
|
+
|
|
284
|
+
If `ed_tools.ts` exports a tool under a different name than the original (e.g., `queryRefinement` wrapping `clarifyAndRefineUserInput`), update the call sites to use the new name.
|
|
285
|
+
|
|
286
|
+
### What NOT to modify
|
|
287
|
+
|
|
288
|
+
- **Do not modify `ed_tools.ts` imports** — it must still import from the original source files.
|
|
289
|
+
- **Do not modify the original tool implementation files** (e.g., `services/apiService.ts`, `utils/queryRefinement.ts`) — they stay as-is.
|
|
290
|
+
- **Do not modify files that don't call tool functions** — only update files that directly import and call the wrapped tools.
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## Step 5: Add config and scripts
|
|
295
|
+
|
|
296
|
+
### `elasticdash.config.ts`
|
|
297
|
+
|
|
298
|
+
Create in project root:
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
// elasticdash.config.ts
|
|
302
|
+
export default {
|
|
303
|
+
testMatch: ['**/*.ai.test.ts'],
|
|
304
|
+
traceMode: 'local' as const,
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### `package.json` scripts
|
|
309
|
+
|
|
310
|
+
Add these scripts:
|
|
311
|
+
|
|
312
|
+
```json
|
|
313
|
+
{
|
|
314
|
+
"scripts": {
|
|
315
|
+
"dashboard:ai": "elasticdash dashboard",
|
|
316
|
+
"test:ai": "elasticdash test"
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**If the project uses TypeScript path aliases** (e.g., `@/lib/...` in `tsconfig.json` `paths`):
|
|
322
|
+
|
|
323
|
+
```json
|
|
324
|
+
{
|
|
325
|
+
"scripts": {
|
|
326
|
+
"dashboard:ai": "NODE_OPTIONS='--import tsx/esm --require tsx/cjs --require tsconfig-paths/register' elasticdash dashboard"
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## Step 6: Environment variables
|
|
334
|
+
|
|
335
|
+
Set in `.env` or CI secrets:
|
|
336
|
+
|
|
337
|
+
| Variable | Description | Required |
|
|
338
|
+
|----------|-------------|----------|
|
|
339
|
+
| `ELASTICDASH_API_URL` | Backend server URL (`https://server.elasticdash.com` for cloud) | For upload/CI |
|
|
340
|
+
| `ELASTICDASH_API_KEY` | Project API key from dashboard | For upload/CI |
|
|
341
|
+
| `ELASTICDASH_DEBUG` | Set to `1` to enable SDK debug logging (default: off) | Optional |
|
|
342
|
+
| `ELASTICDASH_CAPTURE_TRACE` | Set to `1` to record trace fixtures to disk (default: off) | Optional |
|
|
343
|
+
| `ELASTICDASH_ACCEPT_RERUNS` | Set to `false`/`0` to reject rerun requests (default: on) | Optional |
|
|
344
|
+
| `OPENAI_API_KEY` | OpenAI API key | If using OpenAI |
|
|
345
|
+
| `ANTHROPIC_API_KEY` | Anthropic API key | If using Claude |
|
|
346
|
+
| `GEMINI_API_KEY` | Google Gemini API key | If using Gemini |
|
|
347
|
+
| `GROK_API_KEY` | xAI Grok API key | If using Grok |
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## Step 7: Write a test
|
|
352
|
+
|
|
353
|
+
### Option A: `aiTest` — live workflow testing
|
|
354
|
+
|
|
355
|
+
Create a file ending in `.ai.test.ts`:
|
|
356
|
+
|
|
357
|
+
```ts
|
|
358
|
+
// tests/YOUR_WORKFLOW.ai.test.ts
|
|
359
|
+
import 'elasticdash-sdk/dist/test-setup.js'
|
|
360
|
+
import { expect } from 'expect'
|
|
361
|
+
|
|
362
|
+
// Import your workflow from ed_workflows.ts
|
|
363
|
+
import { YOUR_WORKFLOW } from '../ed_workflows'
|
|
364
|
+
|
|
365
|
+
aiTest('YOUR_TEST_NAME', async (ctx) => {
|
|
366
|
+
await YOUR_WORKFLOW({ /* your input */ })
|
|
367
|
+
|
|
368
|
+
// Assert an LLM step occurred
|
|
369
|
+
expect(ctx.trace).toHaveLLMStep({ model: 'gpt-4' })
|
|
370
|
+
|
|
371
|
+
// Assert a tool was called
|
|
372
|
+
expect(ctx.trace).toCallTool('YOUR_TOOL_NAME')
|
|
373
|
+
|
|
374
|
+
// Semantic output matching (LLM-judged)
|
|
375
|
+
expect(ctx.trace).toMatchSemanticOutput('expected output description')
|
|
376
|
+
})
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Option B: `defineTest` — CI/CD fixture-based testing
|
|
380
|
+
|
|
381
|
+
First, record a trace:
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
ELASTICDASH_CAPTURE_TRACE=1 tsx YOUR_WORKFLOW_SCRIPT.ts
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
Then create `ed_tests.ts`:
|
|
388
|
+
|
|
389
|
+
```ts
|
|
390
|
+
// ed_tests.ts
|
|
391
|
+
import { defineTest } from 'elasticdash-sdk'
|
|
392
|
+
import { YOUR_WORKFLOW } from './ed_workflows'
|
|
393
|
+
|
|
394
|
+
defineTest({
|
|
395
|
+
name: 'YOUR_TEST_NAME',
|
|
396
|
+
trace: './.ed_traces/YOUR_TRACE_FILE.json',
|
|
397
|
+
target: { type: 'tool_call', step_id: 'tool_call_0' },
|
|
398
|
+
benchmarks: { max_duration_ms: 2000 },
|
|
399
|
+
run: async () => {
|
|
400
|
+
await YOUR_WORKFLOW({ /* your input */ })
|
|
401
|
+
},
|
|
402
|
+
})
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Run:
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
npx ed ed-test --no-upload
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
## Step 8: Validate the integration
|
|
414
|
+
|
|
415
|
+
After all files are created, validate the setup by establishing a socket.io connection to the ElasticDash backend. Run the `observe` command — it connects to the server, authenticates with the API key, and registers the project's tools and workflows:
|
|
416
|
+
|
|
417
|
+
```bash
|
|
418
|
+
npx elasticdash observe
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
**Expected output on success:**
|
|
422
|
+
|
|
423
|
+
```
|
|
424
|
+
[elasticdash] Observability active
|
|
425
|
+
Session ID : <uuid>
|
|
426
|
+
Server : https://server.elasticdash.com
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
This confirms:
|
|
430
|
+
- `ELASTICDASH_API_URL` and `ELASTICDASH_API_KEY` are valid
|
|
431
|
+
- The socket.io connection to the backend is established
|
|
432
|
+
- The SDK can discover `ed_tools.ts` and `ed_workflows.ts`
|
|
433
|
+
|
|
434
|
+
**If it fails:** Check that `.env` has valid `ELASTICDASH_API_URL` and `ELASTICDASH_API_KEY` values. If the API key is rejected, the user needs to get a new one from https://app.elasticdash.com.
|
|
435
|
+
|
|
436
|
+
After validation, stop the observe process (Ctrl+C) and inform the user that ElasticDash is integrated. Provide these commands for ongoing use:
|
|
437
|
+
|
|
438
|
+
```bash
|
|
439
|
+
# Run aiTest tests
|
|
440
|
+
npx elasticdash test
|
|
441
|
+
|
|
442
|
+
# Run defineTest benchmarks
|
|
443
|
+
npx ed ed-test --no-upload
|
|
444
|
+
|
|
445
|
+
# Open the dashboard
|
|
446
|
+
npx elasticdash dashboard
|
|
447
|
+
|
|
448
|
+
# Start observability (connect to backend for live tracing)
|
|
449
|
+
npx elasticdash observe
|
|
450
|
+
|
|
451
|
+
# Record a trace fixture
|
|
452
|
+
ELASTICDASH_CAPTURE_TRACE=1 tsx your-workflow.ts
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## Decision Trees
|
|
458
|
+
|
|
459
|
+
### Subprocess mode vs HTTP mode
|
|
460
|
+
|
|
461
|
+
```
|
|
462
|
+
Does your workflow live inside a framework route handler (Next.js, Remix, SvelteKit)?
|
|
463
|
+
YES → Use HTTP mode:
|
|
464
|
+
1. Configure workflow in elasticdash.config.ts with mode: 'http'
|
|
465
|
+
2. Add initHttpRunContext() to your request handler
|
|
466
|
+
3. Use wrapTool/wrapAI for observability
|
|
467
|
+
NO → Use subprocess mode (default):
|
|
468
|
+
1. Export workflow from ed_workflows.ts
|
|
469
|
+
2. Tools auto-intercepted via ed_tools.ts
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### HTTP mode config template
|
|
473
|
+
|
|
474
|
+
```ts
|
|
475
|
+
// elasticdash.config.ts
|
|
476
|
+
export default {
|
|
477
|
+
testMatch: ['**/*.ai.test.ts'],
|
|
478
|
+
workflows: {
|
|
479
|
+
YOUR_WORKFLOW: {
|
|
480
|
+
mode: 'http',
|
|
481
|
+
url: 'http://localhost:3001/api/YOUR_ENDPOINT',
|
|
482
|
+
method: 'POST',
|
|
483
|
+
headers: {
|
|
484
|
+
'Content-Type': 'application/json',
|
|
485
|
+
},
|
|
486
|
+
bodyTemplate: {
|
|
487
|
+
messages: [{ role: 'user', content: '{{input.message}}' }],
|
|
488
|
+
},
|
|
489
|
+
responseFormat: 'vercel-ai-stream',
|
|
490
|
+
},
|
|
491
|
+
},
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### HTTP mode handler setup
|
|
496
|
+
|
|
497
|
+
```ts
|
|
498
|
+
// app/api/YOUR_ENDPOINT/route.ts
|
|
499
|
+
import { initHttpRunContext, wrapTool, wrapAI } from 'elasticdash-sdk'
|
|
500
|
+
|
|
501
|
+
export async function POST(req: Request) {
|
|
502
|
+
const runId = req.headers.get('x-elasticdash-run-id')
|
|
503
|
+
const serverUrl = req.headers.get('x-elasticdash-server')
|
|
504
|
+
if (runId && serverUrl) {
|
|
505
|
+
await initHttpRunContext(runId, serverUrl)
|
|
506
|
+
}
|
|
507
|
+
// ... rest of handler
|
|
508
|
+
}
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### AI call recording
|
|
512
|
+
|
|
513
|
+
```
|
|
514
|
+
Does your workflow call LLMs via OpenAI/Gemini/Grok SDKs?
|
|
515
|
+
YES → Automatic interception, no code changes needed
|
|
516
|
+
NO (custom provider or Anthropic SDK) → Use wrapAI:
|
|
517
|
+
import { wrapAI } from 'elasticdash-sdk'
|
|
518
|
+
export const callLLM = wrapAI('model-name', async (messages) => {
|
|
519
|
+
return await yourLLMClient.call(messages)
|
|
520
|
+
})
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Agent setup (`ed_agents.ts`)
|
|
524
|
+
|
|
525
|
+
```
|
|
526
|
+
Does your project use a multi-step agent with a planner/executor pattern?
|
|
527
|
+
YES → Create ed_agents.ts:
|
|
528
|
+
export { plannerAgent, executorAgent } from './your-agent-logic'
|
|
529
|
+
// OR use SDK reference implementations:
|
|
530
|
+
export { plannerAgent, executorAgent, resumeAgentFromTrace } from 'elasticdash-sdk'
|
|
531
|
+
NO → Skip ed_agents.ts
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
---
|
|
535
|
+
|
|
536
|
+
## Troubleshooting
|
|
537
|
+
|
|
538
|
+
| Error | Cause | Fix |
|
|
539
|
+
|-------|-------|-----|
|
|
540
|
+
| `replay miss: tool_call::YOUR_TOOL` | Trace fixture is stale or workflow changed | Re-record: `ELASTICDASH_CAPTURE_TRACE=1 tsx your-workflow.ts` |
|
|
541
|
+
| `MODULE_NOT_FOUND: elasticdash-sdk` | SDK not installed or Next.js bundling issue | Run `npm install elasticdash-sdk`. For Next.js, add to `serverExternalPackages` |
|
|
542
|
+
| `Cannot find module '@/...'` | Path aliases not resolved at runtime | Use advanced dashboard script with `tsconfig-paths/register` |
|
|
543
|
+
| `test has no run function` | `run` field missing in `defineTest` | Add `run: async () => { ... }` to the test definition |
|
|
544
|
+
| `Tool "x" not found in registry` | Tool not exported from `ed_tools.ts` | Export the tool function from `ed_tools.ts` |
|
|
545
|
+
| `ERR_UNKNOWN_FILE_EXTENSION` | ESM/CJS mismatch | Check `package.json` `type` field and `tsconfig.json` `module` setting |
|
|
546
|
+
| Git metadata shows `unknown` | No `.git` directory | Ensure repo is checked out (common in CI with shallow clones) |
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
## Final checklist
|
|
551
|
+
|
|
552
|
+
After integration, verify these files exist:
|
|
553
|
+
|
|
554
|
+
```
|
|
555
|
+
your-project/
|
|
556
|
+
.env # ELASTICDASH_API_URL and ELASTICDASH_API_KEY set
|
|
557
|
+
ed_tools.ts # Instrumented tool wrappers (real function names, not placeholders)
|
|
558
|
+
ed_workflows.ts # Workflow exports using tools from ed_tools.ts
|
|
559
|
+
elasticdash.config.ts # Test runner config
|
|
560
|
+
package.json # dashboard:ai and test:ai scripts added
|
|
561
|
+
.gitignore # .temp/ and .ed_traces/ added
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
Verify by running `npx elasticdash observe` — a successful socket.io connection confirms the integration is complete.
|