@agentlensai/server 0.11.0 → 0.13.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/dist/cloud/auth/rbac.d.ts +1 -1
- package/dist/cloud/auth/rbac.d.ts.map +1 -1
- package/dist/cloud/auth/rbac.js +2 -2
- package/dist/cloud/auth/rbac.js.map +1 -1
- package/dist/cloud/billing/stripe-client.d.ts.map +1 -1
- package/dist/cloud/billing/stripe-client.js +6 -1
- package/dist/cloud/billing/stripe-client.js.map +1 -1
- package/dist/cloud/ingestion/gateway.d.ts.map +1 -1
- package/dist/cloud/ingestion/gateway.js +0 -1
- package/dist/cloud/ingestion/gateway.js.map +1 -1
- package/dist/cloud/middleware/validate-org-access.d.ts +14 -0
- package/dist/cloud/middleware/validate-org-access.d.ts.map +1 -0
- package/dist/cloud/middleware/validate-org-access.js +38 -0
- package/dist/cloud/middleware/validate-org-access.js.map +1 -0
- package/dist/cloud/routes/index.d.ts +13 -0
- package/dist/cloud/routes/index.d.ts.map +1 -0
- package/dist/cloud/routes/index.js +98 -0
- package/dist/cloud/routes/index.js.map +1 -0
- package/dist/config.d.ts +33 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +71 -1
- package/dist/config.js.map +1 -1
- package/dist/db/api-key-lookup.d.ts +25 -0
- package/dist/db/api-key-lookup.d.ts.map +1 -0
- package/dist/db/api-key-lookup.js +38 -0
- package/dist/db/api-key-lookup.js.map +1 -0
- package/dist/db/connection.postgres.d.ts +44 -0
- package/dist/db/connection.postgres.d.ts.map +1 -0
- package/dist/db/connection.postgres.js +79 -0
- package/dist/db/connection.postgres.js.map +1 -0
- package/dist/db/cost-budget-store.d.ts +30 -0
- package/dist/db/cost-budget-store.d.ts.map +1 -0
- package/dist/db/cost-budget-store.js +201 -0
- package/dist/db/cost-budget-store.js.map +1 -0
- package/dist/db/drizzle/0000_initial.sql +336 -0
- package/dist/db/drizzle/0001_indexes.sql +20 -0
- package/dist/db/drizzle/0002_pgvector.sql +19 -0
- package/dist/db/drizzle/drizzle/0000_initial.sql +336 -0
- package/dist/db/drizzle/drizzle/0001_indexes.sql +20 -0
- package/dist/db/drizzle/drizzle/0002_pgvector.sql +19 -0
- package/dist/db/drizzle/drizzle/meta/0000_snapshot.json +2593 -0
- package/dist/db/drizzle/drizzle/meta/_journal.json +27 -0
- package/dist/db/drizzle/meta/0000_snapshot.json +2593 -0
- package/dist/db/drizzle/meta/_journal.json +27 -0
- package/dist/db/embedding-store.d.ts +2 -1
- package/dist/db/embedding-store.d.ts.map +1 -1
- package/dist/db/embedding-store.interface.d.ts +19 -0
- package/dist/db/embedding-store.interface.d.ts.map +1 -0
- package/dist/db/embedding-store.interface.js +7 -0
- package/dist/db/embedding-store.interface.js.map +1 -0
- package/dist/db/embedding-store.js +3 -1
- package/dist/db/embedding-store.js.map +1 -1
- package/dist/db/eval-store.d.ts +88 -0
- package/dist/db/eval-store.d.ts.map +1 -0
- package/dist/db/eval-store.js +408 -0
- package/dist/db/eval-store.js.map +1 -0
- package/dist/db/guardrail-store.d.ts +9 -0
- package/dist/db/guardrail-store.d.ts.map +1 -1
- package/dist/db/guardrail-store.js +57 -3
- package/dist/db/guardrail-store.js.map +1 -1
- package/dist/db/index.d.ts +7 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +4 -12
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrate.d.ts +5 -22
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +7 -637
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/migrate.postgres.d.ts +16 -0
- package/dist/db/migrate.postgres.d.ts.map +1 -0
- package/dist/db/migrate.postgres.js +23 -0
- package/dist/db/migrate.postgres.js.map +1 -0
- package/dist/db/migrate.sqlite.d.ts +26 -0
- package/dist/db/migrate.sqlite.d.ts.map +1 -0
- package/dist/db/migrate.sqlite.js +920 -0
- package/dist/db/migrate.sqlite.js.map +1 -0
- package/dist/db/postgres-embedding-store.d.ts +23 -0
- package/dist/db/postgres-embedding-store.d.ts.map +1 -0
- package/dist/db/postgres-embedding-store.js +218 -0
- package/dist/db/postgres-embedding-store.js.map +1 -0
- package/dist/db/postgres-store.d.ts +80 -0
- package/dist/db/postgres-store.d.ts.map +1 -0
- package/dist/db/postgres-store.js +910 -0
- package/dist/db/postgres-store.js.map +1 -0
- package/dist/db/prompt-store.d.ts +57 -0
- package/dist/db/prompt-store.d.ts.map +1 -0
- package/dist/db/prompt-store.js +300 -0
- package/dist/db/prompt-store.js.map +1 -0
- package/dist/db/repositories/agent-repository.d.ts +21 -0
- package/dist/db/repositories/agent-repository.d.ts.map +1 -0
- package/dist/db/repositories/agent-repository.js +142 -0
- package/dist/db/repositories/agent-repository.js.map +1 -0
- package/dist/db/repositories/alert-repository.d.ts +27 -0
- package/dist/db/repositories/alert-repository.d.ts.map +1 -0
- package/dist/db/repositories/alert-repository.js +164 -0
- package/dist/db/repositories/alert-repository.js.map +1 -0
- package/dist/db/repositories/analytics-repository.d.ts +24 -0
- package/dist/db/repositories/analytics-repository.d.ts.map +1 -0
- package/dist/db/repositories/analytics-repository.js +147 -0
- package/dist/db/repositories/analytics-repository.js.map +1 -0
- package/dist/db/repositories/event-repository.d.ts +81 -0
- package/dist/db/repositories/event-repository.d.ts.map +1 -0
- package/dist/db/repositories/event-repository.js +331 -0
- package/dist/db/repositories/event-repository.js.map +1 -0
- package/dist/db/repositories/notification-channel-repository.d.ts +28 -0
- package/dist/db/repositories/notification-channel-repository.d.ts.map +1 -0
- package/dist/db/repositories/notification-channel-repository.js +151 -0
- package/dist/db/repositories/notification-channel-repository.js.map +1 -0
- package/dist/db/repositories/session-repository.d.ts +26 -0
- package/dist/db/repositories/session-repository.d.ts.map +1 -0
- package/dist/db/repositories/session-repository.js +240 -0
- package/dist/db/repositories/session-repository.js.map +1 -0
- package/dist/db/schema.postgres.d.ts +4681 -0
- package/dist/db/schema.postgres.d.ts.map +1 -0
- package/dist/db/schema.postgres.js +458 -0
- package/dist/db/schema.postgres.js.map +1 -0
- package/dist/db/schema.sqlite.d.ts +2221 -671
- package/dist/db/schema.sqlite.d.ts.map +1 -1
- package/dist/db/schema.sqlite.js +137 -2
- package/dist/db/schema.sqlite.js.map +1 -1
- package/dist/db/services/retention-service.d.ts +13 -0
- package/dist/db/services/retention-service.d.ts.map +1 -0
- package/dist/db/services/retention-service.js +48 -0
- package/dist/db/services/retention-service.js.map +1 -0
- package/dist/db/shared/query-helpers.d.ts +32 -0
- package/dist/db/shared/query-helpers.d.ts.map +1 -0
- package/dist/db/shared/query-helpers.js +180 -0
- package/dist/db/shared/query-helpers.js.map +1 -0
- package/dist/db/sqlite-store.d.ts +48 -55
- package/dist/db/sqlite-store.d.ts.map +1 -1
- package/dist/db/sqlite-store.js +78 -945
- package/dist/db/sqlite-store.js.map +1 -1
- package/dist/db/tenant-scoped-store.d.ts +18 -1
- package/dist/db/tenant-scoped-store.d.ts.map +1 -1
- package/dist/db/tenant-scoped-store.js +6 -0
- package/dist/db/tenant-scoped-store.js.map +1 -1
- package/dist/index.d.ts +28 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +432 -97
- package/dist/index.js.map +1 -1
- package/dist/lib/alert-engine.d.ts +10 -0
- package/dist/lib/alert-engine.d.ts.map +1 -1
- package/dist/lib/alert-engine.js +73 -20
- package/dist/lib/alert-engine.js.map +1 -1
- package/dist/lib/audit-verify.d.ts +40 -0
- package/dist/lib/audit-verify.d.ts.map +1 -0
- package/dist/lib/audit-verify.js +128 -0
- package/dist/lib/audit-verify.js.map +1 -0
- package/dist/lib/audit.d.ts +37 -0
- package/dist/lib/audit.d.ts.map +1 -0
- package/dist/lib/audit.js +59 -0
- package/dist/lib/audit.js.map +1 -0
- package/dist/lib/budget-engine.d.ts +26 -0
- package/dist/lib/budget-engine.d.ts.map +1 -0
- package/dist/lib/budget-engine.js +201 -0
- package/dist/lib/budget-engine.js.map +1 -0
- package/dist/lib/compliance-export.d.ts +41 -0
- package/dist/lib/compliance-export.d.ts.map +1 -0
- package/dist/lib/compliance-export.js +124 -0
- package/dist/lib/compliance-export.js.map +1 -0
- package/dist/lib/compliance-report.d.ts +87 -0
- package/dist/lib/compliance-report.d.ts.map +1 -0
- package/dist/lib/compliance-report.js +148 -0
- package/dist/lib/compliance-report.js.map +1 -0
- package/dist/lib/context/retrieval.d.ts +5 -3
- package/dist/lib/context/retrieval.d.ts.map +1 -1
- package/dist/lib/context/retrieval.js +5 -2
- package/dist/lib/context/retrieval.js.map +1 -1
- package/dist/lib/cost-anomaly-detector.d.ts +23 -0
- package/dist/lib/cost-anomaly-detector.d.ts.map +1 -0
- package/dist/lib/cost-anomaly-detector.js +108 -0
- package/dist/lib/cost-anomaly-detector.js.map +1 -0
- package/dist/lib/db-resilience.d.ts +15 -0
- package/dist/lib/db-resilience.d.ts.map +1 -0
- package/dist/lib/db-resilience.js +49 -0
- package/dist/lib/db-resilience.js.map +1 -0
- package/dist/lib/diagnostics/cache.d.ts +29 -0
- package/dist/lib/diagnostics/cache.d.ts.map +1 -0
- package/dist/lib/diagnostics/cache.js +88 -0
- package/dist/lib/diagnostics/cache.js.map +1 -0
- package/dist/lib/diagnostics/context-builder.d.ts +41 -0
- package/dist/lib/diagnostics/context-builder.d.ts.map +1 -0
- package/dist/lib/diagnostics/context-builder.js +135 -0
- package/dist/lib/diagnostics/context-builder.js.map +1 -0
- package/dist/lib/diagnostics/index.d.ts +34 -0
- package/dist/lib/diagnostics/index.d.ts.map +1 -0
- package/dist/lib/diagnostics/index.js +223 -0
- package/dist/lib/diagnostics/index.js.map +1 -0
- package/dist/lib/diagnostics/llm-client.d.ts +24 -0
- package/dist/lib/diagnostics/llm-client.d.ts.map +1 -0
- package/dist/lib/diagnostics/llm-client.js +42 -0
- package/dist/lib/diagnostics/llm-client.js.map +1 -0
- package/dist/lib/diagnostics/prompt-templates.d.ts +18 -0
- package/dist/lib/diagnostics/prompt-templates.d.ts.map +1 -0
- package/dist/lib/diagnostics/prompt-templates.js +144 -0
- package/dist/lib/diagnostics/prompt-templates.js.map +1 -0
- package/dist/lib/diagnostics/providers/anthropic.d.ts +8 -0
- package/dist/lib/diagnostics/providers/anthropic.d.ts.map +1 -0
- package/dist/lib/diagnostics/providers/anthropic.js +79 -0
- package/dist/lib/diagnostics/providers/anthropic.js.map +1 -0
- package/dist/lib/diagnostics/providers/openai.d.ts +8 -0
- package/dist/lib/diagnostics/providers/openai.d.ts.map +1 -0
- package/dist/lib/diagnostics/providers/openai.js +70 -0
- package/dist/lib/diagnostics/providers/openai.js.map +1 -0
- package/dist/lib/diagnostics/providers/types.d.ts +23 -0
- package/dist/lib/diagnostics/providers/types.d.ts.map +1 -0
- package/dist/lib/diagnostics/providers/types.js +5 -0
- package/dist/lib/diagnostics/providers/types.js.map +1 -0
- package/dist/lib/diagnostics/response-parser.d.ts +60 -0
- package/dist/lib/diagnostics/response-parser.d.ts.map +1 -0
- package/dist/lib/diagnostics/response-parser.js +55 -0
- package/dist/lib/diagnostics/response-parser.js.map +1 -0
- package/dist/lib/diagnostics/types.d.ts +60 -0
- package/dist/lib/diagnostics/types.d.ts.map +1 -0
- package/dist/lib/diagnostics/types.js +7 -0
- package/dist/lib/diagnostics/types.js.map +1 -0
- package/dist/lib/embeddings/index.d.ts +6 -3
- package/dist/lib/embeddings/index.d.ts.map +1 -1
- package/dist/lib/embeddings/index.js +7 -15
- package/dist/lib/embeddings/index.js.map +1 -1
- package/dist/lib/embeddings/worker.d.ts +2 -2
- package/dist/lib/embeddings/worker.d.ts.map +1 -1
- package/dist/lib/embeddings/worker.js +3 -1
- package/dist/lib/embeddings/worker.js.map +1 -1
- package/dist/lib/error-sanitizer.d.ts +28 -0
- package/dist/lib/error-sanitizer.d.ts.map +1 -0
- package/dist/lib/error-sanitizer.js +106 -0
- package/dist/lib/error-sanitizer.js.map +1 -0
- package/dist/lib/eval/index.d.ts +15 -0
- package/dist/lib/eval/index.d.ts.map +1 -0
- package/dist/lib/eval/index.js +24 -0
- package/dist/lib/eval/index.js.map +1 -0
- package/dist/lib/eval/runner.d.ts +28 -0
- package/dist/lib/eval/runner.d.ts.map +1 -0
- package/dist/lib/eval/runner.js +260 -0
- package/dist/lib/eval/runner.js.map +1 -0
- package/dist/lib/eval/scorers/contains.d.ts +10 -0
- package/dist/lib/eval/scorers/contains.d.ts.map +1 -0
- package/dist/lib/eval/scorers/contains.js +33 -0
- package/dist/lib/eval/scorers/contains.js.map +1 -0
- package/dist/lib/eval/scorers/exact-match.d.ts +10 -0
- package/dist/lib/eval/scorers/exact-match.d.ts.map +1 -0
- package/dist/lib/eval/scorers/exact-match.js +33 -0
- package/dist/lib/eval/scorers/exact-match.js.map +1 -0
- package/dist/lib/eval/scorers/index.d.ts +20 -0
- package/dist/lib/eval/scorers/index.d.ts.map +1 -0
- package/dist/lib/eval/scorers/index.js +19 -0
- package/dist/lib/eval/scorers/index.js.map +1 -0
- package/dist/lib/eval/scorers/llm-judge.d.ts +22 -0
- package/dist/lib/eval/scorers/llm-judge.d.ts.map +1 -0
- package/dist/lib/eval/scorers/llm-judge.js +79 -0
- package/dist/lib/eval/scorers/llm-judge.js.map +1 -0
- package/dist/lib/eval/scorers/regex.d.ts +10 -0
- package/dist/lib/eval/scorers/regex.d.ts.map +1 -0
- package/dist/lib/eval/scorers/regex.js +36 -0
- package/dist/lib/eval/scorers/regex.js.map +1 -0
- package/dist/lib/guardrails/actions.d.ts +6 -0
- package/dist/lib/guardrails/actions.d.ts.map +1 -1
- package/dist/lib/guardrails/actions.js +82 -0
- package/dist/lib/guardrails/actions.js.map +1 -1
- package/dist/lib/guardrails/conditions.d.ts +47 -0
- package/dist/lib/guardrails/conditions.d.ts.map +1 -1
- package/dist/lib/guardrails/conditions.js +55 -10
- package/dist/lib/guardrails/conditions.js.map +1 -1
- package/dist/lib/guardrails/content-engine.d.ts +19 -0
- package/dist/lib/guardrails/content-engine.d.ts.map +1 -0
- package/dist/lib/guardrails/content-engine.js +154 -0
- package/dist/lib/guardrails/content-engine.js.map +1 -0
- package/dist/lib/guardrails/engine.d.ts +33 -0
- package/dist/lib/guardrails/engine.d.ts.map +1 -1
- package/dist/lib/guardrails/engine.js +37 -2
- package/dist/lib/guardrails/engine.js.map +1 -1
- package/dist/lib/guardrails/scanners/base-scanner.d.ts +23 -0
- package/dist/lib/guardrails/scanners/base-scanner.d.ts.map +1 -0
- package/dist/lib/guardrails/scanners/base-scanner.js +7 -0
- package/dist/lib/guardrails/scanners/base-scanner.js.map +1 -0
- package/dist/lib/guardrails/scanners/patterns/pii-patterns.d.ts +13 -0
- package/dist/lib/guardrails/scanners/patterns/pii-patterns.d.ts.map +1 -0
- package/dist/lib/guardrails/scanners/patterns/pii-patterns.js +49 -0
- package/dist/lib/guardrails/scanners/patterns/pii-patterns.js.map +1 -0
- package/dist/lib/guardrails/scanners/patterns/secret-patterns.d.ts +6 -0
- package/dist/lib/guardrails/scanners/patterns/secret-patterns.d.ts.map +1 -0
- package/dist/lib/guardrails/scanners/patterns/secret-patterns.js +69 -0
- package/dist/lib/guardrails/scanners/patterns/secret-patterns.js.map +1 -0
- package/dist/lib/guardrails/scanners/pii-scanner.d.ts +10 -0
- package/dist/lib/guardrails/scanners/pii-scanner.d.ts.map +1 -0
- package/dist/lib/guardrails/scanners/pii-scanner.js +57 -0
- package/dist/lib/guardrails/scanners/pii-scanner.js.map +1 -0
- package/dist/lib/guardrails/scanners/scanner-registry.d.ts +14 -0
- package/dist/lib/guardrails/scanners/scanner-registry.d.ts.map +1 -0
- package/dist/lib/guardrails/scanners/scanner-registry.js +51 -0
- package/dist/lib/guardrails/scanners/scanner-registry.js.map +1 -0
- package/dist/lib/guardrails/scanners/secrets-scanner.d.ts +9 -0
- package/dist/lib/guardrails/scanners/secrets-scanner.d.ts.map +1 -0
- package/dist/lib/guardrails/scanners/secrets-scanner.js +47 -0
- package/dist/lib/guardrails/scanners/secrets-scanner.js.map +1 -0
- package/dist/lib/logger.d.ts +8 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +31 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/lore-client.d.ts +128 -0
- package/dist/lib/lore-client.d.ts.map +1 -0
- package/dist/lib/lore-client.js +188 -0
- package/dist/lib/lore-client.js.map +1 -0
- package/dist/lib/mesh-client.d.ts +31 -0
- package/dist/lib/mesh-client.d.ts.map +1 -0
- package/dist/lib/mesh-client.js +72 -0
- package/dist/lib/mesh-client.js.map +1 -0
- package/dist/lib/notifications/grouping-buffer.d.ts +25 -0
- package/dist/lib/notifications/grouping-buffer.d.ts.map +1 -0
- package/dist/lib/notifications/grouping-buffer.js +73 -0
- package/dist/lib/notifications/grouping-buffer.js.map +1 -0
- package/dist/lib/notifications/provider.d.ts +10 -0
- package/dist/lib/notifications/provider.d.ts.map +1 -0
- package/dist/lib/notifications/provider.js +5 -0
- package/dist/lib/notifications/provider.js.map +1 -0
- package/dist/lib/notifications/providers/email.d.ts +14 -0
- package/dist/lib/notifications/providers/email.d.ts.map +1 -0
- package/dist/lib/notifications/providers/email.js +88 -0
- package/dist/lib/notifications/providers/email.js.map +1 -0
- package/dist/lib/notifications/providers/pagerduty.d.ts +16 -0
- package/dist/lib/notifications/providers/pagerduty.d.ts.map +1 -0
- package/dist/lib/notifications/providers/pagerduty.js +94 -0
- package/dist/lib/notifications/providers/pagerduty.js.map +1 -0
- package/dist/lib/notifications/providers/slack.d.ts +14 -0
- package/dist/lib/notifications/providers/slack.d.ts.map +1 -0
- package/dist/lib/notifications/providers/slack.js +106 -0
- package/dist/lib/notifications/providers/slack.js.map +1 -0
- package/dist/lib/notifications/providers/webhook.d.ts +16 -0
- package/dist/lib/notifications/providers/webhook.d.ts.map +1 -0
- package/dist/lib/notifications/providers/webhook.js +78 -0
- package/dist/lib/notifications/providers/webhook.js.map +1 -0
- package/dist/lib/notifications/router.d.ts +30 -0
- package/dist/lib/notifications/router.d.ts.map +1 -0
- package/dist/lib/notifications/router.js +137 -0
- package/dist/lib/notifications/router.js.map +1 -0
- package/dist/lib/notifications/ssrf.d.ts +13 -0
- package/dist/lib/notifications/ssrf.d.ts.map +1 -0
- package/dist/lib/notifications/ssrf.js +37 -0
- package/dist/lib/notifications/ssrf.js.map +1 -0
- package/dist/lib/optimization/analyzers/model-downgrade.d.ts +15 -0
- package/dist/lib/optimization/analyzers/model-downgrade.d.ts.map +1 -0
- package/dist/lib/optimization/analyzers/model-downgrade.js +58 -0
- package/dist/lib/optimization/analyzers/model-downgrade.js.map +1 -0
- package/dist/lib/optimization/analyzers/prompt-optimization.d.ts +17 -0
- package/dist/lib/optimization/analyzers/prompt-optimization.d.ts.map +1 -0
- package/dist/lib/optimization/analyzers/prompt-optimization.js +160 -0
- package/dist/lib/optimization/analyzers/prompt-optimization.js.map +1 -0
- package/dist/lib/optimization/analyzers/types.d.ts +23 -0
- package/dist/lib/optimization/analyzers/types.d.ts.map +1 -0
- package/dist/lib/optimization/analyzers/types.js +5 -0
- package/dist/lib/optimization/analyzers/types.js.map +1 -0
- package/dist/lib/optimization/classifier.d.ts +4 -3
- package/dist/lib/optimization/classifier.d.ts.map +1 -1
- package/dist/lib/optimization/classifier.js +15 -9
- package/dist/lib/optimization/classifier.js.map +1 -1
- package/dist/lib/optimization/cost-optimizer.d.ts +21 -0
- package/dist/lib/optimization/cost-optimizer.d.ts.map +1 -0
- package/dist/lib/optimization/cost-optimizer.js +114 -0
- package/dist/lib/optimization/cost-optimizer.js.map +1 -0
- package/dist/lib/optimization/engine.d.ts.map +1 -1
- package/dist/lib/optimization/engine.js +45 -6
- package/dist/lib/optimization/engine.js.map +1 -1
- package/dist/lib/optimization/forecast.d.ts +39 -0
- package/dist/lib/optimization/forecast.d.ts.map +1 -0
- package/dist/lib/optimization/forecast.js +128 -0
- package/dist/lib/optimization/forecast.js.map +1 -0
- package/dist/lib/secrets.d.ts +30 -0
- package/dist/lib/secrets.d.ts.map +1 -0
- package/dist/lib/secrets.js +103 -0
- package/dist/lib/secrets.js.map +1 -0
- package/dist/lib/threshold-monitor.d.ts +53 -0
- package/dist/lib/threshold-monitor.d.ts.map +1 -0
- package/dist/lib/threshold-monitor.js +112 -0
- package/dist/lib/threshold-monitor.js.map +1 -0
- package/dist/middleware/audit.d.ts +16 -0
- package/dist/middleware/audit.d.ts.map +1 -0
- package/dist/middleware/audit.js +16 -0
- package/dist/middleware/audit.js.map +1 -0
- package/dist/middleware/auth-errors.d.ts +67 -0
- package/dist/middleware/auth-errors.d.ts.map +1 -0
- package/dist/middleware/auth-errors.js +84 -0
- package/dist/middleware/auth-errors.js.map +1 -0
- package/dist/middleware/auth.d.ts +5 -2
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +44 -17
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/body-limit.d.ts +9 -0
- package/dist/middleware/body-limit.d.ts.map +1 -0
- package/dist/middleware/body-limit.js +15 -0
- package/dist/middleware/body-limit.js.map +1 -0
- package/dist/middleware/cors-config.d.ts +30 -0
- package/dist/middleware/cors-config.d.ts.map +1 -0
- package/dist/middleware/cors-config.js +55 -0
- package/dist/middleware/cors-config.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +9 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +56 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/middleware/rbac.d.ts +30 -0
- package/dist/middleware/rbac.d.ts.map +1 -0
- package/dist/middleware/rbac.js +87 -0
- package/dist/middleware/rbac.js.map +1 -0
- package/dist/middleware/security-headers.d.ts +12 -0
- package/dist/middleware/security-headers.d.ts.map +1 -0
- package/dist/middleware/security-headers.js +57 -0
- package/dist/middleware/security-headers.js.map +1 -0
- package/dist/middleware/unified-auth.d.ts +49 -0
- package/dist/middleware/unified-auth.d.ts.map +1 -0
- package/dist/middleware/unified-auth.js +246 -0
- package/dist/middleware/unified-auth.js.map +1 -0
- package/dist/middleware/validation.d.ts +31 -0
- package/dist/middleware/validation.d.ts.map +1 -0
- package/dist/middleware/validation.js +45 -0
- package/dist/middleware/validation.js.map +1 -0
- package/dist/routes/alerts.d.ts.map +1 -1
- package/dist/routes/alerts.js +4 -3
- package/dist/routes/alerts.js.map +1 -1
- package/dist/routes/analytics.d.ts +2 -1
- package/dist/routes/analytics.d.ts.map +1 -1
- package/dist/routes/analytics.js +175 -95
- package/dist/routes/analytics.js.map +1 -1
- package/dist/routes/api-keys.d.ts +5 -0
- package/dist/routes/api-keys.d.ts.map +1 -1
- package/dist/routes/api-keys.js +89 -8
- package/dist/routes/api-keys.js.map +1 -1
- package/dist/routes/audit-verify.d.ts +12 -0
- package/dist/routes/audit-verify.d.ts.map +1 -0
- package/dist/routes/audit-verify.js +73 -0
- package/dist/routes/audit-verify.js.map +1 -0
- package/dist/routes/audit.d.ts +4 -6
- package/dist/routes/audit.d.ts.map +1 -1
- package/dist/routes/audit.js +54 -157
- package/dist/routes/audit.js.map +1 -1
- package/dist/routes/auth.d.ts +21 -0
- package/dist/routes/auth.d.ts.map +1 -0
- package/dist/routes/auth.js +235 -0
- package/dist/routes/auth.js.map +1 -0
- package/dist/routes/benchmarks.d.ts.map +1 -1
- package/dist/routes/benchmarks.js +63 -11
- package/dist/routes/benchmarks.js.map +1 -1
- package/dist/routes/capabilities-top.d.ts.map +1 -1
- package/dist/routes/capabilities-top.js +1 -4
- package/dist/routes/capabilities-top.js.map +1 -1
- package/dist/routes/capabilities.d.ts.map +1 -1
- package/dist/routes/capabilities.js +1 -7
- package/dist/routes/capabilities.js.map +1 -1
- package/dist/routes/compliance.d.ts +17 -0
- package/dist/routes/compliance.d.ts.map +1 -0
- package/dist/routes/compliance.js +151 -0
- package/dist/routes/compliance.js.map +1 -0
- package/dist/routes/config.d.ts +1 -13
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/context.d.ts.map +1 -1
- package/dist/routes/context.js +6 -5
- package/dist/routes/context.js.map +1 -1
- package/dist/routes/cost-budgets.d.ts +20 -0
- package/dist/routes/cost-budgets.d.ts.map +1 -0
- package/dist/routes/cost-budgets.js +194 -0
- package/dist/routes/cost-budgets.js.map +1 -0
- package/dist/routes/delegation.d.ts.map +1 -1
- package/dist/routes/delegation.js +67 -41
- package/dist/routes/delegation.js.map +1 -1
- package/dist/routes/delegations-top.d.ts.map +1 -1
- package/dist/routes/delegations-top.js +1 -3
- package/dist/routes/delegations-top.js.map +1 -1
- package/dist/routes/diagnose.d.ts +16 -0
- package/dist/routes/diagnose.d.ts.map +1 -0
- package/dist/routes/diagnose.js +82 -0
- package/dist/routes/diagnose.js.map +1 -0
- package/dist/routes/discovery.d.ts.map +1 -1
- package/dist/routes/discovery.js +50 -38
- package/dist/routes/discovery.js.map +1 -1
- package/dist/routes/eval.d.ts +24 -0
- package/dist/routes/eval.d.ts.map +1 -0
- package/dist/routes/eval.js +281 -0
- package/dist/routes/eval.js.map +1 -0
- package/dist/routes/events.d.ts.map +1 -1
- package/dist/routes/events.js +11 -6
- package/dist/routes/events.js.map +1 -1
- package/dist/routes/guardrails.d.ts +2 -1
- package/dist/routes/guardrails.d.ts.map +1 -1
- package/dist/routes/guardrails.js +85 -14
- package/dist/routes/guardrails.js.map +1 -1
- package/dist/routes/health.d.ts +14 -11
- package/dist/routes/health.d.ts.map +1 -1
- package/dist/routes/health.js +181 -61
- package/dist/routes/health.js.map +1 -1
- package/dist/routes/lore-proxy.d.ts +13 -0
- package/dist/routes/lore-proxy.d.ts.map +1 -0
- package/dist/routes/lore-proxy.js +229 -0
- package/dist/routes/lore-proxy.js.map +1 -0
- package/dist/routes/mesh-proxy.d.ts +7 -0
- package/dist/routes/mesh-proxy.d.ts.map +1 -0
- package/dist/routes/mesh-proxy.js +94 -0
- package/dist/routes/mesh-proxy.js.map +1 -0
- package/dist/routes/notifications.d.ts +19 -0
- package/dist/routes/notifications.d.ts.map +1 -0
- package/dist/routes/notifications.js +129 -0
- package/dist/routes/notifications.js.map +1 -0
- package/dist/routes/optimize.d.ts.map +1 -1
- package/dist/routes/optimize.js +44 -0
- package/dist/routes/optimize.js.map +1 -1
- package/dist/routes/otlp.d.ts +17 -0
- package/dist/routes/otlp.d.ts.map +1 -0
- package/dist/routes/otlp.js +544 -0
- package/dist/routes/otlp.js.map +1 -0
- package/dist/routes/prompts.d.ts +21 -0
- package/dist/routes/prompts.d.ts.map +1 -0
- package/dist/routes/prompts.js +173 -0
- package/dist/routes/prompts.js.map +1 -0
- package/dist/routes/recall.d.ts.map +1 -1
- package/dist/routes/recall.js +6 -4
- package/dist/routes/recall.js.map +1 -1
- package/dist/routes/replay.d.ts.map +1 -1
- package/dist/routes/replay.js +2 -1
- package/dist/routes/replay.js.map +1 -1
- package/dist/routes/server-info.d.ts +9 -0
- package/dist/routes/server-info.d.ts.map +1 -0
- package/dist/routes/server-info.js +18 -0
- package/dist/routes/server-info.js.map +1 -0
- package/dist/routes/sessions.d.ts +7 -7
- package/dist/routes/sessions.d.ts.map +1 -1
- package/dist/routes/sessions.js +112 -35
- package/dist/routes/sessions.js.map +1 -1
- package/dist/routes/stats.d.ts.map +1 -1
- package/dist/routes/stats.js +40 -0
- package/dist/routes/stats.js.map +1 -1
- package/dist/routes/stream.d.ts +2 -2
- package/dist/routes/stream.d.ts.map +1 -1
- package/dist/routes/stream.js +7 -11
- package/dist/routes/stream.js.map +1 -1
- package/dist/routes/tenant-helper.d.ts +15 -10
- package/dist/routes/tenant-helper.d.ts.map +1 -1
- package/dist/routes/tenant-helper.js +36 -22
- package/dist/routes/tenant-helper.js.map +1 -1
- package/dist/routes/trust.d.ts.map +1 -1
- package/dist/routes/trust.js +1 -3
- package/dist/routes/trust.js.map +1 -1
- package/dist/schemas/api-keys.d.ts +11 -0
- package/dist/schemas/api-keys.d.ts.map +1 -0
- package/dist/schemas/api-keys.js +10 -0
- package/dist/schemas/api-keys.js.map +1 -0
- package/dist/schemas/common.d.ts +34 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +43 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/schemas/delegation.d.ts +23 -0
- package/dist/schemas/delegation.d.ts.map +1 -0
- package/dist/schemas/delegation.js +22 -0
- package/dist/schemas/delegation.js.map +1 -0
- package/dist/schemas/discovery.d.ts +17 -0
- package/dist/schemas/discovery.d.ts.map +1 -0
- package/dist/schemas/discovery.js +15 -0
- package/dist/schemas/discovery.js.map +1 -0
- package/dist/schemas/health.d.ts +75 -0
- package/dist/schemas/health.d.ts.map +1 -0
- package/dist/schemas/health.js +55 -0
- package/dist/schemas/health.js.map +1 -0
- package/dist/schemas/index.d.ts +6 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +6 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/sessions.d.ts +67 -0
- package/dist/schemas/sessions.d.ts.map +1 -0
- package/dist/schemas/sessions.js +58 -0
- package/dist/schemas/sessions.js.map +1 -0
- package/dist/services/delegation-service.d.ts +1 -4
- package/dist/services/delegation-service.d.ts.map +1 -1
- package/dist/services/delegation-service.js +5 -31
- package/dist/services/delegation-service.js.map +1 -1
- package/package.json +29 -19
- package/dist/db/lesson-store.d.ts +0 -57
- package/dist/db/lesson-store.d.ts.map +0 -1
- package/dist/db/lesson-store.js +0 -217
- package/dist/db/lesson-store.js.map +0 -1
- package/dist/lib/embeddings/local.d.ts +0 -15
- package/dist/lib/embeddings/local.d.ts.map +0 -1
- package/dist/lib/embeddings/local.js +0 -65
- package/dist/lib/embeddings/local.js.map +0 -1
- package/dist/lib/redaction/human-review-layer.d.ts +0 -37
- package/dist/lib/redaction/human-review-layer.d.ts.map +0 -1
- package/dist/lib/redaction/human-review-layer.js +0 -62
- package/dist/lib/redaction/human-review-layer.js.map +0 -1
- package/dist/lib/redaction/index.d.ts +0 -12
- package/dist/lib/redaction/index.d.ts.map +0 -1
- package/dist/lib/redaction/index.js +0 -12
- package/dist/lib/redaction/index.js.map +0 -1
- package/dist/lib/redaction/pii-detection-layer.d.ts +0 -30
- package/dist/lib/redaction/pii-detection-layer.d.ts.map +0 -1
- package/dist/lib/redaction/pii-detection-layer.js +0 -183
- package/dist/lib/redaction/pii-detection-layer.js.map +0 -1
- package/dist/lib/redaction/pipeline.d.ts +0 -26
- package/dist/lib/redaction/pipeline.d.ts.map +0 -1
- package/dist/lib/redaction/pipeline.js +0 -91
- package/dist/lib/redaction/pipeline.js.map +0 -1
- package/dist/lib/redaction/secret-detection-layer.d.ts +0 -10
- package/dist/lib/redaction/secret-detection-layer.d.ts.map +0 -1
- package/dist/lib/redaction/secret-detection-layer.js +0 -79
- package/dist/lib/redaction/secret-detection-layer.js.map +0 -1
- package/dist/lib/redaction/secret-patterns.d.ts +0 -29
- package/dist/lib/redaction/secret-patterns.d.ts.map +0 -1
- package/dist/lib/redaction/secret-patterns.js +0 -133
- package/dist/lib/redaction/secret-patterns.js.map +0 -1
- package/dist/lib/redaction/semantic-denylist-layer.d.ts +0 -10
- package/dist/lib/redaction/semantic-denylist-layer.d.ts.map +0 -1
- package/dist/lib/redaction/semantic-denylist-layer.js +0 -64
- package/dist/lib/redaction/semantic-denylist-layer.js.map +0 -1
- package/dist/lib/redaction/tenant-deidentification-layer.d.ts +0 -10
- package/dist/lib/redaction/tenant-deidentification-layer.d.ts.map +0 -1
- package/dist/lib/redaction/tenant-deidentification-layer.js +0 -64
- package/dist/lib/redaction/tenant-deidentification-layer.js.map +0 -1
- package/dist/lib/redaction/url-path-scrubbing-layer.d.ts +0 -14
- package/dist/lib/redaction/url-path-scrubbing-layer.d.ts.map +0 -1
- package/dist/lib/redaction/url-path-scrubbing-layer.js +0 -156
- package/dist/lib/redaction/url-path-scrubbing-layer.js.map +0 -1
- package/dist/routes/community.d.ts +0 -24
- package/dist/routes/community.d.ts.map +0 -1
- package/dist/routes/community.js +0 -272
- package/dist/routes/community.js.map +0 -1
- package/dist/routes/lessons.d.ts +0 -19
- package/dist/routes/lessons.d.ts.map +0 -1
- package/dist/routes/lessons.js +0 -164
- package/dist/routes/lessons.js.map +0 -1
- package/dist/routes/redaction-test.d.ts +0 -14
- package/dist/routes/redaction-test.d.ts.map +0 -1
- package/dist/routes/redaction-test.js +0 -33
- package/dist/routes/redaction-test.js.map +0 -1
- package/dist/services/community-service.d.ts +0 -283
- package/dist/services/community-service.d.ts.map +0 -1
- package/dist/services/community-service.js +0 -816
- package/dist/services/community-service.js.map +0 -1
|
@@ -0,0 +1,920 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database migration runner.
|
|
3
|
+
*
|
|
4
|
+
* For SQLite, uses Drizzle's push-based approach to create/update tables
|
|
5
|
+
* on first start. For production, Drizzle Kit migrations can be used.
|
|
6
|
+
*/
|
|
7
|
+
import { sql } from 'drizzle-orm';
|
|
8
|
+
/**
|
|
9
|
+
* Run migrations: create all tables and indexes if they don't exist.
|
|
10
|
+
*
|
|
11
|
+
* Uses CREATE TABLE IF NOT EXISTS for idempotent startup.
|
|
12
|
+
* This approach is simpler than file-based migrations for an
|
|
13
|
+
* embedded SQLite database that auto-creates on first start.
|
|
14
|
+
*/
|
|
15
|
+
export function runMigrations(db) {
|
|
16
|
+
// Create all tables using raw SQL for CREATE IF NOT EXISTS
|
|
17
|
+
// Drizzle doesn't have a built-in "push" that works at runtime,
|
|
18
|
+
// so we use the schema definitions to generate DDL.
|
|
19
|
+
db.run(sql `
|
|
20
|
+
CREATE TABLE IF NOT EXISTS events (
|
|
21
|
+
id TEXT PRIMARY KEY,
|
|
22
|
+
timestamp TEXT NOT NULL,
|
|
23
|
+
session_id TEXT NOT NULL,
|
|
24
|
+
agent_id TEXT NOT NULL,
|
|
25
|
+
event_type TEXT NOT NULL,
|
|
26
|
+
severity TEXT NOT NULL DEFAULT 'info',
|
|
27
|
+
payload TEXT NOT NULL,
|
|
28
|
+
metadata TEXT NOT NULL DEFAULT '{}',
|
|
29
|
+
prev_hash TEXT,
|
|
30
|
+
hash TEXT NOT NULL
|
|
31
|
+
)
|
|
32
|
+
`);
|
|
33
|
+
db.run(sql `
|
|
34
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
35
|
+
id TEXT NOT NULL,
|
|
36
|
+
agent_id TEXT NOT NULL,
|
|
37
|
+
agent_name TEXT,
|
|
38
|
+
started_at TEXT NOT NULL,
|
|
39
|
+
ended_at TEXT,
|
|
40
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
41
|
+
event_count INTEGER NOT NULL DEFAULT 0,
|
|
42
|
+
tool_call_count INTEGER NOT NULL DEFAULT 0,
|
|
43
|
+
error_count INTEGER NOT NULL DEFAULT 0,
|
|
44
|
+
total_cost_usd REAL NOT NULL DEFAULT 0,
|
|
45
|
+
llm_call_count INTEGER NOT NULL DEFAULT 0,
|
|
46
|
+
total_input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
47
|
+
total_output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
48
|
+
tags TEXT NOT NULL DEFAULT '[]',
|
|
49
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
50
|
+
PRIMARY KEY (id, tenant_id)
|
|
51
|
+
)
|
|
52
|
+
`);
|
|
53
|
+
db.run(sql `
|
|
54
|
+
CREATE TABLE IF NOT EXISTS agents (
|
|
55
|
+
id TEXT NOT NULL,
|
|
56
|
+
name TEXT NOT NULL,
|
|
57
|
+
description TEXT,
|
|
58
|
+
first_seen_at TEXT NOT NULL,
|
|
59
|
+
last_seen_at TEXT NOT NULL,
|
|
60
|
+
session_count INTEGER NOT NULL DEFAULT 0,
|
|
61
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
62
|
+
PRIMARY KEY (id, tenant_id)
|
|
63
|
+
)
|
|
64
|
+
`);
|
|
65
|
+
db.run(sql `
|
|
66
|
+
CREATE TABLE IF NOT EXISTS alert_rules (
|
|
67
|
+
id TEXT PRIMARY KEY,
|
|
68
|
+
name TEXT NOT NULL,
|
|
69
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
70
|
+
condition TEXT NOT NULL,
|
|
71
|
+
threshold REAL NOT NULL,
|
|
72
|
+
window_minutes INTEGER NOT NULL,
|
|
73
|
+
scope TEXT NOT NULL DEFAULT '{}',
|
|
74
|
+
notify_channels TEXT NOT NULL DEFAULT '[]',
|
|
75
|
+
created_at TEXT NOT NULL,
|
|
76
|
+
updated_at TEXT NOT NULL
|
|
77
|
+
)
|
|
78
|
+
`);
|
|
79
|
+
db.run(sql `
|
|
80
|
+
CREATE TABLE IF NOT EXISTS alert_history (
|
|
81
|
+
id TEXT PRIMARY KEY,
|
|
82
|
+
rule_id TEXT NOT NULL REFERENCES alert_rules(id),
|
|
83
|
+
triggered_at TEXT NOT NULL,
|
|
84
|
+
resolved_at TEXT,
|
|
85
|
+
current_value REAL NOT NULL,
|
|
86
|
+
threshold REAL NOT NULL,
|
|
87
|
+
message TEXT NOT NULL
|
|
88
|
+
)
|
|
89
|
+
`);
|
|
90
|
+
db.run(sql `
|
|
91
|
+
CREATE TABLE IF NOT EXISTS api_keys (
|
|
92
|
+
id TEXT PRIMARY KEY,
|
|
93
|
+
key_hash TEXT NOT NULL,
|
|
94
|
+
name TEXT NOT NULL,
|
|
95
|
+
scopes TEXT NOT NULL,
|
|
96
|
+
created_at INTEGER NOT NULL,
|
|
97
|
+
last_used_at INTEGER,
|
|
98
|
+
revoked_at INTEGER,
|
|
99
|
+
rate_limit INTEGER
|
|
100
|
+
)
|
|
101
|
+
`);
|
|
102
|
+
// Create indexes (IF NOT EXISTS)
|
|
103
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp)`);
|
|
104
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_events_session_id ON events(session_id)`);
|
|
105
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_events_agent_id ON events(agent_id)`);
|
|
106
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_events_type ON events(event_type)`);
|
|
107
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_events_session_ts ON events(session_id, timestamp)`);
|
|
108
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_events_agent_type_ts ON events(agent_id, event_type, timestamp)`);
|
|
109
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_sessions_agent_id ON sessions(agent_id)`);
|
|
110
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_sessions_started_at ON sessions(started_at)`);
|
|
111
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status)`);
|
|
112
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_api_keys_hash ON api_keys(key_hash)`);
|
|
113
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_alert_history_rule_id ON alert_history(rule_id)`);
|
|
114
|
+
// ─── Migrations for existing databases ──────────────────
|
|
115
|
+
// Add LLM tracking columns to sessions (v0.3.0)
|
|
116
|
+
// SQLite doesn't support ADD COLUMN IF NOT EXISTS, so we check first
|
|
117
|
+
const sessionColumns = db.all(sql `PRAGMA table_info(sessions)`);
|
|
118
|
+
const sessionColumnNames = new Set(sessionColumns.map((c) => c.name));
|
|
119
|
+
if (!sessionColumnNames.has('llm_call_count')) {
|
|
120
|
+
db.run(sql `ALTER TABLE sessions ADD COLUMN llm_call_count INTEGER NOT NULL DEFAULT 0`);
|
|
121
|
+
}
|
|
122
|
+
if (!sessionColumnNames.has('total_input_tokens')) {
|
|
123
|
+
db.run(sql `ALTER TABLE sessions ADD COLUMN total_input_tokens INTEGER NOT NULL DEFAULT 0`);
|
|
124
|
+
}
|
|
125
|
+
if (!sessionColumnNames.has('total_output_tokens')) {
|
|
126
|
+
db.run(sql `ALTER TABLE sessions ADD COLUMN total_output_tokens INTEGER NOT NULL DEFAULT 0`);
|
|
127
|
+
}
|
|
128
|
+
// ─── Tenant isolation migration (Epic 1) ──────────────────
|
|
129
|
+
// Add tenant_id to all data tables for multi-tenant support
|
|
130
|
+
// api_keys.tenant_id
|
|
131
|
+
const apiKeyColumns = db.all(sql `PRAGMA table_info(api_keys)`);
|
|
132
|
+
const apiKeyColumnNames = new Set(apiKeyColumns.map((c) => c.name));
|
|
133
|
+
if (!apiKeyColumnNames.has('tenant_id')) {
|
|
134
|
+
db.run(sql `ALTER TABLE api_keys ADD COLUMN tenant_id TEXT NOT NULL DEFAULT 'default'`);
|
|
135
|
+
}
|
|
136
|
+
if (!apiKeyColumnNames.has('created_by')) {
|
|
137
|
+
db.run(sql `ALTER TABLE api_keys ADD COLUMN created_by TEXT REFERENCES users(id)`);
|
|
138
|
+
}
|
|
139
|
+
if (!apiKeyColumnNames.has('role')) {
|
|
140
|
+
db.run(sql `ALTER TABLE api_keys ADD COLUMN role TEXT NOT NULL DEFAULT 'editor'`);
|
|
141
|
+
}
|
|
142
|
+
// events.tenant_id
|
|
143
|
+
const eventColumns = db.all(sql `PRAGMA table_info(events)`);
|
|
144
|
+
const eventColumnNames = new Set(eventColumns.map((c) => c.name));
|
|
145
|
+
if (!eventColumnNames.has('tenant_id')) {
|
|
146
|
+
db.run(sql `ALTER TABLE events ADD COLUMN tenant_id TEXT NOT NULL DEFAULT 'default'`);
|
|
147
|
+
}
|
|
148
|
+
// sessions.tenant_id
|
|
149
|
+
if (!sessionColumnNames.has('tenant_id')) {
|
|
150
|
+
db.run(sql `ALTER TABLE sessions ADD COLUMN tenant_id TEXT NOT NULL DEFAULT 'default'`);
|
|
151
|
+
}
|
|
152
|
+
// agents.tenant_id
|
|
153
|
+
const agentColumns = db.all(sql `PRAGMA table_info(agents)`);
|
|
154
|
+
const agentColumnNames = new Set(agentColumns.map((c) => c.name));
|
|
155
|
+
if (!agentColumnNames.has('tenant_id')) {
|
|
156
|
+
db.run(sql `ALTER TABLE agents ADD COLUMN tenant_id TEXT NOT NULL DEFAULT 'default'`);
|
|
157
|
+
}
|
|
158
|
+
// alert_rules.tenant_id
|
|
159
|
+
const alertRuleColumns = db.all(sql `PRAGMA table_info(alert_rules)`);
|
|
160
|
+
const alertRuleColumnNames = new Set(alertRuleColumns.map((c) => c.name));
|
|
161
|
+
if (!alertRuleColumnNames.has('tenant_id')) {
|
|
162
|
+
db.run(sql `ALTER TABLE alert_rules ADD COLUMN tenant_id TEXT NOT NULL DEFAULT 'default'`);
|
|
163
|
+
}
|
|
164
|
+
// alert_history.tenant_id
|
|
165
|
+
const alertHistoryColumns = db.all(sql `PRAGMA table_info(alert_history)`);
|
|
166
|
+
const alertHistoryColumnNames = new Set(alertHistoryColumns.map((c) => c.name));
|
|
167
|
+
if (!alertHistoryColumnNames.has('tenant_id')) {
|
|
168
|
+
db.run(sql `ALTER TABLE alert_history ADD COLUMN tenant_id TEXT NOT NULL DEFAULT 'default'`);
|
|
169
|
+
}
|
|
170
|
+
// Tenant isolation indexes
|
|
171
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_events_tenant_id ON events(tenant_id)`);
|
|
172
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_events_tenant_session ON events(tenant_id, session_id)`);
|
|
173
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_events_tenant_agent_ts ON events(tenant_id, agent_id, timestamp)`);
|
|
174
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_sessions_tenant_id ON sessions(tenant_id)`);
|
|
175
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_sessions_tenant_agent ON sessions(tenant_id, agent_id)`);
|
|
176
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_sessions_tenant_started ON sessions(tenant_id, started_at)`);
|
|
177
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_agents_tenant_id ON agents(tenant_id)`);
|
|
178
|
+
// ─── Embeddings table (Epic 2 — Story 2.2) ──────────────────
|
|
179
|
+
db.run(sql `
|
|
180
|
+
CREATE TABLE IF NOT EXISTS embeddings (
|
|
181
|
+
id TEXT PRIMARY KEY,
|
|
182
|
+
tenant_id TEXT NOT NULL,
|
|
183
|
+
source_type TEXT NOT NULL,
|
|
184
|
+
source_id TEXT NOT NULL,
|
|
185
|
+
content_hash TEXT NOT NULL,
|
|
186
|
+
text_content TEXT NOT NULL,
|
|
187
|
+
embedding BLOB NOT NULL,
|
|
188
|
+
embedding_model TEXT NOT NULL,
|
|
189
|
+
dimensions INTEGER NOT NULL,
|
|
190
|
+
created_at TEXT NOT NULL
|
|
191
|
+
)
|
|
192
|
+
`);
|
|
193
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_embeddings_tenant ON embeddings(tenant_id)`);
|
|
194
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_embeddings_source ON embeddings(source_type, source_id)`);
|
|
195
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_embeddings_content_hash ON embeddings(tenant_id, content_hash)`);
|
|
196
|
+
// ─── Session Summaries table (Epic 2 — Story 2.2) ──────────────────
|
|
197
|
+
db.run(sql `
|
|
198
|
+
CREATE TABLE IF NOT EXISTS session_summaries (
|
|
199
|
+
session_id TEXT NOT NULL,
|
|
200
|
+
tenant_id TEXT NOT NULL,
|
|
201
|
+
summary TEXT NOT NULL,
|
|
202
|
+
topics TEXT NOT NULL DEFAULT '[]',
|
|
203
|
+
tool_sequence TEXT NOT NULL DEFAULT '[]',
|
|
204
|
+
error_summary TEXT,
|
|
205
|
+
outcome TEXT,
|
|
206
|
+
created_at TEXT NOT NULL,
|
|
207
|
+
updated_at TEXT NOT NULL,
|
|
208
|
+
PRIMARY KEY (session_id, tenant_id)
|
|
209
|
+
)
|
|
210
|
+
`);
|
|
211
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_session_summaries_tenant ON session_summaries(tenant_id)`);
|
|
212
|
+
// ─── Composite PK migration (CRITICAL-2) ──────────────────
|
|
213
|
+
// SQLite doesn't support ALTER TABLE to change PKs, so we recreate
|
|
214
|
+
// tables with composite PKs (id, tenant_id) for tenant isolation.
|
|
215
|
+
// Check if sessions table still has single-column PK
|
|
216
|
+
// by looking at the CREATE TABLE statement
|
|
217
|
+
const sessionsSchema = db.get(sql `SELECT sql FROM sqlite_master WHERE type='table' AND name='sessions'`);
|
|
218
|
+
if (sessionsSchema && sessionsSchema.sql.includes('id TEXT PRIMARY KEY')) {
|
|
219
|
+
// Drop old indexes that reference sessions (they'll be recreated)
|
|
220
|
+
db.run(sql `DROP INDEX IF EXISTS idx_sessions_agent_id`);
|
|
221
|
+
db.run(sql `DROP INDEX IF EXISTS idx_sessions_started_at`);
|
|
222
|
+
db.run(sql `DROP INDEX IF EXISTS idx_sessions_status`);
|
|
223
|
+
db.run(sql `DROP INDEX IF EXISTS idx_sessions_tenant_id`);
|
|
224
|
+
db.run(sql `DROP INDEX IF EXISTS idx_sessions_tenant_agent`);
|
|
225
|
+
db.run(sql `DROP INDEX IF EXISTS idx_sessions_tenant_started`);
|
|
226
|
+
db.run(sql `
|
|
227
|
+
CREATE TABLE sessions_new (
|
|
228
|
+
id TEXT NOT NULL,
|
|
229
|
+
agent_id TEXT NOT NULL,
|
|
230
|
+
agent_name TEXT,
|
|
231
|
+
started_at TEXT NOT NULL,
|
|
232
|
+
ended_at TEXT,
|
|
233
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
234
|
+
event_count INTEGER NOT NULL DEFAULT 0,
|
|
235
|
+
tool_call_count INTEGER NOT NULL DEFAULT 0,
|
|
236
|
+
error_count INTEGER NOT NULL DEFAULT 0,
|
|
237
|
+
total_cost_usd REAL NOT NULL DEFAULT 0,
|
|
238
|
+
llm_call_count INTEGER NOT NULL DEFAULT 0,
|
|
239
|
+
total_input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
240
|
+
total_output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
241
|
+
tags TEXT NOT NULL DEFAULT '[]',
|
|
242
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
243
|
+
PRIMARY KEY (id, tenant_id)
|
|
244
|
+
)
|
|
245
|
+
`);
|
|
246
|
+
db.run(sql `
|
|
247
|
+
INSERT INTO sessions_new
|
|
248
|
+
SELECT id, agent_id, agent_name, started_at, ended_at, status,
|
|
249
|
+
event_count, tool_call_count, error_count, total_cost_usd,
|
|
250
|
+
llm_call_count, total_input_tokens, total_output_tokens,
|
|
251
|
+
tags, tenant_id
|
|
252
|
+
FROM sessions
|
|
253
|
+
`);
|
|
254
|
+
db.run(sql `DROP TABLE sessions`);
|
|
255
|
+
db.run(sql `ALTER TABLE sessions_new RENAME TO sessions`);
|
|
256
|
+
// Recreate indexes
|
|
257
|
+
db.run(sql `CREATE INDEX idx_sessions_agent_id ON sessions(agent_id)`);
|
|
258
|
+
db.run(sql `CREATE INDEX idx_sessions_started_at ON sessions(started_at)`);
|
|
259
|
+
db.run(sql `CREATE INDEX idx_sessions_status ON sessions(status)`);
|
|
260
|
+
db.run(sql `CREATE INDEX idx_sessions_tenant_id ON sessions(tenant_id)`);
|
|
261
|
+
db.run(sql `CREATE INDEX idx_sessions_tenant_agent ON sessions(tenant_id, agent_id)`);
|
|
262
|
+
db.run(sql `CREATE INDEX idx_sessions_tenant_started ON sessions(tenant_id, started_at)`);
|
|
263
|
+
}
|
|
264
|
+
// Check if agents table still has single-column PK
|
|
265
|
+
const agentsSchema = db.get(sql `SELECT sql FROM sqlite_master WHERE type='table' AND name='agents'`);
|
|
266
|
+
if (agentsSchema && agentsSchema.sql.includes('id TEXT PRIMARY KEY')) {
|
|
267
|
+
db.run(sql `DROP INDEX IF EXISTS idx_agents_tenant_id`);
|
|
268
|
+
db.run(sql `
|
|
269
|
+
CREATE TABLE agents_new (
|
|
270
|
+
id TEXT NOT NULL,
|
|
271
|
+
name TEXT NOT NULL,
|
|
272
|
+
description TEXT,
|
|
273
|
+
first_seen_at TEXT NOT NULL,
|
|
274
|
+
last_seen_at TEXT NOT NULL,
|
|
275
|
+
session_count INTEGER NOT NULL DEFAULT 0,
|
|
276
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
277
|
+
PRIMARY KEY (id, tenant_id)
|
|
278
|
+
)
|
|
279
|
+
`);
|
|
280
|
+
db.run(sql `
|
|
281
|
+
INSERT INTO agents_new
|
|
282
|
+
SELECT id, name, description, first_seen_at, last_seen_at,
|
|
283
|
+
session_count, tenant_id
|
|
284
|
+
FROM agents
|
|
285
|
+
`);
|
|
286
|
+
db.run(sql `DROP TABLE agents`);
|
|
287
|
+
db.run(sql `ALTER TABLE agents_new RENAME TO agents`);
|
|
288
|
+
db.run(sql `CREATE INDEX idx_agents_tenant_id ON agents(tenant_id)`);
|
|
289
|
+
}
|
|
290
|
+
// ─── Lessons table (Epic 3) ──────────────────────────────
|
|
291
|
+
db.run(sql `
|
|
292
|
+
CREATE TABLE IF NOT EXISTS lessons (
|
|
293
|
+
id TEXT NOT NULL,
|
|
294
|
+
tenant_id TEXT NOT NULL,
|
|
295
|
+
agent_id TEXT,
|
|
296
|
+
category TEXT NOT NULL DEFAULT 'general',
|
|
297
|
+
title TEXT NOT NULL,
|
|
298
|
+
content TEXT NOT NULL,
|
|
299
|
+
context TEXT NOT NULL DEFAULT '{}',
|
|
300
|
+
importance TEXT NOT NULL DEFAULT 'normal',
|
|
301
|
+
source_session_id TEXT,
|
|
302
|
+
source_event_id TEXT,
|
|
303
|
+
access_count INTEGER NOT NULL DEFAULT 0,
|
|
304
|
+
last_accessed_at TEXT,
|
|
305
|
+
created_at TEXT NOT NULL,
|
|
306
|
+
updated_at TEXT NOT NULL,
|
|
307
|
+
archived_at TEXT,
|
|
308
|
+
PRIMARY KEY (id, tenant_id)
|
|
309
|
+
)
|
|
310
|
+
`);
|
|
311
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_lessons_tenant ON lessons(tenant_id)`);
|
|
312
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_lessons_tenant_agent ON lessons(tenant_id, agent_id)`);
|
|
313
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_lessons_tenant_category ON lessons(tenant_id, category)`);
|
|
314
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_lessons_tenant_importance ON lessons(tenant_id, importance)`);
|
|
315
|
+
// ─── Lessons PK migration (H5) ──────────────────────────
|
|
316
|
+
// Migrate existing lessons tables from single-column PK to composite PK
|
|
317
|
+
const lessonsSchema = db.get(sql `SELECT sql FROM sqlite_master WHERE type='table' AND name='lessons'`);
|
|
318
|
+
if (lessonsSchema && lessonsSchema.sql.includes('id TEXT PRIMARY KEY')) {
|
|
319
|
+
db.run(sql `DROP INDEX IF EXISTS idx_lessons_tenant`);
|
|
320
|
+
db.run(sql `DROP INDEX IF EXISTS idx_lessons_tenant_agent`);
|
|
321
|
+
db.run(sql `DROP INDEX IF EXISTS idx_lessons_tenant_category`);
|
|
322
|
+
db.run(sql `DROP INDEX IF EXISTS idx_lessons_tenant_importance`);
|
|
323
|
+
db.run(sql `
|
|
324
|
+
CREATE TABLE lessons_new (
|
|
325
|
+
id TEXT NOT NULL,
|
|
326
|
+
tenant_id TEXT NOT NULL,
|
|
327
|
+
agent_id TEXT,
|
|
328
|
+
category TEXT NOT NULL DEFAULT 'general',
|
|
329
|
+
title TEXT NOT NULL,
|
|
330
|
+
content TEXT NOT NULL,
|
|
331
|
+
context TEXT NOT NULL DEFAULT '{}',
|
|
332
|
+
importance TEXT NOT NULL DEFAULT 'normal',
|
|
333
|
+
source_session_id TEXT,
|
|
334
|
+
source_event_id TEXT,
|
|
335
|
+
access_count INTEGER NOT NULL DEFAULT 0,
|
|
336
|
+
last_accessed_at TEXT,
|
|
337
|
+
created_at TEXT NOT NULL,
|
|
338
|
+
updated_at TEXT NOT NULL,
|
|
339
|
+
archived_at TEXT,
|
|
340
|
+
PRIMARY KEY (id, tenant_id)
|
|
341
|
+
)
|
|
342
|
+
`);
|
|
343
|
+
db.run(sql `
|
|
344
|
+
INSERT INTO lessons_new
|
|
345
|
+
SELECT id, tenant_id, agent_id, category, title, content, context,
|
|
346
|
+
importance, source_session_id, source_event_id, access_count,
|
|
347
|
+
last_accessed_at, created_at, updated_at, archived_at
|
|
348
|
+
FROM lessons
|
|
349
|
+
`);
|
|
350
|
+
db.run(sql `DROP TABLE lessons`);
|
|
351
|
+
db.run(sql `ALTER TABLE lessons_new RENAME TO lessons`);
|
|
352
|
+
db.run(sql `CREATE INDEX idx_lessons_tenant ON lessons(tenant_id)`);
|
|
353
|
+
db.run(sql `CREATE INDEX idx_lessons_tenant_agent ON lessons(tenant_id, agent_id)`);
|
|
354
|
+
db.run(sql `CREATE INDEX idx_lessons_tenant_category ON lessons(tenant_id, category)`);
|
|
355
|
+
db.run(sql `CREATE INDEX idx_lessons_tenant_importance ON lessons(tenant_id, importance)`);
|
|
356
|
+
}
|
|
357
|
+
// ─── Composite index for similarity search (M6) ──────────────────
|
|
358
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_embeddings_tenant_source_time ON embeddings(tenant_id, source_type, created_at)`);
|
|
359
|
+
// ─── Health Snapshots table (Epic 6 — Story 1.3) ──────────────────
|
|
360
|
+
db.run(sql `
|
|
361
|
+
CREATE TABLE IF NOT EXISTS health_snapshots (
|
|
362
|
+
id TEXT NOT NULL,
|
|
363
|
+
tenant_id TEXT NOT NULL,
|
|
364
|
+
agent_id TEXT NOT NULL,
|
|
365
|
+
date TEXT NOT NULL,
|
|
366
|
+
overall_score REAL NOT NULL,
|
|
367
|
+
error_rate_score REAL NOT NULL,
|
|
368
|
+
cost_efficiency_score REAL NOT NULL,
|
|
369
|
+
tool_success_score REAL NOT NULL,
|
|
370
|
+
latency_score REAL NOT NULL,
|
|
371
|
+
completion_rate_score REAL NOT NULL,
|
|
372
|
+
session_count INTEGER NOT NULL,
|
|
373
|
+
created_at TEXT NOT NULL,
|
|
374
|
+
PRIMARY KEY (tenant_id, agent_id, date)
|
|
375
|
+
)
|
|
376
|
+
`);
|
|
377
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_health_snapshots_agent ON health_snapshots(tenant_id, agent_id, date DESC)`);
|
|
378
|
+
// ─── Benchmark tables (v0.7.0 — Story 1.3) ──────────────────
|
|
379
|
+
db.run(sql `
|
|
380
|
+
CREATE TABLE IF NOT EXISTS benchmarks (
|
|
381
|
+
id TEXT PRIMARY KEY,
|
|
382
|
+
tenant_id TEXT NOT NULL,
|
|
383
|
+
name TEXT NOT NULL,
|
|
384
|
+
description TEXT,
|
|
385
|
+
status TEXT NOT NULL DEFAULT 'draft',
|
|
386
|
+
agent_id TEXT,
|
|
387
|
+
metrics TEXT NOT NULL DEFAULT '[]',
|
|
388
|
+
min_sessions_per_variant INTEGER NOT NULL DEFAULT 10,
|
|
389
|
+
time_range_from TEXT,
|
|
390
|
+
time_range_to TEXT,
|
|
391
|
+
created_at TEXT NOT NULL,
|
|
392
|
+
updated_at TEXT NOT NULL,
|
|
393
|
+
completed_at TEXT
|
|
394
|
+
)
|
|
395
|
+
`);
|
|
396
|
+
db.run(sql `
|
|
397
|
+
CREATE TABLE IF NOT EXISTS benchmark_variants (
|
|
398
|
+
id TEXT PRIMARY KEY,
|
|
399
|
+
benchmark_id TEXT NOT NULL REFERENCES benchmarks(id) ON DELETE CASCADE,
|
|
400
|
+
tenant_id TEXT NOT NULL,
|
|
401
|
+
name TEXT NOT NULL,
|
|
402
|
+
description TEXT,
|
|
403
|
+
tag TEXT NOT NULL,
|
|
404
|
+
agent_id TEXT,
|
|
405
|
+
sort_order INTEGER NOT NULL DEFAULT 0
|
|
406
|
+
)
|
|
407
|
+
`);
|
|
408
|
+
db.run(sql `
|
|
409
|
+
CREATE TABLE IF NOT EXISTS benchmark_results (
|
|
410
|
+
id TEXT PRIMARY KEY,
|
|
411
|
+
benchmark_id TEXT NOT NULL REFERENCES benchmarks(id) ON DELETE CASCADE,
|
|
412
|
+
tenant_id TEXT NOT NULL,
|
|
413
|
+
variant_metrics TEXT NOT NULL DEFAULT '[]',
|
|
414
|
+
comparisons TEXT NOT NULL DEFAULT '[]',
|
|
415
|
+
summary TEXT,
|
|
416
|
+
computed_at TEXT NOT NULL
|
|
417
|
+
)
|
|
418
|
+
`);
|
|
419
|
+
// Benchmark indexes
|
|
420
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_benchmarks_tenant_id ON benchmarks(tenant_id)`);
|
|
421
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_benchmarks_tenant_status ON benchmarks(tenant_id, status)`);
|
|
422
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_benchmark_variants_benchmark_id ON benchmark_variants(benchmark_id)`);
|
|
423
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_benchmark_variants_tenant_tag ON benchmark_variants(tenant_id, tag)`);
|
|
424
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_benchmark_results_benchmark_id ON benchmark_results(benchmark_id)`);
|
|
425
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_benchmark_results_tenant_id ON benchmark_results(tenant_id)`);
|
|
426
|
+
// ─── Guardrail tables (v0.8.0 — Phase 3) ──────────────────
|
|
427
|
+
db.run(sql `
|
|
428
|
+
CREATE TABLE IF NOT EXISTS guardrail_rules (
|
|
429
|
+
id TEXT PRIMARY KEY,
|
|
430
|
+
tenant_id TEXT NOT NULL,
|
|
431
|
+
name TEXT NOT NULL,
|
|
432
|
+
description TEXT,
|
|
433
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
434
|
+
condition_type TEXT NOT NULL,
|
|
435
|
+
condition_config TEXT NOT NULL DEFAULT '{}',
|
|
436
|
+
action_type TEXT NOT NULL,
|
|
437
|
+
action_config TEXT NOT NULL DEFAULT '{}',
|
|
438
|
+
agent_id TEXT,
|
|
439
|
+
cooldown_minutes INTEGER NOT NULL DEFAULT 15,
|
|
440
|
+
dry_run INTEGER NOT NULL DEFAULT 0,
|
|
441
|
+
created_at TEXT NOT NULL,
|
|
442
|
+
updated_at TEXT NOT NULL
|
|
443
|
+
)
|
|
444
|
+
`);
|
|
445
|
+
db.run(sql `
|
|
446
|
+
CREATE TABLE IF NOT EXISTS guardrail_state (
|
|
447
|
+
rule_id TEXT NOT NULL,
|
|
448
|
+
tenant_id TEXT NOT NULL,
|
|
449
|
+
last_triggered_at TEXT,
|
|
450
|
+
trigger_count INTEGER NOT NULL DEFAULT 0,
|
|
451
|
+
last_evaluated_at TEXT,
|
|
452
|
+
current_value REAL,
|
|
453
|
+
PRIMARY KEY (rule_id, tenant_id)
|
|
454
|
+
)
|
|
455
|
+
`);
|
|
456
|
+
db.run(sql `
|
|
457
|
+
CREATE TABLE IF NOT EXISTS guardrail_trigger_history (
|
|
458
|
+
id TEXT PRIMARY KEY,
|
|
459
|
+
rule_id TEXT NOT NULL,
|
|
460
|
+
tenant_id TEXT NOT NULL,
|
|
461
|
+
triggered_at TEXT NOT NULL,
|
|
462
|
+
condition_value REAL NOT NULL,
|
|
463
|
+
condition_threshold REAL NOT NULL,
|
|
464
|
+
action_executed INTEGER NOT NULL DEFAULT 0,
|
|
465
|
+
action_result TEXT,
|
|
466
|
+
metadata TEXT NOT NULL DEFAULT '{}'
|
|
467
|
+
)
|
|
468
|
+
`);
|
|
469
|
+
// Guardrail indexes
|
|
470
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_guardrail_rules_tenant ON guardrail_rules(tenant_id)`);
|
|
471
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_guardrail_rules_tenant_enabled ON guardrail_rules(tenant_id, enabled)`);
|
|
472
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_guardrail_state_tenant ON guardrail_state(tenant_id)`);
|
|
473
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_guardrail_trigger_history_tenant ON guardrail_trigger_history(tenant_id)`);
|
|
474
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_guardrail_trigger_history_rule ON guardrail_trigger_history(rule_id, triggered_at)`);
|
|
475
|
+
// ─── Feature 8: Content guardrail columns ──────────────────
|
|
476
|
+
const grColsF8 = db.all(sql `PRAGMA table_info(guardrail_rules)`);
|
|
477
|
+
const grColNamesF8 = new Set(grColsF8.map((c) => c.name));
|
|
478
|
+
if (!grColNamesF8.has('direction')) {
|
|
479
|
+
db.run(sql `ALTER TABLE guardrail_rules ADD COLUMN direction TEXT DEFAULT 'both'`);
|
|
480
|
+
}
|
|
481
|
+
if (!grColNamesF8.has('tool_names')) {
|
|
482
|
+
db.run(sql `ALTER TABLE guardrail_rules ADD COLUMN tool_names TEXT`);
|
|
483
|
+
}
|
|
484
|
+
if (!grColNamesF8.has('priority')) {
|
|
485
|
+
db.run(sql `ALTER TABLE guardrail_rules ADD COLUMN priority INTEGER DEFAULT 0`);
|
|
486
|
+
}
|
|
487
|
+
// ─── Agent model override & pause columns (B1 — Story 1.2) ──────
|
|
488
|
+
// Idempotent: only adds columns if they don't already exist
|
|
489
|
+
const agentColsB1 = db.all(sql `PRAGMA table_info(agents)`);
|
|
490
|
+
const agentColNamesB1 = new Set(agentColsB1.map((c) => c.name));
|
|
491
|
+
if (!agentColNamesB1.has('model_override')) {
|
|
492
|
+
db.run(sql `ALTER TABLE agents ADD COLUMN model_override TEXT`);
|
|
493
|
+
}
|
|
494
|
+
if (!agentColNamesB1.has('paused_at')) {
|
|
495
|
+
db.run(sql `ALTER TABLE agents ADD COLUMN paused_at TEXT`);
|
|
496
|
+
}
|
|
497
|
+
if (!agentColNamesB1.has('pause_reason')) {
|
|
498
|
+
db.run(sql `ALTER TABLE agents ADD COLUMN pause_reason TEXT`);
|
|
499
|
+
}
|
|
500
|
+
// Partial index for finding paused agents efficiently
|
|
501
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_agents_paused ON agents(tenant_id, paused_at) WHERE paused_at IS NOT NULL`);
|
|
502
|
+
// ─── Phase 4: Sharing & Discovery tables (Stories 1.3) ──────────
|
|
503
|
+
db.run(sql `
|
|
504
|
+
CREATE TABLE IF NOT EXISTS sharing_config (
|
|
505
|
+
tenant_id TEXT PRIMARY KEY,
|
|
506
|
+
enabled INTEGER NOT NULL DEFAULT 0,
|
|
507
|
+
human_review_enabled INTEGER NOT NULL DEFAULT 0,
|
|
508
|
+
pool_endpoint TEXT,
|
|
509
|
+
anonymous_contributor_id TEXT,
|
|
510
|
+
purge_token TEXT,
|
|
511
|
+
rate_limit_per_hour INTEGER NOT NULL DEFAULT 50,
|
|
512
|
+
volume_alert_threshold INTEGER NOT NULL DEFAULT 100,
|
|
513
|
+
updated_at TEXT NOT NULL
|
|
514
|
+
)
|
|
515
|
+
`);
|
|
516
|
+
db.run(sql `
|
|
517
|
+
CREATE TABLE IF NOT EXISTS agent_sharing_config (
|
|
518
|
+
tenant_id TEXT NOT NULL,
|
|
519
|
+
agent_id TEXT NOT NULL,
|
|
520
|
+
enabled INTEGER NOT NULL DEFAULT 0,
|
|
521
|
+
categories TEXT NOT NULL DEFAULT '[]',
|
|
522
|
+
updated_at TEXT NOT NULL,
|
|
523
|
+
PRIMARY KEY (tenant_id, agent_id)
|
|
524
|
+
)
|
|
525
|
+
`);
|
|
526
|
+
db.run(sql `
|
|
527
|
+
CREATE TABLE IF NOT EXISTS deny_list_rules (
|
|
528
|
+
id TEXT PRIMARY KEY,
|
|
529
|
+
tenant_id TEXT NOT NULL,
|
|
530
|
+
pattern TEXT NOT NULL,
|
|
531
|
+
is_regex INTEGER NOT NULL DEFAULT 0,
|
|
532
|
+
reason TEXT NOT NULL,
|
|
533
|
+
created_at TEXT NOT NULL
|
|
534
|
+
)
|
|
535
|
+
`);
|
|
536
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_deny_list_rules_tenant ON deny_list_rules(tenant_id)`);
|
|
537
|
+
db.run(sql `
|
|
538
|
+
CREATE TABLE IF NOT EXISTS sharing_audit_log (
|
|
539
|
+
id TEXT PRIMARY KEY,
|
|
540
|
+
tenant_id TEXT NOT NULL,
|
|
541
|
+
event_type TEXT NOT NULL,
|
|
542
|
+
lesson_id TEXT,
|
|
543
|
+
anonymous_lesson_id TEXT,
|
|
544
|
+
lesson_hash TEXT,
|
|
545
|
+
redaction_findings TEXT,
|
|
546
|
+
query_text TEXT,
|
|
547
|
+
result_ids TEXT,
|
|
548
|
+
pool_endpoint TEXT,
|
|
549
|
+
initiated_by TEXT,
|
|
550
|
+
timestamp TEXT NOT NULL
|
|
551
|
+
)
|
|
552
|
+
`);
|
|
553
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_sharing_audit_tenant_ts ON sharing_audit_log(tenant_id, timestamp)`);
|
|
554
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_sharing_audit_type ON sharing_audit_log(tenant_id, event_type)`);
|
|
555
|
+
db.run(sql `
|
|
556
|
+
CREATE TABLE IF NOT EXISTS sharing_review_queue (
|
|
557
|
+
id TEXT PRIMARY KEY,
|
|
558
|
+
tenant_id TEXT NOT NULL,
|
|
559
|
+
lesson_id TEXT NOT NULL,
|
|
560
|
+
original_title TEXT NOT NULL,
|
|
561
|
+
original_content TEXT NOT NULL,
|
|
562
|
+
redacted_title TEXT NOT NULL,
|
|
563
|
+
redacted_content TEXT NOT NULL,
|
|
564
|
+
redaction_findings TEXT NOT NULL,
|
|
565
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
566
|
+
reviewed_by TEXT,
|
|
567
|
+
reviewed_at TEXT,
|
|
568
|
+
created_at TEXT NOT NULL,
|
|
569
|
+
expires_at TEXT NOT NULL
|
|
570
|
+
)
|
|
571
|
+
`);
|
|
572
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_review_queue_tenant_status ON sharing_review_queue(tenant_id, status)`);
|
|
573
|
+
db.run(sql `
|
|
574
|
+
CREATE TABLE IF NOT EXISTS anonymous_id_map (
|
|
575
|
+
tenant_id TEXT NOT NULL,
|
|
576
|
+
agent_id TEXT NOT NULL,
|
|
577
|
+
anonymous_agent_id TEXT NOT NULL,
|
|
578
|
+
valid_from TEXT NOT NULL,
|
|
579
|
+
valid_until TEXT NOT NULL,
|
|
580
|
+
PRIMARY KEY (tenant_id, agent_id, valid_from)
|
|
581
|
+
)
|
|
582
|
+
`);
|
|
583
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_anon_map_anon_id ON anonymous_id_map(anonymous_agent_id)`);
|
|
584
|
+
db.run(sql `
|
|
585
|
+
CREATE TABLE IF NOT EXISTS capability_registry (
|
|
586
|
+
id TEXT PRIMARY KEY,
|
|
587
|
+
tenant_id TEXT NOT NULL,
|
|
588
|
+
agent_id TEXT NOT NULL,
|
|
589
|
+
task_type TEXT NOT NULL,
|
|
590
|
+
custom_type TEXT,
|
|
591
|
+
input_schema TEXT NOT NULL,
|
|
592
|
+
output_schema TEXT NOT NULL,
|
|
593
|
+
quality_metrics TEXT NOT NULL DEFAULT '{}',
|
|
594
|
+
estimated_latency_ms INTEGER,
|
|
595
|
+
estimated_cost_usd REAL,
|
|
596
|
+
max_input_bytes INTEGER,
|
|
597
|
+
scope TEXT NOT NULL DEFAULT 'internal',
|
|
598
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
599
|
+
accept_delegations INTEGER NOT NULL DEFAULT 0,
|
|
600
|
+
inbound_rate_limit INTEGER NOT NULL DEFAULT 10,
|
|
601
|
+
outbound_rate_limit INTEGER NOT NULL DEFAULT 20,
|
|
602
|
+
created_at TEXT NOT NULL,
|
|
603
|
+
updated_at TEXT NOT NULL
|
|
604
|
+
)
|
|
605
|
+
`);
|
|
606
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_capability_tenant_agent ON capability_registry(tenant_id, agent_id)`);
|
|
607
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_capability_task_type ON capability_registry(tenant_id, task_type)`);
|
|
608
|
+
db.run(sql `
|
|
609
|
+
CREATE TABLE IF NOT EXISTS delegation_log (
|
|
610
|
+
id TEXT PRIMARY KEY,
|
|
611
|
+
tenant_id TEXT NOT NULL,
|
|
612
|
+
direction TEXT NOT NULL,
|
|
613
|
+
agent_id TEXT NOT NULL,
|
|
614
|
+
anonymous_target_id TEXT,
|
|
615
|
+
anonymous_source_id TEXT,
|
|
616
|
+
task_type TEXT NOT NULL,
|
|
617
|
+
status TEXT NOT NULL,
|
|
618
|
+
request_size_bytes INTEGER,
|
|
619
|
+
response_size_bytes INTEGER,
|
|
620
|
+
execution_time_ms INTEGER,
|
|
621
|
+
cost_usd REAL,
|
|
622
|
+
created_at TEXT NOT NULL,
|
|
623
|
+
completed_at TEXT
|
|
624
|
+
)
|
|
625
|
+
`);
|
|
626
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_delegation_tenant_ts ON delegation_log(tenant_id, created_at)`);
|
|
627
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_delegation_agent ON delegation_log(tenant_id, agent_id)`);
|
|
628
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_delegation_status ON delegation_log(tenant_id, status)`);
|
|
629
|
+
// ─── Users Table (Enterprise Auth — S3) ─────────────────
|
|
630
|
+
db.run(sql `
|
|
631
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
632
|
+
id TEXT PRIMARY KEY,
|
|
633
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
634
|
+
email TEXT NOT NULL,
|
|
635
|
+
display_name TEXT,
|
|
636
|
+
oidc_subject TEXT,
|
|
637
|
+
oidc_issuer TEXT,
|
|
638
|
+
role TEXT NOT NULL DEFAULT 'viewer',
|
|
639
|
+
created_at INTEGER NOT NULL,
|
|
640
|
+
updated_at INTEGER NOT NULL,
|
|
641
|
+
last_login_at INTEGER,
|
|
642
|
+
disabled_at INTEGER
|
|
643
|
+
)
|
|
644
|
+
`);
|
|
645
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_users_tenant ON users(tenant_id)`);
|
|
646
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_users_email ON users(email)`);
|
|
647
|
+
db.run(sql `CREATE UNIQUE INDEX IF NOT EXISTS idx_users_tenant_email ON users(tenant_id, email)`);
|
|
648
|
+
db.run(sql `CREATE UNIQUE INDEX IF NOT EXISTS idx_users_oidc ON users(oidc_issuer, oidc_subject)`);
|
|
649
|
+
// ─── Refresh Tokens Table (Enterprise Auth — S3) ───────
|
|
650
|
+
db.run(sql `
|
|
651
|
+
CREATE TABLE IF NOT EXISTS refresh_tokens (
|
|
652
|
+
id TEXT PRIMARY KEY,
|
|
653
|
+
user_id TEXT NOT NULL REFERENCES users(id),
|
|
654
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
655
|
+
token_hash TEXT NOT NULL,
|
|
656
|
+
expires_at INTEGER NOT NULL,
|
|
657
|
+
created_at INTEGER NOT NULL,
|
|
658
|
+
revoked_at INTEGER,
|
|
659
|
+
user_agent TEXT,
|
|
660
|
+
ip_address TEXT
|
|
661
|
+
)
|
|
662
|
+
`);
|
|
663
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user ON refresh_tokens(user_id)`);
|
|
664
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_refresh_tokens_hash ON refresh_tokens(token_hash)`);
|
|
665
|
+
// ─── Audit Log table (SH-2) ──────────────────────────────
|
|
666
|
+
db.run(sql `
|
|
667
|
+
CREATE TABLE IF NOT EXISTS audit_log (
|
|
668
|
+
id TEXT PRIMARY KEY,
|
|
669
|
+
timestamp TEXT NOT NULL,
|
|
670
|
+
tenant_id TEXT NOT NULL,
|
|
671
|
+
actor_type TEXT NOT NULL,
|
|
672
|
+
actor_id TEXT NOT NULL,
|
|
673
|
+
action TEXT NOT NULL,
|
|
674
|
+
resource_type TEXT,
|
|
675
|
+
resource_id TEXT,
|
|
676
|
+
details TEXT NOT NULL DEFAULT '{}',
|
|
677
|
+
ip_address TEXT,
|
|
678
|
+
user_agent TEXT
|
|
679
|
+
)
|
|
680
|
+
`);
|
|
681
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_audit_log_tenant_ts ON audit_log(tenant_id, timestamp)`);
|
|
682
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_audit_log_action ON audit_log(action)`);
|
|
683
|
+
// ─── API Key Rotation columns (SH-6) ──────────────────
|
|
684
|
+
const apiKeyColsSH6 = db.all(sql `PRAGMA table_info(api_keys)`);
|
|
685
|
+
const apiKeyColNamesSH6 = new Set(apiKeyColsSH6.map((c) => c.name));
|
|
686
|
+
if (!apiKeyColNamesSH6.has('rotated_at')) {
|
|
687
|
+
db.run(sql `ALTER TABLE api_keys ADD COLUMN rotated_at INTEGER`);
|
|
688
|
+
}
|
|
689
|
+
if (!apiKeyColNamesSH6.has('expires_at')) {
|
|
690
|
+
db.run(sql `ALTER TABLE api_keys ADD COLUMN expires_at INTEGER`);
|
|
691
|
+
}
|
|
692
|
+
// ─── Discovery Config (Story 5.4) ──────────────────────
|
|
693
|
+
db.run(sql `
|
|
694
|
+
CREATE TABLE IF NOT EXISTS discovery_config (
|
|
695
|
+
tenant_id TEXT PRIMARY KEY,
|
|
696
|
+
min_trust_threshold INTEGER NOT NULL DEFAULT 60,
|
|
697
|
+
delegation_enabled INTEGER NOT NULL DEFAULT 0,
|
|
698
|
+
updated_at TEXT NOT NULL
|
|
699
|
+
)
|
|
700
|
+
`);
|
|
701
|
+
// ─── Cost Budget tables (Feature 5) ──────────────────────
|
|
702
|
+
db.run(sql `
|
|
703
|
+
CREATE TABLE IF NOT EXISTS cost_budgets (
|
|
704
|
+
id TEXT PRIMARY KEY,
|
|
705
|
+
tenant_id TEXT NOT NULL,
|
|
706
|
+
scope TEXT NOT NULL,
|
|
707
|
+
agent_id TEXT,
|
|
708
|
+
period TEXT NOT NULL,
|
|
709
|
+
limit_usd REAL NOT NULL,
|
|
710
|
+
on_breach TEXT NOT NULL DEFAULT 'alert',
|
|
711
|
+
downgrade_target_model TEXT,
|
|
712
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
713
|
+
created_at TEXT NOT NULL,
|
|
714
|
+
updated_at TEXT NOT NULL
|
|
715
|
+
)
|
|
716
|
+
`);
|
|
717
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_cost_budgets_tenant ON cost_budgets(tenant_id)`);
|
|
718
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_cost_budgets_tenant_enabled ON cost_budgets(tenant_id, enabled)`);
|
|
719
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_cost_budgets_tenant_agent ON cost_budgets(tenant_id, agent_id)`);
|
|
720
|
+
db.run(sql `
|
|
721
|
+
CREATE TABLE IF NOT EXISTS cost_budget_state (
|
|
722
|
+
budget_id TEXT NOT NULL,
|
|
723
|
+
tenant_id TEXT NOT NULL,
|
|
724
|
+
last_breach_at TEXT,
|
|
725
|
+
breach_count INTEGER NOT NULL DEFAULT 0,
|
|
726
|
+
current_spend REAL,
|
|
727
|
+
period_start TEXT,
|
|
728
|
+
PRIMARY KEY (budget_id, tenant_id)
|
|
729
|
+
)
|
|
730
|
+
`);
|
|
731
|
+
// ─── Notification Channels (Feature 12) ──────────────────
|
|
732
|
+
db.run(sql `
|
|
733
|
+
CREATE TABLE IF NOT EXISTS notification_channels (
|
|
734
|
+
id TEXT PRIMARY KEY,
|
|
735
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
736
|
+
type TEXT NOT NULL,
|
|
737
|
+
name TEXT NOT NULL,
|
|
738
|
+
config TEXT NOT NULL,
|
|
739
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
740
|
+
created_at TEXT NOT NULL,
|
|
741
|
+
updated_at TEXT NOT NULL
|
|
742
|
+
)
|
|
743
|
+
`);
|
|
744
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_notification_channels_tenant ON notification_channels(tenant_id)`);
|
|
745
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_notification_channels_type ON notification_channels(tenant_id, type)`);
|
|
746
|
+
db.run(sql `
|
|
747
|
+
CREATE TABLE IF NOT EXISTS notification_log (
|
|
748
|
+
id TEXT PRIMARY KEY,
|
|
749
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
750
|
+
channel_id TEXT NOT NULL,
|
|
751
|
+
rule_id TEXT,
|
|
752
|
+
rule_type TEXT,
|
|
753
|
+
status TEXT NOT NULL,
|
|
754
|
+
attempt INTEGER NOT NULL DEFAULT 1,
|
|
755
|
+
error_message TEXT,
|
|
756
|
+
payload_summary TEXT,
|
|
757
|
+
created_at TEXT NOT NULL
|
|
758
|
+
)
|
|
759
|
+
`);
|
|
760
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_notification_log_tenant ON notification_log(tenant_id)`);
|
|
761
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_notification_log_channel ON notification_log(channel_id)`);
|
|
762
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_notification_log_created ON notification_log(tenant_id, created_at)`);
|
|
763
|
+
db.run(sql `
|
|
764
|
+
CREATE TABLE IF NOT EXISTS cost_anomaly_config (
|
|
765
|
+
tenant_id TEXT PRIMARY KEY,
|
|
766
|
+
multiplier REAL NOT NULL DEFAULT 3.0,
|
|
767
|
+
min_sessions INTEGER NOT NULL DEFAULT 5,
|
|
768
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
769
|
+
updated_at TEXT NOT NULL
|
|
770
|
+
)
|
|
771
|
+
`);
|
|
772
|
+
// ─── Eval Framework tables (Feature 15) ──────────────────
|
|
773
|
+
db.run(sql `
|
|
774
|
+
CREATE TABLE IF NOT EXISTS eval_datasets (
|
|
775
|
+
id TEXT PRIMARY KEY,
|
|
776
|
+
tenant_id TEXT NOT NULL,
|
|
777
|
+
agent_id TEXT,
|
|
778
|
+
name TEXT NOT NULL,
|
|
779
|
+
description TEXT,
|
|
780
|
+
version INTEGER NOT NULL DEFAULT 1,
|
|
781
|
+
parent_id TEXT,
|
|
782
|
+
immutable INTEGER NOT NULL DEFAULT 0,
|
|
783
|
+
created_at TEXT NOT NULL,
|
|
784
|
+
updated_at TEXT NOT NULL
|
|
785
|
+
)
|
|
786
|
+
`);
|
|
787
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_eval_datasets_tenant ON eval_datasets(tenant_id)`);
|
|
788
|
+
db.run(sql `
|
|
789
|
+
CREATE TABLE IF NOT EXISTS eval_test_cases (
|
|
790
|
+
id TEXT PRIMARY KEY,
|
|
791
|
+
dataset_id TEXT NOT NULL REFERENCES eval_datasets(id) ON DELETE CASCADE,
|
|
792
|
+
tenant_id TEXT NOT NULL,
|
|
793
|
+
input TEXT NOT NULL,
|
|
794
|
+
expected_output TEXT,
|
|
795
|
+
tags TEXT NOT NULL DEFAULT '[]',
|
|
796
|
+
metadata TEXT NOT NULL DEFAULT '{}',
|
|
797
|
+
scoring_criteria TEXT,
|
|
798
|
+
sort_order INTEGER NOT NULL DEFAULT 0,
|
|
799
|
+
created_at TEXT NOT NULL
|
|
800
|
+
)
|
|
801
|
+
`);
|
|
802
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_eval_test_cases_dataset ON eval_test_cases(dataset_id)`);
|
|
803
|
+
db.run(sql `
|
|
804
|
+
CREATE TABLE IF NOT EXISTS eval_runs (
|
|
805
|
+
id TEXT PRIMARY KEY,
|
|
806
|
+
tenant_id TEXT NOT NULL,
|
|
807
|
+
dataset_id TEXT NOT NULL REFERENCES eval_datasets(id),
|
|
808
|
+
dataset_version INTEGER NOT NULL,
|
|
809
|
+
agent_id TEXT NOT NULL,
|
|
810
|
+
webhook_url TEXT NOT NULL,
|
|
811
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
812
|
+
config TEXT NOT NULL DEFAULT '{}',
|
|
813
|
+
baseline_run_id TEXT,
|
|
814
|
+
total_cases INTEGER NOT NULL DEFAULT 0,
|
|
815
|
+
passed_cases INTEGER NOT NULL DEFAULT 0,
|
|
816
|
+
failed_cases INTEGER NOT NULL DEFAULT 0,
|
|
817
|
+
avg_score REAL,
|
|
818
|
+
total_cost_usd REAL,
|
|
819
|
+
total_duration_ms INTEGER,
|
|
820
|
+
started_at TEXT,
|
|
821
|
+
completed_at TEXT,
|
|
822
|
+
created_at TEXT NOT NULL,
|
|
823
|
+
error TEXT
|
|
824
|
+
)
|
|
825
|
+
`);
|
|
826
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_eval_runs_tenant ON eval_runs(tenant_id)`);
|
|
827
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_eval_runs_dataset ON eval_runs(dataset_id)`);
|
|
828
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_eval_runs_agent ON eval_runs(tenant_id, agent_id)`);
|
|
829
|
+
db.run(sql `
|
|
830
|
+
CREATE TABLE IF NOT EXISTS eval_results (
|
|
831
|
+
id TEXT PRIMARY KEY,
|
|
832
|
+
run_id TEXT NOT NULL REFERENCES eval_runs(id) ON DELETE CASCADE,
|
|
833
|
+
test_case_id TEXT NOT NULL REFERENCES eval_test_cases(id),
|
|
834
|
+
tenant_id TEXT NOT NULL,
|
|
835
|
+
session_id TEXT,
|
|
836
|
+
actual_output TEXT,
|
|
837
|
+
score REAL NOT NULL,
|
|
838
|
+
passed INTEGER NOT NULL,
|
|
839
|
+
scorer_type TEXT NOT NULL,
|
|
840
|
+
scorer_details TEXT NOT NULL DEFAULT '{}',
|
|
841
|
+
latency_ms INTEGER,
|
|
842
|
+
cost_usd REAL,
|
|
843
|
+
token_count INTEGER,
|
|
844
|
+
error TEXT,
|
|
845
|
+
created_at TEXT NOT NULL
|
|
846
|
+
)
|
|
847
|
+
`);
|
|
848
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_eval_results_run ON eval_results(run_id)`);
|
|
849
|
+
// ─── Prompt Management tables (Feature 19) ──────────────────
|
|
850
|
+
db.run(sql `
|
|
851
|
+
CREATE TABLE IF NOT EXISTS prompt_templates (
|
|
852
|
+
id TEXT PRIMARY KEY,
|
|
853
|
+
tenant_id TEXT NOT NULL,
|
|
854
|
+
name TEXT NOT NULL,
|
|
855
|
+
description TEXT,
|
|
856
|
+
category TEXT NOT NULL DEFAULT 'general',
|
|
857
|
+
current_version_id TEXT,
|
|
858
|
+
created_at TEXT NOT NULL,
|
|
859
|
+
updated_at TEXT NOT NULL,
|
|
860
|
+
deleted_at TEXT
|
|
861
|
+
)
|
|
862
|
+
`);
|
|
863
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_prompt_templates_tenant ON prompt_templates(tenant_id)`);
|
|
864
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_prompt_templates_tenant_cat ON prompt_templates(tenant_id, category)`);
|
|
865
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_prompt_templates_tenant_name ON prompt_templates(tenant_id, name)`);
|
|
866
|
+
db.run(sql `
|
|
867
|
+
CREATE TABLE IF NOT EXISTS prompt_versions (
|
|
868
|
+
id TEXT PRIMARY KEY,
|
|
869
|
+
template_id TEXT NOT NULL,
|
|
870
|
+
tenant_id TEXT NOT NULL,
|
|
871
|
+
version_number INTEGER NOT NULL,
|
|
872
|
+
content TEXT NOT NULL,
|
|
873
|
+
variables TEXT,
|
|
874
|
+
content_hash TEXT NOT NULL,
|
|
875
|
+
changelog TEXT,
|
|
876
|
+
created_by TEXT,
|
|
877
|
+
created_at TEXT NOT NULL,
|
|
878
|
+
UNIQUE(template_id, version_number)
|
|
879
|
+
)
|
|
880
|
+
`);
|
|
881
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_prompt_versions_tenant ON prompt_versions(tenant_id)`);
|
|
882
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_prompt_versions_hash ON prompt_versions(content_hash)`);
|
|
883
|
+
db.run(sql `
|
|
884
|
+
CREATE TABLE IF NOT EXISTS prompt_fingerprints (
|
|
885
|
+
content_hash TEXT NOT NULL,
|
|
886
|
+
tenant_id TEXT NOT NULL,
|
|
887
|
+
agent_id TEXT NOT NULL,
|
|
888
|
+
first_seen_at TEXT NOT NULL,
|
|
889
|
+
last_seen_at TEXT NOT NULL,
|
|
890
|
+
call_count INTEGER NOT NULL DEFAULT 0,
|
|
891
|
+
template_id TEXT,
|
|
892
|
+
sample_content TEXT,
|
|
893
|
+
PRIMARY KEY (content_hash, tenant_id, agent_id)
|
|
894
|
+
)
|
|
895
|
+
`);
|
|
896
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_prompt_fp_tenant ON prompt_fingerprints(tenant_id)`);
|
|
897
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_prompt_fp_agent ON prompt_fingerprints(tenant_id, agent_id)`);
|
|
898
|
+
db.run(sql `CREATE INDEX IF NOT EXISTS idx_prompt_fp_template ON prompt_fingerprints(template_id)`);
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Verify that WAL mode is enabled.
|
|
902
|
+
*/
|
|
903
|
+
export function verifyPragmas(db) {
|
|
904
|
+
const journalMode = db.get(sql `PRAGMA journal_mode`)?.journal_mode ?? '';
|
|
905
|
+
const synchronous = db.get(sql `PRAGMA synchronous`)?.synchronous ?? -1;
|
|
906
|
+
const cacheSize = db.get(sql `PRAGMA cache_size`)?.cache_size ?? 0;
|
|
907
|
+
// SQLite returns { timeout: N } for PRAGMA busy_timeout
|
|
908
|
+
const busyTimeout = db.get(sql `PRAGMA busy_timeout`)?.timeout ?? 0;
|
|
909
|
+
const foreignKeys = db.get(sql `PRAGMA foreign_keys`)?.foreign_keys === 1;
|
|
910
|
+
// synchronous: 0=OFF, 1=NORMAL, 2=FULL, 3=EXTRA
|
|
911
|
+
const syncNames = { 0: 'OFF', 1: 'NORMAL', 2: 'FULL', 3: 'EXTRA' };
|
|
912
|
+
return {
|
|
913
|
+
journalMode,
|
|
914
|
+
synchronous: syncNames[synchronous] ?? String(synchronous),
|
|
915
|
+
cacheSize,
|
|
916
|
+
busyTimeout,
|
|
917
|
+
foreignKeys,
|
|
918
|
+
};
|
|
919
|
+
}
|
|
920
|
+
//# sourceMappingURL=migrate.sqlite.js.map
|