@revealui/ai 0.1.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 +22 -0
- package/LICENSE.commercial +112 -0
- package/README.md +314 -0
- package/dist/a2a/card.d.ts +26 -0
- package/dist/a2a/card.d.ts.map +1 -0
- package/dist/a2a/card.js +173 -0
- package/dist/a2a/handler.d.ts +26 -0
- package/dist/a2a/handler.d.ts.map +1 -0
- package/dist/a2a/handler.js +170 -0
- package/dist/a2a/index.d.ts +10 -0
- package/dist/a2a/index.d.ts.map +1 -0
- package/dist/a2a/index.js +9 -0
- package/dist/a2a/task-store.d.ts +42 -0
- package/dist/a2a/task-store.d.ts.map +1 -0
- package/dist/a2a/task-store.js +99 -0
- package/dist/audit/emitter.d.ts +34 -0
- package/dist/audit/emitter.d.ts.map +1 -0
- package/dist/audit/emitter.js +34 -0
- package/dist/audit/index.d.ts +44 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +48 -0
- package/dist/audit/observer.d.ts +108 -0
- package/dist/audit/observer.d.ts.map +1 -0
- package/dist/audit/observer.js +271 -0
- package/dist/audit/policy.d.ts +70 -0
- package/dist/audit/policy.d.ts.map +1 -0
- package/dist/audit/policy.js +209 -0
- package/dist/audit/store.d.ts +42 -0
- package/dist/audit/store.d.ts.map +1 -0
- package/dist/audit/store.js +80 -0
- package/dist/audit/types.d.ts +169 -0
- package/dist/audit/types.d.ts.map +1 -0
- package/dist/audit/types.js +80 -0
- package/dist/client/hooks/index.d.ts +22 -0
- package/dist/client/hooks/index.d.ts.map +1 -0
- package/dist/client/hooks/index.js +21 -0
- package/dist/client/hooks/useAgentContext.d.ts +30 -0
- package/dist/client/hooks/useAgentContext.d.ts.map +1 -0
- package/dist/client/hooks/useAgentContext.js +161 -0
- package/dist/client/hooks/useAgentEvents.d.ts +126 -0
- package/dist/client/hooks/useAgentEvents.d.ts.map +1 -0
- package/dist/client/hooks/useAgentEvents.js +232 -0
- package/dist/client/hooks/useAgentStream.d.ts +44 -0
- package/dist/client/hooks/useAgentStream.d.ts.map +1 -0
- package/dist/client/hooks/useAgentStream.js +101 -0
- package/dist/client/hooks/useEpisodicMemory.d.ts +25 -0
- package/dist/client/hooks/useEpisodicMemory.d.ts.map +1 -0
- package/dist/client/hooks/useEpisodicMemory.js +174 -0
- package/dist/client/hooks/useWorkingMemory.d.ts +57 -0
- package/dist/client/hooks/useWorkingMemory.d.ts.map +1 -0
- package/dist/client/hooks/useWorkingMemory.js +276 -0
- package/dist/client/index.d.ts +14 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +13 -0
- package/dist/embeddings/index.d.ts +51 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +73 -0
- package/dist/index.d.ts +83 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +103 -0
- package/dist/inference/context-assembly.d.ts +27 -0
- package/dist/inference/context-assembly.d.ts.map +1 -0
- package/dist/inference/context-assembly.js +81 -0
- package/dist/inference/overflow-compressor.d.ts +17 -0
- package/dist/inference/overflow-compressor.d.ts.map +1 -0
- package/dist/inference/overflow-compressor.js +40 -0
- package/dist/inference/runRag.d.ts +35 -0
- package/dist/inference/runRag.d.ts.map +1 -0
- package/dist/inference/runRag.js +53 -0
- package/dist/ingestion/bm25.d.ts +29 -0
- package/dist/ingestion/bm25.d.ts.map +1 -0
- package/dist/ingestion/bm25.js +161 -0
- package/dist/ingestion/cms-indexer.d.ts +39 -0
- package/dist/ingestion/cms-indexer.d.ts.map +1 -0
- package/dist/ingestion/cms-indexer.js +74 -0
- package/dist/ingestion/file-parsers.d.ts +51 -0
- package/dist/ingestion/file-parsers.d.ts.map +1 -0
- package/dist/ingestion/file-parsers.js +247 -0
- package/dist/ingestion/hybrid-search.d.ts +22 -0
- package/dist/ingestion/hybrid-search.d.ts.map +1 -0
- package/dist/ingestion/hybrid-search.js +63 -0
- package/dist/ingestion/index.d.ts +9 -0
- package/dist/ingestion/index.d.ts.map +1 -0
- package/dist/ingestion/index.js +8 -0
- package/dist/ingestion/pipeline.d.ts +35 -0
- package/dist/ingestion/pipeline.d.ts.map +1 -0
- package/dist/ingestion/pipeline.js +114 -0
- package/dist/ingestion/rag-vector-service.d.ts +34 -0
- package/dist/ingestion/rag-vector-service.d.ts.map +1 -0
- package/dist/ingestion/rag-vector-service.js +98 -0
- package/dist/ingestion/reranker.d.ts +10 -0
- package/dist/ingestion/reranker.d.ts.map +1 -0
- package/dist/ingestion/reranker.js +41 -0
- package/dist/ingestion/text-splitter.d.ts +25 -0
- package/dist/ingestion/text-splitter.d.ts.map +1 -0
- package/dist/ingestion/text-splitter.js +119 -0
- package/dist/llm/cache-utils.d.ts +146 -0
- package/dist/llm/cache-utils.d.ts.map +1 -0
- package/dist/llm/cache-utils.js +204 -0
- package/dist/llm/client.d.ts +134 -0
- package/dist/llm/client.d.ts.map +1 -0
- package/dist/llm/client.js +497 -0
- package/dist/llm/key-validator.d.ts +25 -0
- package/dist/llm/key-validator.d.ts.map +1 -0
- package/dist/llm/key-validator.js +101 -0
- package/dist/llm/provider-health.d.ts +40 -0
- package/dist/llm/provider-health.d.ts.map +1 -0
- package/dist/llm/provider-health.js +97 -0
- package/dist/llm/providers/anthropic.d.ts +31 -0
- package/dist/llm/providers/anthropic.d.ts.map +1 -0
- package/dist/llm/providers/anthropic.js +248 -0
- package/dist/llm/providers/base.d.ts +111 -0
- package/dist/llm/providers/base.d.ts.map +1 -0
- package/dist/llm/providers/base.js +6 -0
- package/dist/llm/providers/groq.d.ts +23 -0
- package/dist/llm/providers/groq.d.ts.map +1 -0
- package/dist/llm/providers/groq.js +27 -0
- package/dist/llm/providers/ollama.d.ts +27 -0
- package/dist/llm/providers/ollama.d.ts.map +1 -0
- package/dist/llm/providers/ollama.js +48 -0
- package/dist/llm/providers/openai.d.ts +19 -0
- package/dist/llm/providers/openai.d.ts.map +1 -0
- package/dist/llm/providers/openai.js +245 -0
- package/dist/llm/providers/vultr.d.ts +18 -0
- package/dist/llm/providers/vultr.d.ts.map +1 -0
- package/dist/llm/providers/vultr.js +168 -0
- package/dist/llm/response-cache.d.ts +166 -0
- package/dist/llm/response-cache.d.ts.map +1 -0
- package/dist/llm/response-cache.js +233 -0
- package/dist/llm/semantic-cache.d.ts +179 -0
- package/dist/llm/semantic-cache.d.ts.map +1 -0
- package/dist/llm/semantic-cache.js +306 -0
- package/dist/llm/server.d.ts +14 -0
- package/dist/llm/server.d.ts.map +1 -0
- package/dist/llm/server.js +15 -0
- package/dist/llm/token-counter.d.ts +48 -0
- package/dist/llm/token-counter.d.ts.map +1 -0
- package/dist/llm/token-counter.js +77 -0
- package/dist/llm/workspace-provider-config.d.ts +38 -0
- package/dist/llm/workspace-provider-config.d.ts.map +1 -0
- package/dist/llm/workspace-provider-config.js +47 -0
- package/dist/memory/agent/context-manager.d.ts +148 -0
- package/dist/memory/agent/context-manager.d.ts.map +1 -0
- package/dist/memory/agent/context-manager.js +284 -0
- package/dist/memory/agent/index.d.ts +7 -0
- package/dist/memory/agent/index.d.ts.map +1 -0
- package/dist/memory/agent/index.js +6 -0
- package/dist/memory/crdt/index.d.ts +13 -0
- package/dist/memory/crdt/index.d.ts.map +1 -0
- package/dist/memory/crdt/index.js +12 -0
- package/dist/memory/crdt/lww-register.d.ts +108 -0
- package/dist/memory/crdt/lww-register.d.ts.map +1 -0
- package/dist/memory/crdt/lww-register.js +169 -0
- package/dist/memory/crdt/or-set.d.ts +141 -0
- package/dist/memory/crdt/or-set.d.ts.map +1 -0
- package/dist/memory/crdt/or-set.js +291 -0
- package/dist/memory/crdt/pn-counter.d.ts +116 -0
- package/dist/memory/crdt/pn-counter.d.ts.map +1 -0
- package/dist/memory/crdt/pn-counter.js +174 -0
- package/dist/memory/crdt/vector-clock.d.ts +115 -0
- package/dist/memory/crdt/vector-clock.d.ts.map +1 -0
- package/dist/memory/crdt/vector-clock.js +179 -0
- package/dist/memory/errors/index.d.ts +56 -0
- package/dist/memory/errors/index.d.ts.map +1 -0
- package/dist/memory/errors/index.js +85 -0
- package/dist/memory/index.d.ts +21 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +20 -0
- package/dist/memory/persistence/crdt-persistence.d.ts +85 -0
- package/dist/memory/persistence/crdt-persistence.d.ts.map +1 -0
- package/dist/memory/persistence/crdt-persistence.js +204 -0
- package/dist/memory/persistence/index.d.ts +7 -0
- package/dist/memory/persistence/index.d.ts.map +1 -0
- package/dist/memory/persistence/index.js +6 -0
- package/dist/memory/preferences/index.d.ts +7 -0
- package/dist/memory/preferences/index.d.ts.map +1 -0
- package/dist/memory/preferences/index.js +6 -0
- package/dist/memory/preferences/user-preferences-manager.d.ts +133 -0
- package/dist/memory/preferences/user-preferences-manager.d.ts.map +1 -0
- package/dist/memory/preferences/user-preferences-manager.js +342 -0
- package/dist/memory/services/index.d.ts +8 -0
- package/dist/memory/services/index.d.ts.map +1 -0
- package/dist/memory/services/index.js +6 -0
- package/dist/memory/services/node-id-service.d.ts +75 -0
- package/dist/memory/services/node-id-service.d.ts.map +1 -0
- package/dist/memory/services/node-id-service.js +190 -0
- package/dist/memory/stores/episodic-memory.d.ts +182 -0
- package/dist/memory/stores/episodic-memory.d.ts.map +1 -0
- package/dist/memory/stores/episodic-memory.js +378 -0
- package/dist/memory/stores/index.d.ts +16 -0
- package/dist/memory/stores/index.d.ts.map +1 -0
- package/dist/memory/stores/index.js +15 -0
- package/dist/memory/stores/procedural-memory.d.ts +89 -0
- package/dist/memory/stores/procedural-memory.d.ts.map +1 -0
- package/dist/memory/stores/procedural-memory.js +152 -0
- package/dist/memory/stores/semantic-memory.d.ts +92 -0
- package/dist/memory/stores/semantic-memory.d.ts.map +1 -0
- package/dist/memory/stores/semantic-memory.js +155 -0
- package/dist/memory/stores/working-memory.d.ts +225 -0
- package/dist/memory/stores/working-memory.d.ts.map +1 -0
- package/dist/memory/stores/working-memory.js +336 -0
- package/dist/memory/utils/deep-clone.d.ts +10 -0
- package/dist/memory/utils/deep-clone.d.ts.map +1 -0
- package/dist/memory/utils/deep-clone.js +9 -0
- package/dist/memory/utils/index.d.ts +8 -0
- package/dist/memory/utils/index.d.ts.map +1 -0
- package/dist/memory/utils/index.js +7 -0
- package/dist/memory/utils/logger.d.ts +21 -0
- package/dist/memory/utils/logger.d.ts.map +1 -0
- package/dist/memory/utils/logger.js +62 -0
- package/dist/memory/utils/sql-helpers.d.ts +97 -0
- package/dist/memory/utils/sql-helpers.d.ts.map +1 -0
- package/dist/memory/utils/sql-helpers.js +214 -0
- package/dist/memory/utils/validation.d.ts +62 -0
- package/dist/memory/utils/validation.d.ts.map +1 -0
- package/dist/memory/utils/validation.js +244 -0
- package/dist/memory/vector/index.d.ts +12 -0
- package/dist/memory/vector/index.d.ts.map +1 -0
- package/dist/memory/vector/index.js +14 -0
- package/dist/memory/vector/vector-memory-service.d.ts +88 -0
- package/dist/memory/vector/vector-memory-service.d.ts.map +1 -0
- package/dist/memory/vector/vector-memory-service.js +335 -0
- package/dist/observability/logger.d.ts +79 -0
- package/dist/observability/logger.d.ts.map +1 -0
- package/dist/observability/logger.js +165 -0
- package/dist/observability/metrics.d.ts +43 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +197 -0
- package/dist/observability/query.d.ts +150 -0
- package/dist/observability/query.d.ts.map +1 -0
- package/dist/observability/query.js +339 -0
- package/dist/observability/types.d.ts +140 -0
- package/dist/observability/types.d.ts.map +1 -0
- package/dist/observability/types.js +6 -0
- package/dist/orchestration/agent.d.ts +98 -0
- package/dist/orchestration/agent.d.ts.map +1 -0
- package/dist/orchestration/agent.js +6 -0
- package/dist/orchestration/defaults.d.ts +21 -0
- package/dist/orchestration/defaults.d.ts.map +1 -0
- package/dist/orchestration/defaults.js +22 -0
- package/dist/orchestration/memory-integration.d.ts +58 -0
- package/dist/orchestration/memory-integration.d.ts.map +1 -0
- package/dist/orchestration/memory-integration.js +130 -0
- package/dist/orchestration/orchestrator.d.ts +67 -0
- package/dist/orchestration/orchestrator.d.ts.map +1 -0
- package/dist/orchestration/orchestrator.js +174 -0
- package/dist/orchestration/runtime.d.ts +82 -0
- package/dist/orchestration/runtime.d.ts.map +1 -0
- package/dist/orchestration/runtime.js +251 -0
- package/dist/orchestration/streaming-runtime.d.ts +36 -0
- package/dist/orchestration/streaming-runtime.d.ts.map +1 -0
- package/dist/orchestration/streaming-runtime.js +175 -0
- package/dist/orchestration/ticket-agent.d.ts +70 -0
- package/dist/orchestration/ticket-agent.d.ts.map +1 -0
- package/dist/orchestration/ticket-agent.js +146 -0
- package/dist/skills/activation/index.d.ts +7 -0
- package/dist/skills/activation/index.d.ts.map +1 -0
- package/dist/skills/activation/index.js +6 -0
- package/dist/skills/activation/skill-activator.d.ts +68 -0
- package/dist/skills/activation/skill-activator.d.ts.map +1 -0
- package/dist/skills/activation/skill-activator.js +224 -0
- package/dist/skills/catalog/catalog-search.d.ts +55 -0
- package/dist/skills/catalog/catalog-search.d.ts.map +1 -0
- package/dist/skills/catalog/catalog-search.js +111 -0
- package/dist/skills/catalog/catalog-types.d.ts +81 -0
- package/dist/skills/catalog/catalog-types.d.ts.map +1 -0
- package/dist/skills/catalog/catalog-types.js +66 -0
- package/dist/skills/catalog/index.d.ts +9 -0
- package/dist/skills/catalog/index.d.ts.map +1 -0
- package/dist/skills/catalog/index.js +7 -0
- package/dist/skills/catalog/vercel-catalog.d.ts +42 -0
- package/dist/skills/catalog/vercel-catalog.d.ts.map +1 -0
- package/dist/skills/catalog/vercel-catalog.js +189 -0
- package/dist/skills/compat/index.d.ts +9 -0
- package/dist/skills/compat/index.d.ts.map +1 -0
- package/dist/skills/compat/index.js +8 -0
- package/dist/skills/compat/skill-enhancer.d.ts +37 -0
- package/dist/skills/compat/skill-enhancer.d.ts.map +1 -0
- package/dist/skills/compat/skill-enhancer.js +76 -0
- package/dist/skills/compat/tool-mapper.d.ts +61 -0
- package/dist/skills/compat/tool-mapper.d.ts.map +1 -0
- package/dist/skills/compat/tool-mapper.js +168 -0
- package/dist/skills/compat/vercel-compat.d.ts +33 -0
- package/dist/skills/compat/vercel-compat.d.ts.map +1 -0
- package/dist/skills/compat/vercel-compat.js +132 -0
- package/dist/skills/index.d.ts +40 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +47 -0
- package/dist/skills/integration/agent-skill-provider.d.ts +94 -0
- package/dist/skills/integration/agent-skill-provider.d.ts.map +1 -0
- package/dist/skills/integration/agent-skill-provider.js +161 -0
- package/dist/skills/integration/index.d.ts +7 -0
- package/dist/skills/integration/index.d.ts.map +1 -0
- package/dist/skills/integration/index.js +6 -0
- package/dist/skills/loader/github-loader.d.ts +61 -0
- package/dist/skills/loader/github-loader.d.ts.map +1 -0
- package/dist/skills/loader/github-loader.js +176 -0
- package/dist/skills/loader/index.d.ts +10 -0
- package/dist/skills/loader/index.d.ts.map +1 -0
- package/dist/skills/loader/index.js +9 -0
- package/dist/skills/loader/local-loader.d.ts +56 -0
- package/dist/skills/loader/local-loader.d.ts.map +1 -0
- package/dist/skills/loader/local-loader.js +186 -0
- package/dist/skills/loader/vercel-loader.d.ts +64 -0
- package/dist/skills/loader/vercel-loader.d.ts.map +1 -0
- package/dist/skills/loader/vercel-loader.js +313 -0
- package/dist/skills/loader/vercel-types.d.ts +64 -0
- package/dist/skills/loader/vercel-types.d.ts.map +1 -0
- package/dist/skills/loader/vercel-types.js +55 -0
- package/dist/skills/parser/index.d.ts +7 -0
- package/dist/skills/parser/index.d.ts.map +1 -0
- package/dist/skills/parser/index.js +6 -0
- package/dist/skills/parser/skill-md-parser.d.ts +64 -0
- package/dist/skills/parser/skill-md-parser.d.ts.map +1 -0
- package/dist/skills/parser/skill-md-parser.js +242 -0
- package/dist/skills/registry/index.d.ts +7 -0
- package/dist/skills/registry/index.d.ts.map +1 -0
- package/dist/skills/registry/index.js +6 -0
- package/dist/skills/registry/skill-registry.d.ts +133 -0
- package/dist/skills/registry/skill-registry.d.ts.map +1 -0
- package/dist/skills/registry/skill-registry.js +373 -0
- package/dist/skills/types.d.ts +216 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +176 -0
- package/dist/templates/agent-spec.d.ts +138 -0
- package/dist/templates/agent-spec.d.ts.map +1 -0
- package/dist/templates/agent-spec.js +138 -0
- package/dist/templates/index.d.ts +56 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +58 -0
- package/dist/templates/prompt-spec.d.ts +140 -0
- package/dist/templates/prompt-spec.d.ts.map +1 -0
- package/dist/templates/prompt-spec.js +210 -0
- package/dist/templates/skill-spec.d.ts +106 -0
- package/dist/templates/skill-spec.d.ts.map +1 -0
- package/dist/templates/skill-spec.js +119 -0
- package/dist/tools/base.d.ts +74 -0
- package/dist/tools/base.d.ts.map +1 -0
- package/dist/tools/base.js +6 -0
- package/dist/tools/cms/collection-tools.d.ts +36 -0
- package/dist/tools/cms/collection-tools.d.ts.map +1 -0
- package/dist/tools/cms/collection-tools.js +178 -0
- package/dist/tools/cms/factory.d.ts +89 -0
- package/dist/tools/cms/factory.d.ts.map +1 -0
- package/dist/tools/cms/factory.js +462 -0
- package/dist/tools/cms/global-tools.d.ts +21 -0
- package/dist/tools/cms/global-tools.d.ts.map +1 -0
- package/dist/tools/cms/global-tools.js +92 -0
- package/dist/tools/cms/index.d.ts +11 -0
- package/dist/tools/cms/index.d.ts.map +1 -0
- package/dist/tools/cms/index.js +11 -0
- package/dist/tools/cms/media-tools.d.ts +31 -0
- package/dist/tools/cms/media-tools.d.ts.map +1 -0
- package/dist/tools/cms/media-tools.js +140 -0
- package/dist/tools/cms/user-tools.d.ts +31 -0
- package/dist/tools/cms/user-tools.d.ts.map +1 -0
- package/dist/tools/cms/user-tools.js +135 -0
- package/dist/tools/deduplicator.d.ts +19 -0
- package/dist/tools/deduplicator.d.ts.map +1 -0
- package/dist/tools/deduplicator.js +53 -0
- package/dist/tools/document-summarizer.d.ts +11 -0
- package/dist/tools/document-summarizer.d.ts.map +1 -0
- package/dist/tools/document-summarizer.js +82 -0
- package/dist/tools/mcp-adapter.d.ts +66 -0
- package/dist/tools/mcp-adapter.d.ts.map +1 -0
- package/dist/tools/mcp-adapter.js +152 -0
- package/dist/tools/memory/index.d.ts +3 -0
- package/dist/tools/memory/index.d.ts.map +1 -0
- package/dist/tools/memory/index.js +1 -0
- package/dist/tools/memory/store-memory.d.ts +39 -0
- package/dist/tools/memory/store-memory.d.ts.map +1 -0
- package/dist/tools/memory/store-memory.js +94 -0
- package/dist/tools/registry.d.ts +14 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +48 -0
- package/dist/tools/ticket-tools.d.ts +31 -0
- package/dist/tools/ticket-tools.d.ts.map +1 -0
- package/dist/tools/ticket-tools.js +74 -0
- package/dist/tools/web/duck-duck-go.d.ts +52 -0
- package/dist/tools/web/duck-duck-go.d.ts.map +1 -0
- package/dist/tools/web/duck-duck-go.js +202 -0
- package/dist/tools/web/exa.d.ts +34 -0
- package/dist/tools/web/exa.d.ts.map +1 -0
- package/dist/tools/web/exa.js +80 -0
- package/dist/tools/web/index.d.ts +6 -0
- package/dist/tools/web/index.d.ts.map +1 -0
- package/dist/tools/web/index.js +4 -0
- package/dist/tools/web/scraper.d.ts +9 -0
- package/dist/tools/web/scraper.d.ts.map +1 -0
- package/dist/tools/web/scraper.js +118 -0
- package/dist/tools/web/tavily.d.ts +32 -0
- package/dist/tools/web/tavily.d.ts.map +1 -0
- package/dist/tools/web/tavily.js +73 -0
- package/dist/tools/web/types.d.ts +31 -0
- package/dist/tools/web/types.d.ts.map +1 -0
- package/dist/tools/web/types.js +9 -0
- package/package.json +143 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Observer
|
|
3
|
+
*
|
|
4
|
+
* The central human-facing audit system. This is the ONLY component
|
|
5
|
+
* that has full read/write access to the audit trail. Agents never
|
|
6
|
+
* receive a reference to this object.
|
|
7
|
+
*
|
|
8
|
+
* Responsibilities:
|
|
9
|
+
* - Receives events from agent emitters
|
|
10
|
+
* - Stores entries in the append-only store
|
|
11
|
+
* - Evaluates policies and generates alerts
|
|
12
|
+
* - Tracks agent halt status
|
|
13
|
+
* - Provides query interface for human review
|
|
14
|
+
*/
|
|
15
|
+
import { randomUUID } from 'node:crypto';
|
|
16
|
+
import { createAuditEmitter } from './emitter.js';
|
|
17
|
+
import { AuditPolicyEngine } from './policy.js';
|
|
18
|
+
// ─── Audit Observer ─────────────────────────────────────────────────────────
|
|
19
|
+
export class AuditObserver {
|
|
20
|
+
store;
|
|
21
|
+
policyEngine;
|
|
22
|
+
recentHistory = [];
|
|
23
|
+
recentHistorySize;
|
|
24
|
+
agentStatus = new Map();
|
|
25
|
+
fleetHalted = false;
|
|
26
|
+
onAlert;
|
|
27
|
+
onAgentHalted;
|
|
28
|
+
onFleetHalted;
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.store = config.store;
|
|
31
|
+
this.policyEngine = new AuditPolicyEngine();
|
|
32
|
+
this.recentHistorySize = config.recentHistorySize ?? 1000;
|
|
33
|
+
this.onAlert = config.onAlert;
|
|
34
|
+
this.onAgentHalted = config.onAgentHalted;
|
|
35
|
+
this.onFleetHalted = config.onFleetHalted;
|
|
36
|
+
}
|
|
37
|
+
// ── Emitter Factory (for agents) ────────────────────────────────────────
|
|
38
|
+
/**
|
|
39
|
+
* Create a write-only AuditEmitter for an agent.
|
|
40
|
+
* This is the only audit API agents should ever receive.
|
|
41
|
+
*/
|
|
42
|
+
createEmitterForAgent(agentId) {
|
|
43
|
+
// Initialize agent status tracking
|
|
44
|
+
if (!this.agentStatus.has(agentId)) {
|
|
45
|
+
this.agentStatus.set(agentId, {
|
|
46
|
+
agentId,
|
|
47
|
+
halted: false,
|
|
48
|
+
totalEvents: 0,
|
|
49
|
+
totalViolations: 0,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
const handler = (emitterAgentId, eventType, payload, severity) => {
|
|
53
|
+
// Drop events from halted agents (they shouldn't be running)
|
|
54
|
+
const status = this.agentStatus.get(emitterAgentId);
|
|
55
|
+
if (status?.halted || this.fleetHalted)
|
|
56
|
+
return;
|
|
57
|
+
void this.handleEvent(emitterAgentId, eventType, payload, severity);
|
|
58
|
+
};
|
|
59
|
+
return createAuditEmitter(agentId, handler);
|
|
60
|
+
}
|
|
61
|
+
// ── Internal Event Handling ─────────────────────────────────────────────
|
|
62
|
+
async handleEvent(agentId, eventType, payload, severity) {
|
|
63
|
+
const entry = {
|
|
64
|
+
id: randomUUID(),
|
|
65
|
+
timestamp: new Date(),
|
|
66
|
+
eventType,
|
|
67
|
+
severity,
|
|
68
|
+
agentId,
|
|
69
|
+
taskId: typeof payload.taskId === 'string' ? payload.taskId : undefined,
|
|
70
|
+
sessionId: typeof payload.sessionId === 'string' ? payload.sessionId : undefined,
|
|
71
|
+
payload,
|
|
72
|
+
policyViolations: [],
|
|
73
|
+
};
|
|
74
|
+
// Evaluate policies
|
|
75
|
+
const { violations, alerts, shouldHaltAgent, shouldHaltAll } = this.policyEngine.evaluate(entry, this.recentHistory);
|
|
76
|
+
entry.policyViolations = violations;
|
|
77
|
+
// Update severity if policy violations are more severe
|
|
78
|
+
if (violations.length > 0) {
|
|
79
|
+
const maxSeverity = alerts.reduce((max, a) => {
|
|
80
|
+
const rank = { info: 0, warn: 1, critical: 2 };
|
|
81
|
+
return rank[a.severity] > rank[max] ? a.severity : max;
|
|
82
|
+
}, entry.severity);
|
|
83
|
+
entry.severity = maxSeverity;
|
|
84
|
+
}
|
|
85
|
+
// Persist entry
|
|
86
|
+
await this.store.append(entry);
|
|
87
|
+
// Update recent history
|
|
88
|
+
this.recentHistory.push(entry);
|
|
89
|
+
if (this.recentHistory.length > this.recentHistorySize) {
|
|
90
|
+
this.recentHistory = this.recentHistory.slice(-this.recentHistorySize);
|
|
91
|
+
}
|
|
92
|
+
// Update agent status
|
|
93
|
+
const status = this.agentStatus.get(agentId);
|
|
94
|
+
if (status) {
|
|
95
|
+
status.totalEvents++;
|
|
96
|
+
status.lastEventAt = entry.timestamp;
|
|
97
|
+
if (violations.length > 0) {
|
|
98
|
+
status.totalViolations += violations.length;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Fire alert callbacks
|
|
102
|
+
for (const alert of alerts) {
|
|
103
|
+
this.onAlert?.(alert);
|
|
104
|
+
}
|
|
105
|
+
// Execute halt actions
|
|
106
|
+
if (shouldHaltAll) {
|
|
107
|
+
this.haltFleet('system', `Policy violation by agent ${agentId}`);
|
|
108
|
+
}
|
|
109
|
+
else if (shouldHaltAgent) {
|
|
110
|
+
this.haltAgent(agentId, 'system', `Policy violation: ${violations.join(', ')}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// ── Human Control Interface ─────────────────────────────────────────────
|
|
114
|
+
/**
|
|
115
|
+
* Halt a specific agent. Only humans should call this.
|
|
116
|
+
*/
|
|
117
|
+
haltAgent(agentId, haltedBy, reason) {
|
|
118
|
+
const status = this.agentStatus.get(agentId) ?? {
|
|
119
|
+
agentId,
|
|
120
|
+
halted: false,
|
|
121
|
+
totalEvents: 0,
|
|
122
|
+
totalViolations: 0,
|
|
123
|
+
};
|
|
124
|
+
status.halted = true;
|
|
125
|
+
status.haltedBy = haltedBy;
|
|
126
|
+
status.haltedAt = new Date();
|
|
127
|
+
status.haltReason = reason;
|
|
128
|
+
this.agentStatus.set(agentId, status);
|
|
129
|
+
// Log the human action
|
|
130
|
+
void this.handleEvent('system', 'human:agent:halted', {
|
|
131
|
+
targetAgentId: agentId,
|
|
132
|
+
haltedBy,
|
|
133
|
+
reason,
|
|
134
|
+
}, 'critical');
|
|
135
|
+
this.onAgentHalted?.(agentId, reason);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Resume a halted agent. Only humans should call this.
|
|
139
|
+
*/
|
|
140
|
+
resumeAgent(agentId, resumedBy) {
|
|
141
|
+
const status = this.agentStatus.get(agentId);
|
|
142
|
+
if (!status)
|
|
143
|
+
return;
|
|
144
|
+
status.halted = false;
|
|
145
|
+
status.haltedBy = undefined;
|
|
146
|
+
status.haltedAt = undefined;
|
|
147
|
+
status.haltReason = undefined;
|
|
148
|
+
void this.handleEvent('system', 'human:agent:resumed', {
|
|
149
|
+
targetAgentId: agentId,
|
|
150
|
+
resumedBy,
|
|
151
|
+
}, 'info');
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Halt the entire agent fleet. Emergency stop.
|
|
155
|
+
*/
|
|
156
|
+
haltFleet(haltedBy, reason) {
|
|
157
|
+
this.fleetHalted = true;
|
|
158
|
+
for (const status of this.agentStatus.values()) {
|
|
159
|
+
status.halted = true;
|
|
160
|
+
status.haltedBy = haltedBy;
|
|
161
|
+
status.haltedAt = new Date();
|
|
162
|
+
status.haltReason = reason;
|
|
163
|
+
}
|
|
164
|
+
void this.handleEvent('system', 'human:fleet:halted', {
|
|
165
|
+
haltedBy,
|
|
166
|
+
reason,
|
|
167
|
+
}, 'critical');
|
|
168
|
+
this.onFleetHalted?.(reason);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Resume the entire fleet. Only humans should call this.
|
|
172
|
+
*/
|
|
173
|
+
resumeFleet(resumedBy) {
|
|
174
|
+
this.fleetHalted = false;
|
|
175
|
+
for (const status of this.agentStatus.values()) {
|
|
176
|
+
status.halted = false;
|
|
177
|
+
status.haltedBy = undefined;
|
|
178
|
+
status.haltedAt = undefined;
|
|
179
|
+
status.haltReason = undefined;
|
|
180
|
+
}
|
|
181
|
+
void this.handleEvent('system', 'human:fleet:resumed', {
|
|
182
|
+
resumedBy,
|
|
183
|
+
}, 'info');
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Check if an agent is halted
|
|
187
|
+
*/
|
|
188
|
+
isAgentHalted(agentId) {
|
|
189
|
+
if (this.fleetHalted)
|
|
190
|
+
return true;
|
|
191
|
+
return this.agentStatus.get(agentId)?.halted ?? false;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Check if the entire fleet is halted
|
|
195
|
+
*/
|
|
196
|
+
isFleetHalted() {
|
|
197
|
+
return this.fleetHalted;
|
|
198
|
+
}
|
|
199
|
+
// ── Policy Management ───────────────────────────────────────────────────
|
|
200
|
+
/**
|
|
201
|
+
* Add a human-defined policy
|
|
202
|
+
*/
|
|
203
|
+
addPolicy(policy) {
|
|
204
|
+
this.policyEngine.addPolicy(policy);
|
|
205
|
+
void this.handleEvent('system', 'human:policy:added', {
|
|
206
|
+
policyId: policy.id,
|
|
207
|
+
policyName: policy.name,
|
|
208
|
+
createdBy: policy.createdBy,
|
|
209
|
+
}, 'info');
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Remove a policy
|
|
213
|
+
*/
|
|
214
|
+
removePolicy(policyId, removedBy) {
|
|
215
|
+
this.policyEngine.removePolicy(policyId);
|
|
216
|
+
void this.handleEvent('system', 'human:policy:removed', {
|
|
217
|
+
policyId,
|
|
218
|
+
removedBy,
|
|
219
|
+
}, 'info');
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Get all active policies
|
|
223
|
+
*/
|
|
224
|
+
getPolicies() {
|
|
225
|
+
return this.policyEngine.getPolicies();
|
|
226
|
+
}
|
|
227
|
+
// ── Query Interface ─────────────────────────────────────────────────────
|
|
228
|
+
/**
|
|
229
|
+
* Query audit entries
|
|
230
|
+
*/
|
|
231
|
+
async query(filter) {
|
|
232
|
+
return this.store.query(filter);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get all alerts
|
|
236
|
+
*/
|
|
237
|
+
getAlerts(unacknowledgedOnly = false) {
|
|
238
|
+
return this.policyEngine.getAlerts(unacknowledgedOnly);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Acknowledge an alert
|
|
242
|
+
*/
|
|
243
|
+
acknowledgeAlert(alertId, acknowledgedBy) {
|
|
244
|
+
const result = this.policyEngine.acknowledgeAlert(alertId, acknowledgedBy);
|
|
245
|
+
if (result) {
|
|
246
|
+
void this.handleEvent('system', 'human:alert:acknowledged', {
|
|
247
|
+
alertId,
|
|
248
|
+
acknowledgedBy,
|
|
249
|
+
}, 'info');
|
|
250
|
+
}
|
|
251
|
+
return result;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Get status of all tracked agents
|
|
255
|
+
*/
|
|
256
|
+
getAgentStatuses() {
|
|
257
|
+
return Array.from(this.agentStatus.values());
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Get status of a specific agent
|
|
261
|
+
*/
|
|
262
|
+
getAgentStatus(agentId) {
|
|
263
|
+
return this.agentStatus.get(agentId);
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Get total entry count
|
|
267
|
+
*/
|
|
268
|
+
async getTotalEntries() {
|
|
269
|
+
return this.store.count();
|
|
270
|
+
}
|
|
271
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Policy Engine
|
|
3
|
+
*
|
|
4
|
+
* Human-defined rules that evaluate audit entries and trigger alerts.
|
|
5
|
+
* Policies are configured by humans, not agents. They define what
|
|
6
|
+
* constitutes suspicious or dangerous behavior and what action to take.
|
|
7
|
+
*/
|
|
8
|
+
import type { AuditAlert, AuditEntry, AuditPolicy } from './types.js';
|
|
9
|
+
export declare class AuditPolicyEngine {
|
|
10
|
+
private policies;
|
|
11
|
+
private alerts;
|
|
12
|
+
private alertCounter;
|
|
13
|
+
/**
|
|
14
|
+
* Add a human-defined policy
|
|
15
|
+
*/
|
|
16
|
+
addPolicy(policy: AuditPolicy): void;
|
|
17
|
+
/**
|
|
18
|
+
* Remove a policy by ID
|
|
19
|
+
*/
|
|
20
|
+
removePolicy(policyId: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Get all active policies
|
|
23
|
+
*/
|
|
24
|
+
getPolicies(): AuditPolicy[];
|
|
25
|
+
/**
|
|
26
|
+
* Evaluate an entry against all active policies.
|
|
27
|
+
* Returns the IDs of violated policies and any alerts generated.
|
|
28
|
+
*/
|
|
29
|
+
evaluate(entry: AuditEntry, recentHistory: AuditEntry[]): {
|
|
30
|
+
violations: string[];
|
|
31
|
+
alerts: AuditAlert[];
|
|
32
|
+
shouldHaltAgent: boolean;
|
|
33
|
+
shouldHaltAll: boolean;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Get all alerts (newest first)
|
|
37
|
+
*/
|
|
38
|
+
getAlerts(unacknowledgedOnly?: boolean): AuditAlert[];
|
|
39
|
+
/**
|
|
40
|
+
* Acknowledge an alert (human action)
|
|
41
|
+
*/
|
|
42
|
+
acknowledgeAlert(alertId: string, acknowledgedBy: string): boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Pre-built policies for common safety patterns.
|
|
46
|
+
* Humans can use these as-is or as templates for custom policies.
|
|
47
|
+
*/
|
|
48
|
+
export declare const builtinPolicies: {
|
|
49
|
+
/**
|
|
50
|
+
* Alert when an agent exceeds a tool call rate limit
|
|
51
|
+
*/
|
|
52
|
+
readonly toolCallRateLimit: (maxCallsPerMinute: number, createdBy: string) => AuditPolicy;
|
|
53
|
+
/**
|
|
54
|
+
* Halt agent that attempts to modify its own instructions
|
|
55
|
+
*/
|
|
56
|
+
readonly selfModificationBlock: (createdBy: string) => AuditPolicy;
|
|
57
|
+
/**
|
|
58
|
+
* Alert on consecutive task failures
|
|
59
|
+
*/
|
|
60
|
+
readonly consecutiveFailures: (maxConsecutive: number, createdBy: string) => AuditPolicy;
|
|
61
|
+
/**
|
|
62
|
+
* Emergency halt if any agent accesses denied tools
|
|
63
|
+
*/
|
|
64
|
+
readonly deniedToolAccess: (createdBy: string) => AuditPolicy;
|
|
65
|
+
/**
|
|
66
|
+
* Fleet-wide emergency stop on excessive memory writes
|
|
67
|
+
*/
|
|
68
|
+
readonly fleetMemoryFlood: (maxWritesPerMinute: number, createdBy: string) => AuditPolicy;
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/audit/policy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAIrE,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAsC;IACtD,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,YAAY,CAAI;IAExB;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAIpC;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIpC;;OAEG;IACH,WAAW,IAAI,WAAW,EAAE;IAI5B;;;OAGG;IACH,QAAQ,CACN,KAAK,EAAE,UAAU,EACjB,aAAa,EAAE,UAAU,EAAE,GAC1B;QACD,UAAU,EAAE,MAAM,EAAE,CAAA;QACpB,MAAM,EAAE,UAAU,EAAE,CAAA;QACpB,eAAe,EAAE,OAAO,CAAA;QACxB,aAAa,EAAE,OAAO,CAAA;KACvB;IAuCD;;OAEG;IACH,SAAS,CAAC,kBAAkB,UAAQ,GAAG,UAAU,EAAE;IAMnD;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO;CASnE;AAID;;;GAGG;AACH,eAAO,MAAM,eAAe;IAC1B;;OAEG;oDACkC,MAAM,aAAa,MAAM,KAAG,WAAW;IAwB5E;;OAEG;gDAC8B,MAAM,KAAG,WAAW;IAwBrD;;OAEG;mDACiC,MAAM,aAAa,MAAM,KAAG,WAAW;IA2B3E;;OAEG;2CACyB,MAAM,KAAG,WAAW;IAgBhD;;OAEG;oDACkC,MAAM,aAAa,MAAM,KAAG,WAAW;CAmBpE,CAAA"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Policy Engine
|
|
3
|
+
*
|
|
4
|
+
* Human-defined rules that evaluate audit entries and trigger alerts.
|
|
5
|
+
* Policies are configured by humans, not agents. They define what
|
|
6
|
+
* constitutes suspicious or dangerous behavior and what action to take.
|
|
7
|
+
*/
|
|
8
|
+
// ─── Policy Engine ──────────────────────────────────────────────────────────
|
|
9
|
+
export class AuditPolicyEngine {
|
|
10
|
+
policies = new Map();
|
|
11
|
+
alerts = [];
|
|
12
|
+
alertCounter = 0;
|
|
13
|
+
/**
|
|
14
|
+
* Add a human-defined policy
|
|
15
|
+
*/
|
|
16
|
+
addPolicy(policy) {
|
|
17
|
+
this.policies.set(policy.id, policy);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Remove a policy by ID
|
|
21
|
+
*/
|
|
22
|
+
removePolicy(policyId) {
|
|
23
|
+
this.policies.delete(policyId);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get all active policies
|
|
27
|
+
*/
|
|
28
|
+
getPolicies() {
|
|
29
|
+
return Array.from(this.policies.values());
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Evaluate an entry against all active policies.
|
|
33
|
+
* Returns the IDs of violated policies and any alerts generated.
|
|
34
|
+
*/
|
|
35
|
+
evaluate(entry, recentHistory) {
|
|
36
|
+
const violations = [];
|
|
37
|
+
const newAlerts = [];
|
|
38
|
+
let shouldHaltAgent = false;
|
|
39
|
+
let shouldHaltAll = false;
|
|
40
|
+
for (const policy of this.policies.values()) {
|
|
41
|
+
if (!policy.enabled)
|
|
42
|
+
continue;
|
|
43
|
+
try {
|
|
44
|
+
if (policy.condition(entry, recentHistory)) {
|
|
45
|
+
violations.push(policy.id);
|
|
46
|
+
const alert = {
|
|
47
|
+
id: `alert-${++this.alertCounter}`,
|
|
48
|
+
policyId: policy.id,
|
|
49
|
+
policyName: policy.name,
|
|
50
|
+
triggeringEntryId: entry.id,
|
|
51
|
+
agentId: entry.agentId,
|
|
52
|
+
severity: policy.severity,
|
|
53
|
+
action: policy.action,
|
|
54
|
+
createdAt: new Date(),
|
|
55
|
+
acknowledged: false,
|
|
56
|
+
};
|
|
57
|
+
newAlerts.push(alert);
|
|
58
|
+
this.alerts.push(alert);
|
|
59
|
+
if (policy.action === 'halt_agent')
|
|
60
|
+
shouldHaltAgent = true;
|
|
61
|
+
if (policy.action === 'halt_all')
|
|
62
|
+
shouldHaltAll = true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Policy evaluation errors should never crash the system
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return { violations, alerts: newAlerts, shouldHaltAgent, shouldHaltAll };
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get all alerts (newest first)
|
|
73
|
+
*/
|
|
74
|
+
getAlerts(unacknowledgedOnly = false) {
|
|
75
|
+
const result = unacknowledgedOnly ? this.alerts.filter((a) => !a.acknowledged) : this.alerts;
|
|
76
|
+
return [...result].reverse();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Acknowledge an alert (human action)
|
|
80
|
+
*/
|
|
81
|
+
acknowledgeAlert(alertId, acknowledgedBy) {
|
|
82
|
+
const alert = this.alerts.find((a) => a.id === alertId);
|
|
83
|
+
if (!alert)
|
|
84
|
+
return false;
|
|
85
|
+
alert.acknowledged = true;
|
|
86
|
+
alert.acknowledgedBy = acknowledgedBy;
|
|
87
|
+
alert.acknowledgedAt = new Date();
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// ─── Built-in Policies ──────────────────────────────────────────────────────
|
|
92
|
+
/**
|
|
93
|
+
* Pre-built policies for common safety patterns.
|
|
94
|
+
* Humans can use these as-is or as templates for custom policies.
|
|
95
|
+
*/
|
|
96
|
+
export const builtinPolicies = {
|
|
97
|
+
/**
|
|
98
|
+
* Alert when an agent exceeds a tool call rate limit
|
|
99
|
+
*/
|
|
100
|
+
toolCallRateLimit(maxCallsPerMinute, createdBy) {
|
|
101
|
+
return {
|
|
102
|
+
id: 'builtin:tool-call-rate-limit',
|
|
103
|
+
name: 'Tool Call Rate Limit',
|
|
104
|
+
description: `Alert when an agent exceeds ${maxCallsPerMinute} tool calls per minute`,
|
|
105
|
+
severity: 'warn',
|
|
106
|
+
action: 'alert',
|
|
107
|
+
enabled: true,
|
|
108
|
+
createdBy,
|
|
109
|
+
createdAt: new Date(),
|
|
110
|
+
condition: (entry, history) => {
|
|
111
|
+
if (entry.eventType !== 'agent:tool:called')
|
|
112
|
+
return false;
|
|
113
|
+
const oneMinuteAgo = new Date(Date.now() - 60_000);
|
|
114
|
+
const recentCalls = history.filter((e) => e.agentId === entry.agentId &&
|
|
115
|
+
e.eventType === 'agent:tool:called' &&
|
|
116
|
+
e.timestamp >= oneMinuteAgo);
|
|
117
|
+
return recentCalls.length >= maxCallsPerMinute;
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
},
|
|
121
|
+
/**
|
|
122
|
+
* Halt agent that attempts to modify its own instructions
|
|
123
|
+
*/
|
|
124
|
+
selfModificationBlock(createdBy) {
|
|
125
|
+
return {
|
|
126
|
+
id: 'builtin:self-modification-block',
|
|
127
|
+
name: 'Self-Modification Block',
|
|
128
|
+
description: 'Halt any agent that attempts to modify its own instructions or specification',
|
|
129
|
+
severity: 'critical',
|
|
130
|
+
action: 'halt_agent',
|
|
131
|
+
enabled: true,
|
|
132
|
+
createdBy,
|
|
133
|
+
createdAt: new Date(),
|
|
134
|
+
condition: (entry) => {
|
|
135
|
+
if (entry.eventType !== 'agent:tool:called')
|
|
136
|
+
return false;
|
|
137
|
+
const toolName = String(entry.payload.toolName ?? '');
|
|
138
|
+
const args = String(entry.payload.arguments ?? '');
|
|
139
|
+
return (toolName.includes('modify_spec') ||
|
|
140
|
+
toolName.includes('update_instructions') ||
|
|
141
|
+
args.includes('self_modify') ||
|
|
142
|
+
args.includes('update_own_prompt'));
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
},
|
|
146
|
+
/**
|
|
147
|
+
* Alert on consecutive task failures
|
|
148
|
+
*/
|
|
149
|
+
consecutiveFailures(maxConsecutive, createdBy) {
|
|
150
|
+
return {
|
|
151
|
+
id: 'builtin:consecutive-failures',
|
|
152
|
+
name: 'Consecutive Failure Limit',
|
|
153
|
+
description: `Alert when an agent fails ${maxConsecutive} consecutive tasks`,
|
|
154
|
+
severity: 'warn',
|
|
155
|
+
action: 'alert',
|
|
156
|
+
enabled: true,
|
|
157
|
+
createdBy,
|
|
158
|
+
createdAt: new Date(),
|
|
159
|
+
condition: (entry, history) => {
|
|
160
|
+
if (entry.eventType !== 'agent:task:failed')
|
|
161
|
+
return false;
|
|
162
|
+
const agentHistory = history
|
|
163
|
+
.filter((e) => e.agentId === entry.agentId &&
|
|
164
|
+
(e.eventType === 'agent:task:completed' || e.eventType === 'agent:task:failed'))
|
|
165
|
+
.slice(-maxConsecutive);
|
|
166
|
+
return (agentHistory.length >= maxConsecutive &&
|
|
167
|
+
agentHistory.every((e) => e.eventType === 'agent:task:failed'));
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
/**
|
|
172
|
+
* Emergency halt if any agent accesses denied tools
|
|
173
|
+
*/
|
|
174
|
+
deniedToolAccess(createdBy) {
|
|
175
|
+
return {
|
|
176
|
+
id: 'builtin:denied-tool-access',
|
|
177
|
+
name: 'Denied Tool Access',
|
|
178
|
+
description: 'Halt agent that attempts to use a denied tool',
|
|
179
|
+
severity: 'critical',
|
|
180
|
+
action: 'halt_agent',
|
|
181
|
+
enabled: true,
|
|
182
|
+
createdBy,
|
|
183
|
+
createdAt: new Date(),
|
|
184
|
+
condition: (entry) => {
|
|
185
|
+
return entry.eventType === 'agent:tool:denied';
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
},
|
|
189
|
+
/**
|
|
190
|
+
* Fleet-wide emergency stop on excessive memory writes
|
|
191
|
+
*/
|
|
192
|
+
fleetMemoryFlood(maxWritesPerMinute, createdBy) {
|
|
193
|
+
return {
|
|
194
|
+
id: 'builtin:fleet-memory-flood',
|
|
195
|
+
name: 'Fleet Memory Flood Protection',
|
|
196
|
+
description: `Halt all agents if total memory writes exceed ${maxWritesPerMinute}/min across fleet`,
|
|
197
|
+
severity: 'critical',
|
|
198
|
+
action: 'halt_all',
|
|
199
|
+
enabled: true,
|
|
200
|
+
createdBy,
|
|
201
|
+
createdAt: new Date(),
|
|
202
|
+
condition: (_entry, history) => {
|
|
203
|
+
const oneMinuteAgo = new Date(Date.now() - 60_000);
|
|
204
|
+
const recentWrites = history.filter((e) => e.eventType === 'agent:memory:write' && e.timestamp >= oneMinuteAgo);
|
|
205
|
+
return recentWrites.length >= maxWritesPerMinute;
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
},
|
|
209
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Store
|
|
3
|
+
*
|
|
4
|
+
* Append-only storage interface for audit entries.
|
|
5
|
+
* No update or delete operations — the log is immutable.
|
|
6
|
+
* Includes an in-memory implementation and a pluggable interface
|
|
7
|
+
* for persistent backends (PostgreSQL, etc.).
|
|
8
|
+
*/
|
|
9
|
+
import type { AuditEntry, AuditFilter } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Append-only audit store.
|
|
12
|
+
* Implementations MUST NOT provide update or delete methods.
|
|
13
|
+
*/
|
|
14
|
+
export interface AuditStore {
|
|
15
|
+
/** Append a single entry to the log */
|
|
16
|
+
append(entry: AuditEntry): Promise<void>;
|
|
17
|
+
/** Append multiple entries atomically */
|
|
18
|
+
appendBatch(entries: AuditEntry[]): Promise<void>;
|
|
19
|
+
/** Query entries with filters (human-side only) */
|
|
20
|
+
query(filter: AuditFilter): Promise<AuditEntry[]>;
|
|
21
|
+
/** Get total entry count (optionally filtered by agent) */
|
|
22
|
+
count(agentId?: string): Promise<number>;
|
|
23
|
+
/** Get entries since a given timestamp */
|
|
24
|
+
since(timestamp: Date, limit?: number): Promise<AuditEntry[]>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* In-memory audit store for development and testing.
|
|
28
|
+
* Entries are stored in a simple array — not suitable for production.
|
|
29
|
+
*/
|
|
30
|
+
export declare class InMemoryAuditStore implements AuditStore {
|
|
31
|
+
private entries;
|
|
32
|
+
private readonly maxEntries;
|
|
33
|
+
constructor(maxEntries?: number);
|
|
34
|
+
append(entry: AuditEntry): Promise<void>;
|
|
35
|
+
appendBatch(entries: AuditEntry[]): Promise<void>;
|
|
36
|
+
query(filter: AuditFilter): Promise<AuditEntry[]>;
|
|
37
|
+
count(agentId?: string): Promise<number>;
|
|
38
|
+
since(timestamp: Date, limit?: number): Promise<AuditEntry[]>;
|
|
39
|
+
/** Evict oldest entries when over the limit */
|
|
40
|
+
private enforceLimit;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/audit/store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAIzD;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,uCAAuC;IACvC,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAExC,yCAAyC;IACzC,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEjD,mDAAmD;IACnD,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;IAEjD,2DAA2D;IAC3D,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAExC,0CAA0C;IAC1C,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;CAC9D;AAID;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,UAAU;IACnD,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;gBAEvB,UAAU,SAAU;IAI1B,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxC,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjD,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IA0CjD,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOxC,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,SAAO,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAIjE,+CAA+C;IAC/C,OAAO,CAAC,YAAY;CAKrB"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Store
|
|
3
|
+
*
|
|
4
|
+
* Append-only storage interface for audit entries.
|
|
5
|
+
* No update or delete operations — the log is immutable.
|
|
6
|
+
* Includes an in-memory implementation and a pluggable interface
|
|
7
|
+
* for persistent backends (PostgreSQL, etc.).
|
|
8
|
+
*/
|
|
9
|
+
// ─── In-Memory Implementation ───────────────────────────────────────────────
|
|
10
|
+
/**
|
|
11
|
+
* In-memory audit store for development and testing.
|
|
12
|
+
* Entries are stored in a simple array — not suitable for production.
|
|
13
|
+
*/
|
|
14
|
+
export class InMemoryAuditStore {
|
|
15
|
+
entries = [];
|
|
16
|
+
maxEntries;
|
|
17
|
+
constructor(maxEntries = 100_000) {
|
|
18
|
+
this.maxEntries = maxEntries;
|
|
19
|
+
}
|
|
20
|
+
async append(entry) {
|
|
21
|
+
this.entries.push(entry);
|
|
22
|
+
this.enforceLimit();
|
|
23
|
+
}
|
|
24
|
+
async appendBatch(entries) {
|
|
25
|
+
this.entries.push(...entries);
|
|
26
|
+
this.enforceLimit();
|
|
27
|
+
}
|
|
28
|
+
async query(filter) {
|
|
29
|
+
let results = this.entries;
|
|
30
|
+
if (filter.agentId) {
|
|
31
|
+
results = results.filter((e) => e.agentId === filter.agentId);
|
|
32
|
+
}
|
|
33
|
+
if (filter.taskId) {
|
|
34
|
+
results = results.filter((e) => e.taskId === filter.taskId);
|
|
35
|
+
}
|
|
36
|
+
if (filter.sessionId) {
|
|
37
|
+
results = results.filter((e) => e.sessionId === filter.sessionId);
|
|
38
|
+
}
|
|
39
|
+
if (filter.eventTypes && filter.eventTypes.length > 0) {
|
|
40
|
+
const types = new Set(filter.eventTypes);
|
|
41
|
+
results = results.filter((e) => types.has(e.eventType));
|
|
42
|
+
}
|
|
43
|
+
if (filter.severity && filter.severity.length > 0) {
|
|
44
|
+
const sevs = new Set(filter.severity);
|
|
45
|
+
results = results.filter((e) => sevs.has(e.severity));
|
|
46
|
+
}
|
|
47
|
+
if (filter.startTime) {
|
|
48
|
+
const startTime = filter.startTime;
|
|
49
|
+
results = results.filter((e) => e.timestamp >= startTime);
|
|
50
|
+
}
|
|
51
|
+
if (filter.endTime) {
|
|
52
|
+
const endTime = filter.endTime;
|
|
53
|
+
results = results.filter((e) => e.timestamp <= endTime);
|
|
54
|
+
}
|
|
55
|
+
// Most recent first
|
|
56
|
+
results = [...results].reverse();
|
|
57
|
+
if (filter.offset) {
|
|
58
|
+
results = results.slice(filter.offset);
|
|
59
|
+
}
|
|
60
|
+
if (filter.limit) {
|
|
61
|
+
results = results.slice(0, filter.limit);
|
|
62
|
+
}
|
|
63
|
+
return results;
|
|
64
|
+
}
|
|
65
|
+
async count(agentId) {
|
|
66
|
+
if (agentId) {
|
|
67
|
+
return this.entries.filter((e) => e.agentId === agentId).length;
|
|
68
|
+
}
|
|
69
|
+
return this.entries.length;
|
|
70
|
+
}
|
|
71
|
+
async since(timestamp, limit = 1000) {
|
|
72
|
+
return this.entries.filter((e) => e.timestamp >= timestamp).slice(-limit);
|
|
73
|
+
}
|
|
74
|
+
/** Evict oldest entries when over the limit */
|
|
75
|
+
enforceLimit() {
|
|
76
|
+
if (this.entries.length > this.maxEntries) {
|
|
77
|
+
this.entries = this.entries.slice(this.entries.length - this.maxEntries);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|