@measureoneinc/savant 1.0.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/README-SDK.md +148 -0
- package/dist/ai/agents/domain-identifier.agent.d.ts +34 -0
- package/dist/ai/agents/domain-identifier.agent.d.ts.map +1 -0
- package/dist/ai/agents/domain-identifier.agent.js +176 -0
- package/dist/ai/agents/domain-identifier.agent.js.map +1 -0
- package/dist/ai/agents/dynamic-agent.d.ts +105 -0
- package/dist/ai/agents/dynamic-agent.d.ts.map +1 -0
- package/dist/ai/agents/dynamic-agent.js +505 -0
- package/dist/ai/agents/dynamic-agent.js.map +1 -0
- package/dist/ai/agents/executor.agent.d.ts +25 -0
- package/dist/ai/agents/executor.agent.d.ts.map +1 -0
- package/dist/ai/agents/executor.agent.js +44 -0
- package/dist/ai/agents/executor.agent.js.map +1 -0
- package/dist/ai/agents/index.d.ts +17 -0
- package/dist/ai/agents/index.d.ts.map +1 -0
- package/dist/ai/agents/index.js +29 -0
- package/dist/ai/agents/index.js.map +1 -0
- package/dist/ai/agents/knowledge.agent.d.ts +25 -0
- package/dist/ai/agents/knowledge.agent.d.ts.map +1 -0
- package/dist/ai/agents/knowledge.agent.js +42 -0
- package/dist/ai/agents/knowledge.agent.js.map +1 -0
- package/dist/ai/agents/learning.agent.d.ts +63 -0
- package/dist/ai/agents/learning.agent.d.ts.map +1 -0
- package/dist/ai/agents/learning.agent.js +288 -0
- package/dist/ai/agents/learning.agent.js.map +1 -0
- package/dist/ai/agents/orchestrator.agent.d.ts +26 -0
- package/dist/ai/agents/orchestrator.agent.d.ts.map +1 -0
- package/dist/ai/agents/orchestrator.agent.js +42 -0
- package/dist/ai/agents/orchestrator.agent.js.map +1 -0
- package/dist/ai/agents/planner.agent.d.ts +25 -0
- package/dist/ai/agents/planner.agent.d.ts.map +1 -0
- package/dist/ai/agents/planner.agent.js +36 -0
- package/dist/ai/agents/planner.agent.js.map +1 -0
- package/dist/ai/agents/response-parser.d.ts +23 -0
- package/dist/ai/agents/response-parser.d.ts.map +1 -0
- package/dist/ai/agents/response-parser.js +313 -0
- package/dist/ai/agents/response-parser.js.map +1 -0
- package/dist/ai/agents/summarizer.agent.d.ts +38 -0
- package/dist/ai/agents/summarizer.agent.d.ts.map +1 -0
- package/dist/ai/agents/summarizer.agent.js +245 -0
- package/dist/ai/agents/summarizer.agent.js.map +1 -0
- package/dist/ai/instructions/domain-identifier.instructions.d.ts +10 -0
- package/dist/ai/instructions/domain-identifier.instructions.d.ts.map +1 -0
- package/dist/ai/instructions/domain-identifier.instructions.js +63 -0
- package/dist/ai/instructions/domain-identifier.instructions.js.map +1 -0
- package/dist/ai/instructions/executor.instructions.d.ts +11 -0
- package/dist/ai/instructions/executor.instructions.d.ts.map +1 -0
- package/dist/ai/instructions/executor.instructions.js +218 -0
- package/dist/ai/instructions/executor.instructions.js.map +1 -0
- package/dist/ai/instructions/knowledge.instructions.d.ts +11 -0
- package/dist/ai/instructions/knowledge.instructions.d.ts.map +1 -0
- package/dist/ai/instructions/knowledge.instructions.js +145 -0
- package/dist/ai/instructions/knowledge.instructions.js.map +1 -0
- package/dist/ai/instructions/learning.instructions.d.ts +11 -0
- package/dist/ai/instructions/learning.instructions.d.ts.map +1 -0
- package/dist/ai/instructions/learning.instructions.js +226 -0
- package/dist/ai/instructions/learning.instructions.js.map +1 -0
- package/dist/ai/instructions/orchestrator.instructions.d.ts +11 -0
- package/dist/ai/instructions/orchestrator.instructions.d.ts.map +1 -0
- package/dist/ai/instructions/orchestrator.instructions.js +148 -0
- package/dist/ai/instructions/orchestrator.instructions.js.map +1 -0
- package/dist/ai/instructions/planner.instructions.d.ts +12 -0
- package/dist/ai/instructions/planner.instructions.d.ts.map +1 -0
- package/dist/ai/instructions/planner.instructions.js +129 -0
- package/dist/ai/instructions/planner.instructions.js.map +1 -0
- package/dist/ai/instructions/summarizer.instructions.d.ts +11 -0
- package/dist/ai/instructions/summarizer.instructions.d.ts.map +1 -0
- package/dist/ai/instructions/summarizer.instructions.js +84 -0
- package/dist/ai/instructions/summarizer.instructions.js.map +1 -0
- package/dist/ai/learning/execution-learner.d.ts +79 -0
- package/dist/ai/learning/execution-learner.d.ts.map +1 -0
- package/dist/ai/learning/execution-learner.js +536 -0
- package/dist/ai/learning/execution-learner.js.map +1 -0
- package/dist/ai/response_handlers/base-handler.d.ts +73 -0
- package/dist/ai/response_handlers/base-handler.d.ts.map +1 -0
- package/dist/ai/response_handlers/base-handler.js +153 -0
- package/dist/ai/response_handlers/base-handler.js.map +1 -0
- package/dist/ai/response_handlers/direct-response-handler.d.ts +18 -0
- package/dist/ai/response_handlers/direct-response-handler.d.ts.map +1 -0
- package/dist/ai/response_handlers/direct-response-handler.js +86 -0
- package/dist/ai/response_handlers/direct-response-handler.js.map +1 -0
- package/dist/ai/response_handlers/error-handler.d.ts +13 -0
- package/dist/ai/response_handlers/error-handler.d.ts.map +1 -0
- package/dist/ai/response_handlers/error-handler.js +72 -0
- package/dist/ai/response_handlers/error-handler.js.map +1 -0
- package/dist/ai/response_handlers/handler-registry.d.ts +51 -0
- package/dist/ai/response_handlers/handler-registry.d.ts.map +1 -0
- package/dist/ai/response_handlers/handler-registry.js +268 -0
- package/dist/ai/response_handlers/handler-registry.js.map +1 -0
- package/dist/ai/response_handlers/index.d.ts +16 -0
- package/dist/ai/response_handlers/index.d.ts.map +1 -0
- package/dist/ai/response_handlers/index.js +29 -0
- package/dist/ai/response_handlers/index.js.map +1 -0
- package/dist/ai/response_handlers/message-handler.d.ts +23 -0
- package/dist/ai/response_handlers/message-handler.d.ts.map +1 -0
- package/dist/ai/response_handlers/message-handler.js +193 -0
- package/dist/ai/response_handlers/message-handler.js.map +1 -0
- package/dist/ai/response_handlers/plan-ready-handler.d.ts +26 -0
- package/dist/ai/response_handlers/plan-ready-handler.d.ts.map +1 -0
- package/dist/ai/response_handlers/plan-ready-handler.js +394 -0
- package/dist/ai/response_handlers/plan-ready-handler.js.map +1 -0
- package/dist/ai/response_handlers/request-input-handler.d.ts +14 -0
- package/dist/ai/response_handlers/request-input-handler.d.ts.map +1 -0
- package/dist/ai/response_handlers/request-input-handler.js +87 -0
- package/dist/ai/response_handlers/request-input-handler.js.map +1 -0
- package/dist/ai/response_handlers/request-plan-handler.d.ts +18 -0
- package/dist/ai/response_handlers/request-plan-handler.d.ts.map +1 -0
- package/dist/ai/response_handlers/request-plan-handler.js +143 -0
- package/dist/ai/response_handlers/request-plan-handler.js.map +1 -0
- package/dist/ai/response_handlers/step-complete-handler.d.ts +22 -0
- package/dist/ai/response_handlers/step-complete-handler.d.ts.map +1 -0
- package/dist/ai/response_handlers/step-complete-handler.js +307 -0
- package/dist/ai/response_handlers/step-complete-handler.js.map +1 -0
- package/dist/ai/response_handlers/unknown-handler.d.ts +12 -0
- package/dist/ai/response_handlers/unknown-handler.d.ts.map +1 -0
- package/dist/ai/response_handlers/unknown-handler.js +27 -0
- package/dist/ai/response_handlers/unknown-handler.js.map +1 -0
- package/dist/ai/response_handlers/user-input-handler.d.ts +20 -0
- package/dist/ai/response_handlers/user-input-handler.d.ts.map +1 -0
- package/dist/ai/response_handlers/user-input-handler.js +69 -0
- package/dist/ai/response_handlers/user-input-handler.js.map +1 -0
- package/dist/ai/tools/log-step.d.ts +29 -0
- package/dist/ai/tools/log-step.d.ts.map +1 -0
- package/dist/ai/tools/log-step.js +47 -0
- package/dist/ai/tools/log-step.js.map +1 -0
- package/dist/app.d.ts +15 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +223 -0
- package/dist/app.js.map +1 -0
- package/dist/config/environment/local.d.ts +12 -0
- package/dist/config/environment/local.d.ts.map +1 -0
- package/dist/config/environment/local.js +124 -0
- package/dist/config/environment/local.js.map +1 -0
- package/dist/config/environment/production.d.ts +7 -0
- package/dist/config/environment/production.d.ts.map +1 -0
- package/dist/config/environment/production.js +105 -0
- package/dist/config/environment/production.js.map +1 -0
- package/dist/config/environment/test.d.ts +7 -0
- package/dist/config/environment/test.d.ts.map +1 -0
- package/dist/config/environment/test.js +97 -0
- package/dist/config/environment/test.js.map +1 -0
- package/dist/config/index.d.ts +219 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +360 -0
- package/dist/config/index.js.map +1 -0
- package/dist/controllers/agent_request.controller.d.ts +43 -0
- package/dist/controllers/agent_request.controller.d.ts.map +1 -0
- package/dist/controllers/agent_request.controller.js +141 -0
- package/dist/controllers/agent_request.controller.js.map +1 -0
- package/dist/controllers/base.controller.d.ts +208 -0
- package/dist/controllers/base.controller.d.ts.map +1 -0
- package/dist/controllers/base.controller.js +378 -0
- package/dist/controllers/base.controller.js.map +1 -0
- package/dist/controllers/conversations.controller.d.ts +31 -0
- package/dist/controllers/conversations.controller.d.ts.map +1 -0
- package/dist/controllers/conversations.controller.js +138 -0
- package/dist/controllers/conversations.controller.js.map +1 -0
- package/dist/controllers/knowledge.controller.d.ts +63 -0
- package/dist/controllers/knowledge.controller.d.ts.map +1 -0
- package/dist/controllers/knowledge.controller.js +311 -0
- package/dist/controllers/knowledge.controller.js.map +1 -0
- package/dist/controllers/mcp.controller.d.ts +25 -0
- package/dist/controllers/mcp.controller.d.ts.map +1 -0
- package/dist/controllers/mcp.controller.js +93 -0
- package/dist/controllers/mcp.controller.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/app-constants.d.ts +231 -0
- package/dist/lib/app-constants.d.ts.map +1 -0
- package/dist/lib/app-constants.js +240 -0
- package/dist/lib/app-constants.js.map +1 -0
- package/dist/lib/controller-utils.d.ts +48 -0
- package/dist/lib/controller-utils.d.ts.map +1 -0
- package/dist/lib/controller-utils.js +70 -0
- package/dist/lib/controller-utils.js.map +1 -0
- package/dist/lib/exceptions/app-exceptions.d.ts +158 -0
- package/dist/lib/exceptions/app-exceptions.d.ts.map +1 -0
- package/dist/lib/exceptions/app-exceptions.js +287 -0
- package/dist/lib/exceptions/app-exceptions.js.map +1 -0
- package/dist/lib/middleware/upload.middleware.d.ts +13 -0
- package/dist/lib/middleware/upload.middleware.d.ts.map +1 -0
- package/dist/lib/middleware/upload.middleware.js +35 -0
- package/dist/lib/middleware/upload.middleware.js.map +1 -0
- package/dist/lib/middleware/validation.middleware.d.ts +29 -0
- package/dist/lib/middleware/validation.middleware.d.ts.map +1 -0
- package/dist/lib/middleware/validation.middleware.js +219 -0
- package/dist/lib/middleware/validation.middleware.js.map +1 -0
- package/dist/lib/model/validation-schema/submit-message.schema.d.ts +3 -0
- package/dist/lib/model/validation-schema/submit-message.schema.d.ts.map +1 -0
- package/dist/lib/model/validation-schema/submit-message.schema.js +40 -0
- package/dist/lib/model/validation-schema/submit-message.schema.js.map +1 -0
- package/dist/lib/model/validation-schema/update-knowledge.schema.d.ts +3 -0
- package/dist/lib/model/validation-schema/update-knowledge.schema.d.ts.map +1 -0
- package/dist/lib/model/validation-schema/update-knowledge.schema.js +35 -0
- package/dist/lib/model/validation-schema/update-knowledge.schema.js.map +1 -0
- package/dist/lib/open-ai-event-processor.d.ts +101 -0
- package/dist/lib/open-ai-event-processor.d.ts.map +1 -0
- package/dist/lib/open-ai-event-processor.js +426 -0
- package/dist/lib/open-ai-event-processor.js.map +1 -0
- package/dist/lib/schemas/ai-responses.schema.d.ts +617 -0
- package/dist/lib/schemas/ai-responses.schema.d.ts.map +1 -0
- package/dist/lib/schemas/ai-responses.schema.js +377 -0
- package/dist/lib/schemas/ai-responses.schema.js.map +1 -0
- package/dist/lib/schemas/common.schemas.d.ts +84 -0
- package/dist/lib/schemas/common.schemas.d.ts.map +1 -0
- package/dist/lib/schemas/common.schemas.js +87 -0
- package/dist/lib/schemas/common.schemas.js.map +1 -0
- package/dist/lib/schemas/conversation.schema.d.ts +28 -0
- package/dist/lib/schemas/conversation.schema.d.ts.map +1 -0
- package/dist/lib/schemas/conversation.schema.js +31 -0
- package/dist/lib/schemas/conversation.schema.js.map +1 -0
- package/dist/lib/schemas/http-client.schema.d.ts +39 -0
- package/dist/lib/schemas/http-client.schema.d.ts.map +1 -0
- package/dist/lib/schemas/http-client.schema.js +36 -0
- package/dist/lib/schemas/http-client.schema.js.map +1 -0
- package/dist/lib/schemas/index.d.ts +95 -0
- package/dist/lib/schemas/index.d.ts.map +1 -0
- package/dist/lib/schemas/index.js +32 -0
- package/dist/lib/schemas/index.js.map +1 -0
- package/dist/lib/schemas/knowledge.schema.d.ts +145 -0
- package/dist/lib/schemas/knowledge.schema.d.ts.map +1 -0
- package/dist/lib/schemas/knowledge.schema.js +81 -0
- package/dist/lib/schemas/knowledge.schema.js.map +1 -0
- package/dist/lib/schemas/orchestration.schema.d.ts +168 -0
- package/dist/lib/schemas/orchestration.schema.d.ts.map +1 -0
- package/dist/lib/schemas/orchestration.schema.js +133 -0
- package/dist/lib/schemas/orchestration.schema.js.map +1 -0
- package/dist/lib/schemas/plan.schema.d.ts +103 -0
- package/dist/lib/schemas/plan.schema.d.ts.map +1 -0
- package/dist/lib/schemas/plan.schema.js +58 -0
- package/dist/lib/schemas/plan.schema.js.map +1 -0
- package/dist/lib/sequelize-service.d.ts +23 -0
- package/dist/lib/sequelize-service.d.ts.map +1 -0
- package/dist/lib/sequelize-service.js +446 -0
- package/dist/lib/sequelize-service.js.map +1 -0
- package/dist/lib/source-hash.d.ts +39 -0
- package/dist/lib/source-hash.d.ts.map +1 -0
- package/dist/lib/source-hash.js +56 -0
- package/dist/lib/source-hash.js.map +1 -0
- package/dist/lib/stable-stringify.d.ts +32 -0
- package/dist/lib/stable-stringify.d.ts.map +1 -0
- package/dist/lib/stable-stringify.js +72 -0
- package/dist/lib/stable-stringify.js.map +1 -0
- package/dist/lib/streaming-utils.d.ts +60 -0
- package/dist/lib/streaming-utils.d.ts.map +1 -0
- package/dist/lib/streaming-utils.js +190 -0
- package/dist/lib/streaming-utils.js.map +1 -0
- package/dist/lib/utils/conversation-builder.d.ts +36 -0
- package/dist/lib/utils/conversation-builder.d.ts.map +1 -0
- package/dist/lib/utils/conversation-builder.js +132 -0
- package/dist/lib/utils/conversation-builder.js.map +1 -0
- package/dist/lib/utils/domain-matcher.d.ts +25 -0
- package/dist/lib/utils/domain-matcher.d.ts.map +1 -0
- package/dist/lib/utils/domain-matcher.js +42 -0
- package/dist/lib/utils/domain-matcher.js.map +1 -0
- package/dist/lib/utils/file-util.d.ts +157 -0
- package/dist/lib/utils/file-util.d.ts.map +1 -0
- package/dist/lib/utils/file-util.js +373 -0
- package/dist/lib/utils/file-util.js.map +1 -0
- package/dist/lib/utils/html-summarizer.d.ts +27 -0
- package/dist/lib/utils/html-summarizer.d.ts.map +1 -0
- package/dist/lib/utils/html-summarizer.js +189 -0
- package/dist/lib/utils/html-summarizer.js.map +1 -0
- package/dist/lib/utils/http-client.d.ts +108 -0
- package/dist/lib/utils/http-client.d.ts.map +1 -0
- package/dist/lib/utils/http-client.js +298 -0
- package/dist/lib/utils/http-client.js.map +1 -0
- package/dist/lib/utils/index.d.ts +12 -0
- package/dist/lib/utils/index.d.ts.map +1 -0
- package/dist/lib/utils/index.js +28 -0
- package/dist/lib/utils/index.js.map +1 -0
- package/dist/lib/utils/logger.d.ts +30 -0
- package/dist/lib/utils/logger.d.ts.map +1 -0
- package/dist/lib/utils/logger.js +88 -0
- package/dist/lib/utils/logger.js.map +1 -0
- package/dist/lib/utils/mcp-utils.d.ts +208 -0
- package/dist/lib/utils/mcp-utils.d.ts.map +1 -0
- package/dist/lib/utils/mcp-utils.js +451 -0
- package/dist/lib/utils/mcp-utils.js.map +1 -0
- package/dist/lib/utils/sequelize-service.d.ts +153 -0
- package/dist/lib/utils/sequelize-service.d.ts.map +1 -0
- package/dist/lib/utils/sequelize-service.js +339 -0
- package/dist/lib/utils/sequelize-service.js.map +1 -0
- package/dist/lib/utils/tool-call-extractor.d.ts +36 -0
- package/dist/lib/utils/tool-call-extractor.d.ts.map +1 -0
- package/dist/lib/utils/tool-call-extractor.js +121 -0
- package/dist/lib/utils/tool-call-extractor.js.map +1 -0
- package/dist/lib/utils/zod-to-json-schema.d.ts +17 -0
- package/dist/lib/utils/zod-to-json-schema.d.ts.map +1 -0
- package/dist/lib/utils/zod-to-json-schema.js +53 -0
- package/dist/lib/utils/zod-to-json-schema.js.map +1 -0
- package/dist/models/AgentRequest.d.ts +33 -0
- package/dist/models/AgentRequest.d.ts.map +1 -0
- package/dist/models/AgentRequest.js +49 -0
- package/dist/models/AgentRequest.js.map +1 -0
- package/dist/models/AgentRun.d.ts +44 -0
- package/dist/models/AgentRun.d.ts.map +1 -0
- package/dist/models/AgentRun.js +53 -0
- package/dist/models/AgentRun.js.map +1 -0
- package/dist/models/AuditLog.d.ts +37 -0
- package/dist/models/AuditLog.d.ts.map +1 -0
- package/dist/models/AuditLog.js +46 -0
- package/dist/models/AuditLog.js.map +1 -0
- package/dist/models/Conversation.d.ts +39 -0
- package/dist/models/Conversation.d.ts.map +1 -0
- package/dist/models/Conversation.js +49 -0
- package/dist/models/Conversation.js.map +1 -0
- package/dist/models/Embedding.d.ts +56 -0
- package/dist/models/Embedding.d.ts.map +1 -0
- package/dist/models/Embedding.js +36 -0
- package/dist/models/Embedding.js.map +1 -0
- package/dist/models/ExecutionPattern.d.ts +57 -0
- package/dist/models/ExecutionPattern.d.ts.map +1 -0
- package/dist/models/ExecutionPattern.js +61 -0
- package/dist/models/ExecutionPattern.js.map +1 -0
- package/dist/models/Knowledge.d.ts +49 -0
- package/dist/models/Knowledge.d.ts.map +1 -0
- package/dist/models/Knowledge.js +67 -0
- package/dist/models/Knowledge.js.map +1 -0
- package/dist/models/KnowledgeRevision.d.ts +35 -0
- package/dist/models/KnowledgeRevision.d.ts.map +1 -0
- package/dist/models/KnowledgeRevision.js +51 -0
- package/dist/models/KnowledgeRevision.js.map +1 -0
- package/dist/models/Plan.d.ts +34 -0
- package/dist/models/Plan.d.ts.map +1 -0
- package/dist/models/Plan.js +43 -0
- package/dist/models/Plan.js.map +1 -0
- package/dist/models/PlanStep.d.ts +56 -0
- package/dist/models/PlanStep.d.ts.map +1 -0
- package/dist/models/PlanStep.js +65 -0
- package/dist/models/PlanStep.js.map +1 -0
- package/dist/models/SourceData.d.ts +39 -0
- package/dist/models/SourceData.d.ts.map +1 -0
- package/dist/models/SourceData.js +18 -0
- package/dist/models/SourceData.js.map +1 -0
- package/dist/models/index.d.ts +36 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +179 -0
- package/dist/models/index.js.map +1 -0
- package/dist/routes/agent.routes.d.ts +13 -0
- package/dist/routes/agent.routes.d.ts.map +1 -0
- package/dist/routes/agent.routes.js +27 -0
- package/dist/routes/agent.routes.js.map +1 -0
- package/dist/routes/agent_request.routes.d.ts +13 -0
- package/dist/routes/agent_request.routes.d.ts.map +1 -0
- package/dist/routes/agent_request.routes.js +65 -0
- package/dist/routes/agent_request.routes.js.map +1 -0
- package/dist/routes/knowledge.routes.d.ts +13 -0
- package/dist/routes/knowledge.routes.d.ts.map +1 -0
- package/dist/routes/knowledge.routes.js +91 -0
- package/dist/routes/knowledge.routes.js.map +1 -0
- package/dist/routes/mcp.routes.d.ts +14 -0
- package/dist/routes/mcp.routes.d.ts.map +1 -0
- package/dist/routes/mcp.routes.js +27 -0
- package/dist/routes/mcp.routes.js.map +1 -0
- package/dist/sdk/index.d.ts +13 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js +35 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/savant.sdk.d.ts +53 -0
- package/dist/sdk/savant.sdk.d.ts.map +1 -0
- package/dist/sdk/savant.sdk.js +120 -0
- package/dist/sdk/savant.sdk.js.map +1 -0
- package/dist/services/agent-request-service.d.ts +104 -0
- package/dist/services/agent-request-service.d.ts.map +1 -0
- package/dist/services/agent-request-service.js +319 -0
- package/dist/services/agent-request-service.js.map +1 -0
- package/dist/services/audit_log.service.d.ts +104 -0
- package/dist/services/audit_log.service.d.ts.map +1 -0
- package/dist/services/audit_log.service.js +339 -0
- package/dist/services/audit_log.service.js.map +1 -0
- package/dist/services/conversation.service.d.ts +90 -0
- package/dist/services/conversation.service.d.ts.map +1 -0
- package/dist/services/conversation.service.js +552 -0
- package/dist/services/conversation.service.js.map +1 -0
- package/dist/services/domain.service.d.ts +58 -0
- package/dist/services/domain.service.d.ts.map +1 -0
- package/dist/services/domain.service.js +244 -0
- package/dist/services/domain.service.js.map +1 -0
- package/dist/services/embedding.service.d.ts +132 -0
- package/dist/services/embedding.service.d.ts.map +1 -0
- package/dist/services/embedding.service.js +587 -0
- package/dist/services/embedding.service.js.map +1 -0
- package/dist/services/file_upload.service.d.ts +50 -0
- package/dist/services/file_upload.service.d.ts.map +1 -0
- package/dist/services/file_upload.service.js +172 -0
- package/dist/services/file_upload.service.js.map +1 -0
- package/dist/services/knowledge.service.d.ts +200 -0
- package/dist/services/knowledge.service.d.ts.map +1 -0
- package/dist/services/knowledge.service.js +784 -0
- package/dist/services/knowledge.service.js.map +1 -0
- package/dist/types/responses-api.types.d.ts +181 -0
- package/dist/types/responses-api.types.d.ts.map +1 -0
- package/dist/types/responses-api.types.js +12 -0
- package/dist/types/responses-api.types.js.map +1 -0
- package/package.json +145 -0
|
@@ -0,0 +1,784 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Knowledge Service - Sequelize Version
|
|
4
|
+
*
|
|
5
|
+
* Service for managing Knowledge entities.
|
|
6
|
+
* Handles all database operations using Sequelize.
|
|
7
|
+
*
|
|
8
|
+
* @author MeasureOne, Inc.
|
|
9
|
+
* @version 1.0.0
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.KnowledgeService = void 0;
|
|
13
|
+
const logger_1 = require("../lib/utils/logger");
|
|
14
|
+
const sequelize_service_1 = require("../lib/sequelize-service");
|
|
15
|
+
const models_1 = require("../models");
|
|
16
|
+
const sequelize_1 = require("sequelize");
|
|
17
|
+
const uuid_1 = require("uuid");
|
|
18
|
+
const stable_stringify_1 = require("../lib/stable-stringify");
|
|
19
|
+
const source_hash_1 = require("../lib/source-hash");
|
|
20
|
+
const config_1 = require("../config");
|
|
21
|
+
const logger = (0, logger_1.create_default_logger)("knowledge-service");
|
|
22
|
+
class KnowledgeService {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.sequelize = (0, sequelize_service_1.get_sequelize_service)();
|
|
25
|
+
}
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// KNOWLEDGE OPERATIONS
|
|
28
|
+
// ============================================================================
|
|
29
|
+
/**
|
|
30
|
+
* Get the next revision number for a knowledge
|
|
31
|
+
*
|
|
32
|
+
* @param knowledge_id - ID of the knowledge
|
|
33
|
+
* @returns Promise resolving to the next revision number
|
|
34
|
+
*/
|
|
35
|
+
async get_next_revision_number(knowledge_id) {
|
|
36
|
+
const max_revision = await models_1.KnowledgeRevisionModel.max("revision", {
|
|
37
|
+
where: { knowledge_id },
|
|
38
|
+
});
|
|
39
|
+
return (typeof max_revision === "number" ? max_revision : 0) + 1;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create a new revision for existing knowledge
|
|
43
|
+
* Shared method used by both SEED and LEARNING embedding creation
|
|
44
|
+
*
|
|
45
|
+
* @param knowledge_id - ID of the knowledge
|
|
46
|
+
* @param source_data - Source data object (will be stringified)
|
|
47
|
+
* @param source_hash - Hash of the source data
|
|
48
|
+
* @param metadata - Optional metadata object (will be stringified)
|
|
49
|
+
* @param transaction - Optional transaction (if not provided, creates a new one)
|
|
50
|
+
* @returns Promise resolving to the new revision ID
|
|
51
|
+
*/
|
|
52
|
+
async create_revision_for_knowledge(knowledge_id, source_data, source_hash, metadata, transaction) {
|
|
53
|
+
const should_commit = !transaction;
|
|
54
|
+
const txn = transaction || await this.sequelize.transaction();
|
|
55
|
+
try {
|
|
56
|
+
// Get the knowledge to verify it exists
|
|
57
|
+
const knowledge = await models_1.KnowledgeModel.findByPk(knowledge_id, { transaction: txn });
|
|
58
|
+
if (!knowledge) {
|
|
59
|
+
throw new Error(`Knowledge ${knowledge_id} not found`);
|
|
60
|
+
}
|
|
61
|
+
// Get the next revision number
|
|
62
|
+
const next_revision = await this.get_next_revision_number(knowledge_id);
|
|
63
|
+
// Create new revision
|
|
64
|
+
const new_revision_id = `kn_rev_${(0, uuid_1.v4)()}`;
|
|
65
|
+
const revision_data = {
|
|
66
|
+
id: new_revision_id,
|
|
67
|
+
knowledge_id: knowledge_id,
|
|
68
|
+
revision: next_revision,
|
|
69
|
+
source_data: typeof source_data === 'string' ? source_data : (0, stable_stringify_1.stable_stringify)(source_data),
|
|
70
|
+
source_hash: source_hash,
|
|
71
|
+
metadata: metadata ? (typeof metadata === 'string' ? metadata : JSON.stringify(metadata)) : undefined,
|
|
72
|
+
};
|
|
73
|
+
await models_1.KnowledgeRevisionModel.create(revision_data, { transaction: txn });
|
|
74
|
+
// Update knowledge's current_revision_id
|
|
75
|
+
knowledge.current_revision_id = new_revision_id;
|
|
76
|
+
await knowledge.save({ transaction: txn });
|
|
77
|
+
if (should_commit) {
|
|
78
|
+
await txn.commit();
|
|
79
|
+
}
|
|
80
|
+
logger.info("Created new revision for knowledge", {
|
|
81
|
+
knowledge_id,
|
|
82
|
+
revision_id: new_revision_id,
|
|
83
|
+
revision_number: next_revision
|
|
84
|
+
});
|
|
85
|
+
return new_revision_id;
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
if (should_commit) {
|
|
89
|
+
await txn.rollback();
|
|
90
|
+
}
|
|
91
|
+
logger.error("Failed to create revision for knowledge", {
|
|
92
|
+
knowledge_id,
|
|
93
|
+
error: error instanceof Error ? error.message : String(error)
|
|
94
|
+
});
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Create new knowledge with LEARNING metadata
|
|
100
|
+
* Shared method used by both embedding.service and execution-learner
|
|
101
|
+
*
|
|
102
|
+
* @param learning_text - The learning text content
|
|
103
|
+
* @returns Promise resolving to knowledge ID and revision ID
|
|
104
|
+
*/
|
|
105
|
+
async create_learning_knowledge(learning_text) {
|
|
106
|
+
const app_id = config_1.config_utils.get("APPLICATION_ID") || "savant-orchestration";
|
|
107
|
+
const requester_id = config_1.config_utils.get("REQUESTER_ID") || "execution-learner";
|
|
108
|
+
// Create new knowledge with 1st revision
|
|
109
|
+
const knowledge_result = await this.create_knowledge({
|
|
110
|
+
application_id: app_id,
|
|
111
|
+
requester_id: requester_id,
|
|
112
|
+
source_data: {
|
|
113
|
+
source_type: 'VALUE',
|
|
114
|
+
mime_type: 'text/markdown',
|
|
115
|
+
content: learning_text
|
|
116
|
+
},
|
|
117
|
+
status: 'COMPLETED',
|
|
118
|
+
delivery_details: {},
|
|
119
|
+
metadata: {
|
|
120
|
+
purpose: 'learned-patterns',
|
|
121
|
+
auto_generated: 'true',
|
|
122
|
+
created_by: 'execution-learner',
|
|
123
|
+
type: 'LEARNING'
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
// Get the created knowledge with revision
|
|
127
|
+
const knowledge_model = await models_1.KnowledgeModel.findByPk(knowledge_result.id);
|
|
128
|
+
if (!knowledge_model?.current_revision_id) {
|
|
129
|
+
throw new Error(`No revision found for newly created knowledge ${knowledge_result.id}`);
|
|
130
|
+
}
|
|
131
|
+
logger.info("Created new knowledge with first revision for learning", {
|
|
132
|
+
knowledge_id: knowledge_result.id,
|
|
133
|
+
revision_id: knowledge_model.current_revision_id
|
|
134
|
+
});
|
|
135
|
+
return {
|
|
136
|
+
knowledge_id: knowledge_result.id,
|
|
137
|
+
revision_id: knowledge_model.current_revision_id
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get the current revision for a knowledge
|
|
142
|
+
*
|
|
143
|
+
* @param knowledge_id - ID of the knowledge
|
|
144
|
+
* @returns Promise resolving to the current revision or null if not found
|
|
145
|
+
*/
|
|
146
|
+
async get_current_revision(knowledge_id) {
|
|
147
|
+
const knowledge = await models_1.KnowledgeModel.findByPk(knowledge_id);
|
|
148
|
+
if (!knowledge || !knowledge.current_revision_id) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
const revision = await models_1.KnowledgeRevisionModel.findByPk(knowledge.current_revision_id);
|
|
152
|
+
return revision ? revision.to_shared_type() : null;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Create a new knowledge with initial revision
|
|
156
|
+
*/
|
|
157
|
+
async create_knowledge(data) {
|
|
158
|
+
const transaction = await this.sequelize.transaction();
|
|
159
|
+
try {
|
|
160
|
+
const knowledge_id = `kn_${(0, uuid_1.v4)()}`;
|
|
161
|
+
// Validate that source_data is either VALUE or REFERENCE type
|
|
162
|
+
if (!data.source_data || typeof data.source_data !== 'object') {
|
|
163
|
+
throw new Error("source_data must be an object.");
|
|
164
|
+
}
|
|
165
|
+
if (data.source_data.source_type === 'VALUE') {
|
|
166
|
+
if (typeof data.source_data.content !== 'string') {
|
|
167
|
+
throw new Error("source_data with VALUE type must have a content string.");
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else if (data.source_data.source_type === 'REFERENCE') {
|
|
171
|
+
if (typeof data.source_data.uri !== 'string') {
|
|
172
|
+
throw new Error("source_data with REFERENCE type must have a uri string.");
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
throw new Error("source_data.source_type must be either 'VALUE' or 'REFERENCE'.");
|
|
177
|
+
}
|
|
178
|
+
// Create stable hash for the source data
|
|
179
|
+
const stable_json = (0, stable_stringify_1.stable_stringify)(data.source_data);
|
|
180
|
+
const source_hash = (0, source_hash_1.compute_source_hash)(stable_json);
|
|
181
|
+
const current_revision_id = `kn_rev_${(0, uuid_1.v4)()}`;
|
|
182
|
+
// Create a proper Knowledge object for from_shared_type
|
|
183
|
+
// from_shared_type expects a Knowledge with all required schema fields
|
|
184
|
+
const knowledge_for_model = {
|
|
185
|
+
id: knowledge_id,
|
|
186
|
+
application_id: data.application_id,
|
|
187
|
+
requester_id: data.requester_id,
|
|
188
|
+
source_data: data.source_data,
|
|
189
|
+
status: data.status,
|
|
190
|
+
delivery_details: data.delivery_details,
|
|
191
|
+
created_at: new Date().toISOString(),
|
|
192
|
+
updated_at: new Date().toISOString(),
|
|
193
|
+
...(data.response && { response: data.response }),
|
|
194
|
+
...(data.metadata && { metadata: data.metadata }),
|
|
195
|
+
...(data.deleted_at && { deleted_at: data.deleted_at }),
|
|
196
|
+
};
|
|
197
|
+
// Convert to model attributes using from_shared_type
|
|
198
|
+
// from_shared_type always returns required fields, so we can safely use it
|
|
199
|
+
const knowledge_data = models_1.KnowledgeModel.from_shared_type(knowledge_for_model);
|
|
200
|
+
// Create Knowledge WITHOUT current_revision_id first (to avoid foreign key constraint violation)
|
|
201
|
+
// We'll set it after creating the revision
|
|
202
|
+
const knowledge = await models_1.KnowledgeModel.create(knowledge_data, { transaction });
|
|
203
|
+
// Create the first revision (revision 1)
|
|
204
|
+
const revision_data = {
|
|
205
|
+
id: current_revision_id,
|
|
206
|
+
knowledge_id: knowledge_id,
|
|
207
|
+
revision: 1,
|
|
208
|
+
source_data: stable_json,
|
|
209
|
+
source_hash: source_hash,
|
|
210
|
+
metadata: data.metadata ? JSON.stringify(data.metadata) : undefined,
|
|
211
|
+
};
|
|
212
|
+
await models_1.KnowledgeRevisionModel.create(revision_data, { transaction });
|
|
213
|
+
// Now update Knowledge to set current_revision_id (revision exists now)
|
|
214
|
+
knowledge.current_revision_id = current_revision_id;
|
|
215
|
+
await knowledge.save({ transaction });
|
|
216
|
+
await transaction.commit();
|
|
217
|
+
logger.info("Knowledge created with initial revision", {
|
|
218
|
+
id: knowledge.id,
|
|
219
|
+
revision: 1,
|
|
220
|
+
source_hash: source_hash,
|
|
221
|
+
});
|
|
222
|
+
return { id: knowledge.id };
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
await transaction.rollback();
|
|
226
|
+
logger.error("Failed to create knowledge", error);
|
|
227
|
+
throw error;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Get knowledge by ID
|
|
232
|
+
*/
|
|
233
|
+
async get_knowledge_by_id(id) {
|
|
234
|
+
try {
|
|
235
|
+
const knowledge = await models_1.KnowledgeModel.findByPk(id, {
|
|
236
|
+
paranoid: true, // Exclude soft-deleted records
|
|
237
|
+
});
|
|
238
|
+
if (!knowledge) {
|
|
239
|
+
throw new Error(`Knowledge not found: ${id}`);
|
|
240
|
+
}
|
|
241
|
+
logger.info("Knowledge retrieved", { id });
|
|
242
|
+
return knowledge.to_shared_type();
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
logger.error("Failed to get knowledge", error);
|
|
246
|
+
throw error;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Update knowledge
|
|
251
|
+
*
|
|
252
|
+
* Updates a knowledge and creates a new revision if the source_data
|
|
253
|
+
* has changed (indicated by a different source_hash). If the source_hash
|
|
254
|
+
* remains the same, the existing revision is kept.
|
|
255
|
+
*/
|
|
256
|
+
async update_knowledge(data) {
|
|
257
|
+
const transaction = await this.sequelize.transaction();
|
|
258
|
+
try {
|
|
259
|
+
const knowledge = await models_1.KnowledgeModel.findByPk(data.id);
|
|
260
|
+
if (!knowledge) {
|
|
261
|
+
throw new Error(`Knowledge not found: ${data.id}`);
|
|
262
|
+
}
|
|
263
|
+
let new_revision_id = null;
|
|
264
|
+
// Handle source_data changes
|
|
265
|
+
if (data.source_data) {
|
|
266
|
+
new_revision_id = await this.handle_source_data_update(data, knowledge, transaction);
|
|
267
|
+
}
|
|
268
|
+
// Update other fields
|
|
269
|
+
this.update_knowledge_fields(knowledge, data);
|
|
270
|
+
// Update current_revision_id if a new revision was created
|
|
271
|
+
if (new_revision_id) {
|
|
272
|
+
knowledge.current_revision_id = new_revision_id;
|
|
273
|
+
}
|
|
274
|
+
await knowledge.save({ transaction });
|
|
275
|
+
await transaction.commit();
|
|
276
|
+
logger.info("Knowledge updated", {
|
|
277
|
+
id: data.id,
|
|
278
|
+
new_revision_created: !!new_revision_id,
|
|
279
|
+
revision_id: new_revision_id || knowledge.current_revision_id,
|
|
280
|
+
});
|
|
281
|
+
return { id: knowledge.id };
|
|
282
|
+
}
|
|
283
|
+
catch (error) {
|
|
284
|
+
await transaction.rollback();
|
|
285
|
+
logger.error("Failed to update knowledge", error);
|
|
286
|
+
throw error;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Handle source data update and revision creation
|
|
291
|
+
*/
|
|
292
|
+
async handle_source_data_update(data, knowledge, transaction) {
|
|
293
|
+
// Validate source_data type inline
|
|
294
|
+
if (!data.source_data || typeof data.source_data !== 'object' ||
|
|
295
|
+
(data.source_data.source_type !== 'VALUE' && data.source_data.source_type !== 'REFERENCE')) {
|
|
296
|
+
throw new Error("source_data must be either VALUE or REFERENCE type.");
|
|
297
|
+
}
|
|
298
|
+
// Create stable hash for the new source data
|
|
299
|
+
const stable_json = (0, stable_stringify_1.stable_stringify)(data.source_data);
|
|
300
|
+
const new_source_hash = (0, source_hash_1.compute_source_hash)(stable_json);
|
|
301
|
+
// Check if source_hash has changed
|
|
302
|
+
const current_revision = await models_1.KnowledgeRevisionModel.findOne({
|
|
303
|
+
where: { id: knowledge.current_revision_id },
|
|
304
|
+
});
|
|
305
|
+
if (!current_revision) {
|
|
306
|
+
throw new Error(`Current revision not found: ${knowledge.current_revision_id}`);
|
|
307
|
+
}
|
|
308
|
+
// If source hash hasn't changed, no new revision needed
|
|
309
|
+
if (current_revision.source_hash === new_source_hash) {
|
|
310
|
+
knowledge.source_data = stable_json;
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
// Source data has changed, create new revision
|
|
314
|
+
const next_revision_number = await this.get_next_revision_number(data.id);
|
|
315
|
+
const new_revision_id = `kn_rev_${(0, uuid_1.v4)()}`;
|
|
316
|
+
const revision_data = {
|
|
317
|
+
id: new_revision_id,
|
|
318
|
+
knowledge_id: data.id,
|
|
319
|
+
revision: next_revision_number,
|
|
320
|
+
source_data: stable_json,
|
|
321
|
+
source_hash: new_source_hash,
|
|
322
|
+
metadata: data.metadata ? JSON.stringify(data.metadata) : undefined,
|
|
323
|
+
};
|
|
324
|
+
await models_1.KnowledgeRevisionModel.create(revision_data, { transaction });
|
|
325
|
+
logger.info("New revision created due to source_data change", {
|
|
326
|
+
knowledge_id: data.id, revision: next_revision_number,
|
|
327
|
+
old_source_hash: current_revision.source_hash, new_source_hash: new_source_hash,
|
|
328
|
+
});
|
|
329
|
+
// Update the source_data field
|
|
330
|
+
knowledge.source_data = stable_json;
|
|
331
|
+
return new_revision_id;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Update knowledge fields (excluding source_data)
|
|
335
|
+
*/
|
|
336
|
+
update_knowledge_fields(knowledge, data) {
|
|
337
|
+
if (data.application_id)
|
|
338
|
+
knowledge.application_id = data.application_id;
|
|
339
|
+
if (data.requester_id)
|
|
340
|
+
knowledge.requester_id = data.requester_id;
|
|
341
|
+
if (data.status)
|
|
342
|
+
knowledge.status = data.status;
|
|
343
|
+
if (data.response !== undefined)
|
|
344
|
+
knowledge.response = data.response;
|
|
345
|
+
if (data.delivery_details)
|
|
346
|
+
knowledge.delivery_details = JSON.stringify(data.delivery_details);
|
|
347
|
+
if (data.metadata !== undefined) {
|
|
348
|
+
knowledge.metadata = data.metadata ? JSON.stringify(data.metadata) : undefined;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Delete knowledge (soft delete)
|
|
353
|
+
*/
|
|
354
|
+
async delete_knowledge(id) {
|
|
355
|
+
try {
|
|
356
|
+
const knowledge = await models_1.KnowledgeModel.findByPk(id);
|
|
357
|
+
if (!knowledge) {
|
|
358
|
+
throw new Error(`Knowledge not found: ${id}`);
|
|
359
|
+
}
|
|
360
|
+
await knowledge.destroy(); // Sequelize handles soft delete with paranoid: true
|
|
361
|
+
logger.info("Knowledge soft deleted", { id });
|
|
362
|
+
return { id };
|
|
363
|
+
}
|
|
364
|
+
catch (error) {
|
|
365
|
+
logger.error("Failed to delete knowledge", error);
|
|
366
|
+
throw error;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* List knowledge with pagination and filtering
|
|
371
|
+
*/
|
|
372
|
+
async list_knowledge(filters) {
|
|
373
|
+
try {
|
|
374
|
+
const { page = 1, limit = 20, application_id, requester_id, status } = filters;
|
|
375
|
+
const offset = (page - 1) * limit;
|
|
376
|
+
const where = {};
|
|
377
|
+
if (application_id)
|
|
378
|
+
where.application_id = application_id;
|
|
379
|
+
if (requester_id)
|
|
380
|
+
where.requester_id = requester_id;
|
|
381
|
+
if (status)
|
|
382
|
+
where.status = status;
|
|
383
|
+
const { count: total, rows: knowledge_list } = await models_1.KnowledgeModel.findAndCountAll({
|
|
384
|
+
where,
|
|
385
|
+
offset,
|
|
386
|
+
limit,
|
|
387
|
+
order: [["created_at", "DESC"]],
|
|
388
|
+
paranoid: true, // Exclude soft-deleted records
|
|
389
|
+
});
|
|
390
|
+
const converted_list = knowledge_list.map((kn) => kn.to_shared_type());
|
|
391
|
+
const pagination = {
|
|
392
|
+
page,
|
|
393
|
+
limit,
|
|
394
|
+
offset,
|
|
395
|
+
total,
|
|
396
|
+
total_pages: Math.ceil(total / limit),
|
|
397
|
+
has_next: page < Math.ceil(total / limit),
|
|
398
|
+
has_prev: page > 1,
|
|
399
|
+
};
|
|
400
|
+
logger.info("Knowledge listed", {
|
|
401
|
+
count: knowledge_list.length,
|
|
402
|
+
total,
|
|
403
|
+
});
|
|
404
|
+
return { data: converted_list, pagination };
|
|
405
|
+
}
|
|
406
|
+
catch (error) {
|
|
407
|
+
logger.error("Failed to list knowledge", error);
|
|
408
|
+
throw error;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Get knowledge by application ID
|
|
413
|
+
*/
|
|
414
|
+
async get_knowledge_by_application(application_id, filters) {
|
|
415
|
+
try {
|
|
416
|
+
const { page = 1, limit = 20, status } = filters;
|
|
417
|
+
const offset = (page - 1) * limit;
|
|
418
|
+
const where = { application_id };
|
|
419
|
+
if (status)
|
|
420
|
+
where.status = status;
|
|
421
|
+
const { count: total, rows: knowledge_list } = await models_1.KnowledgeModel.findAndCountAll({
|
|
422
|
+
where,
|
|
423
|
+
offset,
|
|
424
|
+
limit,
|
|
425
|
+
order: [["created_at", "DESC"]],
|
|
426
|
+
paranoid: true,
|
|
427
|
+
});
|
|
428
|
+
const converted_list = knowledge_list.map((kn) => kn.to_shared_type());
|
|
429
|
+
const pagination = {
|
|
430
|
+
page,
|
|
431
|
+
limit,
|
|
432
|
+
offset,
|
|
433
|
+
total,
|
|
434
|
+
total_pages: Math.ceil(total / limit),
|
|
435
|
+
has_next: page < Math.ceil(total / limit),
|
|
436
|
+
has_prev: page > 1,
|
|
437
|
+
};
|
|
438
|
+
logger.info("Knowledge listed by application", {
|
|
439
|
+
application_id,
|
|
440
|
+
count: knowledge_list.length,
|
|
441
|
+
total,
|
|
442
|
+
});
|
|
443
|
+
return { data: converted_list, pagination };
|
|
444
|
+
}
|
|
445
|
+
catch (error) {
|
|
446
|
+
logger.error("Failed to get knowledge by application", error);
|
|
447
|
+
throw error;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Get knowledge by requester ID
|
|
452
|
+
*/
|
|
453
|
+
async get_knowledge_by_requester(requester_id, filters) {
|
|
454
|
+
try {
|
|
455
|
+
const { page = 1, limit = 20, status } = filters;
|
|
456
|
+
const offset = (page - 1) * limit;
|
|
457
|
+
const where = { requester_id };
|
|
458
|
+
if (status)
|
|
459
|
+
where.status = status;
|
|
460
|
+
const { count: total, rows: knowledge_list } = await models_1.KnowledgeModel.findAndCountAll({
|
|
461
|
+
where,
|
|
462
|
+
offset,
|
|
463
|
+
limit,
|
|
464
|
+
order: [["created_at", "DESC"]],
|
|
465
|
+
paranoid: true,
|
|
466
|
+
});
|
|
467
|
+
const converted_list = knowledge_list.map((kn) => kn.to_shared_type());
|
|
468
|
+
const pagination = {
|
|
469
|
+
page,
|
|
470
|
+
limit,
|
|
471
|
+
offset,
|
|
472
|
+
total,
|
|
473
|
+
total_pages: Math.ceil(total / limit),
|
|
474
|
+
has_next: page < Math.ceil(total / limit),
|
|
475
|
+
has_prev: page > 1,
|
|
476
|
+
};
|
|
477
|
+
logger.info("Knowledge listed by requester", {
|
|
478
|
+
requester_id,
|
|
479
|
+
count: knowledge_list.length,
|
|
480
|
+
total,
|
|
481
|
+
});
|
|
482
|
+
return { data: converted_list, pagination };
|
|
483
|
+
}
|
|
484
|
+
catch (error) {
|
|
485
|
+
logger.error("Failed to get knowledge by requester", error);
|
|
486
|
+
throw error;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Update knowledge status
|
|
491
|
+
*/
|
|
492
|
+
async update_knowledge_status(id, status, response) {
|
|
493
|
+
try {
|
|
494
|
+
const knowledge = await models_1.KnowledgeModel.findByPk(id);
|
|
495
|
+
if (!knowledge) {
|
|
496
|
+
throw new Error(`Knowledge not found: ${id}`);
|
|
497
|
+
}
|
|
498
|
+
knowledge.status = status;
|
|
499
|
+
if (response !== undefined) {
|
|
500
|
+
knowledge.response = response;
|
|
501
|
+
}
|
|
502
|
+
await knowledge.save();
|
|
503
|
+
logger.info("Knowledge status updated", { id, status });
|
|
504
|
+
return { id };
|
|
505
|
+
}
|
|
506
|
+
catch (error) {
|
|
507
|
+
logger.error("Failed to update knowledge status", error);
|
|
508
|
+
throw error;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Get knowledge statistics
|
|
513
|
+
*/
|
|
514
|
+
async get_knowledge_stats(filters) {
|
|
515
|
+
try {
|
|
516
|
+
const where = {};
|
|
517
|
+
if (filters.application_id)
|
|
518
|
+
where.application_id = filters.application_id;
|
|
519
|
+
if (filters.requester_id)
|
|
520
|
+
where.requester_id = filters.requester_id;
|
|
521
|
+
if (filters.start_date || filters.end_date) {
|
|
522
|
+
where.created_at = {};
|
|
523
|
+
if (filters.start_date)
|
|
524
|
+
where.created_at[sequelize_1.Op.gte] = new Date(filters.start_date);
|
|
525
|
+
if (filters.end_date)
|
|
526
|
+
where.created_at[sequelize_1.Op.lte] = new Date(filters.end_date);
|
|
527
|
+
}
|
|
528
|
+
const { count: total } = await models_1.KnowledgeModel.findAndCountAll({
|
|
529
|
+
where,
|
|
530
|
+
paranoid: true,
|
|
531
|
+
});
|
|
532
|
+
const sequelize = this.sequelize;
|
|
533
|
+
const statusCounts = await models_1.KnowledgeModel.findAll({
|
|
534
|
+
where,
|
|
535
|
+
attributes: ["status", [sequelize.fn("COUNT", sequelize.col("id")), "count"]],
|
|
536
|
+
group: ["status"],
|
|
537
|
+
paranoid: true,
|
|
538
|
+
raw: true,
|
|
539
|
+
});
|
|
540
|
+
const by_status = statusCounts.reduce((acc, item) => {
|
|
541
|
+
acc[item.status] = parseInt(item.count);
|
|
542
|
+
return acc;
|
|
543
|
+
}, {});
|
|
544
|
+
const stats = {
|
|
545
|
+
total,
|
|
546
|
+
pending: by_status.PENDING || 0,
|
|
547
|
+
completed: by_status.COMPLETED || 0,
|
|
548
|
+
failed: by_status.FAILED || 0,
|
|
549
|
+
by_status,
|
|
550
|
+
};
|
|
551
|
+
logger.info("Knowledge stats retrieved", { total, by_status });
|
|
552
|
+
return stats;
|
|
553
|
+
}
|
|
554
|
+
catch (error) {
|
|
555
|
+
logger.error("Failed to get knowledge stats", error);
|
|
556
|
+
throw error;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Set content for knowledge (placeholder method)
|
|
561
|
+
*/
|
|
562
|
+
async set_content(data) {
|
|
563
|
+
try {
|
|
564
|
+
// This is a placeholder method - implement based on your requirements
|
|
565
|
+
logger.info("Set content called", { data });
|
|
566
|
+
return {
|
|
567
|
+
success: true,
|
|
568
|
+
message: "Content set successfully",
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
catch (error) {
|
|
572
|
+
logger.error("Failed to set content", error);
|
|
573
|
+
throw error;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
// ============================================================================
|
|
577
|
+
// KNOWLEDGE REVISION OPERATIONS
|
|
578
|
+
// ============================================================================
|
|
579
|
+
/**
|
|
580
|
+
* Update knowledge with revision tracking
|
|
581
|
+
*/
|
|
582
|
+
async update_knowledge_with_revision(payload) {
|
|
583
|
+
const transaction = await this.sequelize.transaction();
|
|
584
|
+
try {
|
|
585
|
+
logger.info("Updating knowledge with revision", { knowledge_id: payload.id });
|
|
586
|
+
const knowledge = await this.load_knowledge_for_update(payload.id, transaction);
|
|
587
|
+
const revision_info = await this.handle_revision_update(payload, transaction);
|
|
588
|
+
await transaction.commit();
|
|
589
|
+
const response = this.build_update_response(payload.id, knowledge, revision_info);
|
|
590
|
+
logger.info("Knowledge updated successfully", { knowledge_id: payload.id, revision: revision_info.revision_number, reused: revision_info.reused, revision_id: revision_info.revision_id });
|
|
591
|
+
return response;
|
|
592
|
+
}
|
|
593
|
+
catch (error) {
|
|
594
|
+
await transaction.rollback();
|
|
595
|
+
logger.error("Failed to update knowledge with revision", { knowledge_id: payload.id, error: error instanceof Error ? error.message : String(error) });
|
|
596
|
+
throw error;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Load knowledge for update
|
|
601
|
+
*/
|
|
602
|
+
async load_knowledge_for_update(id, transaction) {
|
|
603
|
+
const knowledge = await models_1.KnowledgeModel.findByPk(id, { paranoid: true, transaction });
|
|
604
|
+
if (!knowledge) {
|
|
605
|
+
throw new Error(`Knowledge not found: ${id}`);
|
|
606
|
+
}
|
|
607
|
+
return knowledge;
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Handle revision update logic
|
|
611
|
+
*/
|
|
612
|
+
async handle_revision_update(payload, transaction) {
|
|
613
|
+
let revision_number = 1;
|
|
614
|
+
let reused = false;
|
|
615
|
+
let source_hash = "";
|
|
616
|
+
let revision_id = "";
|
|
617
|
+
if (!payload.source_data) {
|
|
618
|
+
return { revision_number, reused, source_hash, revision_id };
|
|
619
|
+
}
|
|
620
|
+
// Validate and compute hash - only VALUE sources are supported
|
|
621
|
+
if (!payload.source_data || typeof payload.source_data !== 'object' || payload.source_data.source_type !== 'VALUE') {
|
|
622
|
+
throw new Error("Only VALUE sources are supported at this time.");
|
|
623
|
+
}
|
|
624
|
+
if (typeof payload.source_data.content !== 'string') {
|
|
625
|
+
throw new Error("source_data with VALUE type must have a content string.");
|
|
626
|
+
}
|
|
627
|
+
const stable_json = (0, stable_stringify_1.stable_stringify)(payload.source_data);
|
|
628
|
+
source_hash = (0, source_hash_1.compute_source_hash)(stable_json);
|
|
629
|
+
// Check for existing revision
|
|
630
|
+
const existing_revision = await models_1.KnowledgeRevisionModel.findOne({
|
|
631
|
+
where: { knowledge_id: payload.id, source_hash },
|
|
632
|
+
transaction,
|
|
633
|
+
});
|
|
634
|
+
if (existing_revision) {
|
|
635
|
+
revision_number = existing_revision.to_shared_type().revision;
|
|
636
|
+
revision_id = existing_revision.id;
|
|
637
|
+
reused = true;
|
|
638
|
+
logger.info("Reusing existing revision", {
|
|
639
|
+
knowledge_id: payload.id,
|
|
640
|
+
revision: revision_number,
|
|
641
|
+
revision_id,
|
|
642
|
+
source_hash,
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
if (!existing_revision) {
|
|
646
|
+
// Create new revision using shared method
|
|
647
|
+
revision_id = await this.create_revision_for_knowledge(payload.id, stable_json, source_hash, undefined, transaction);
|
|
648
|
+
// Get the created revision to get revision number
|
|
649
|
+
const created_revision = await models_1.KnowledgeRevisionModel.findByPk(revision_id, { transaction });
|
|
650
|
+
revision_number = created_revision ? created_revision.revision : 1;
|
|
651
|
+
logger.info("Created new revision", {
|
|
652
|
+
knowledge_id: payload.id,
|
|
653
|
+
revision: revision_number,
|
|
654
|
+
revision_id,
|
|
655
|
+
source_hash,
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
const knowledge = await models_1.KnowledgeModel.findByPk(payload.id, { transaction });
|
|
659
|
+
// Update knowledge source_data (current_revision_id already updated by create_revision_for_knowledge)
|
|
660
|
+
knowledge.source_data = stable_json;
|
|
661
|
+
await knowledge.save({ transaction });
|
|
662
|
+
return { revision_number, reused, source_hash, revision_id };
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Build update response
|
|
666
|
+
*/
|
|
667
|
+
build_update_response(id, knowledge, revision_info) {
|
|
668
|
+
return {
|
|
669
|
+
id,
|
|
670
|
+
revision_number: revision_info.revision_number,
|
|
671
|
+
reused: revision_info.reused,
|
|
672
|
+
source_hash: revision_info.source_hash,
|
|
673
|
+
revision_id: revision_info.revision_id,
|
|
674
|
+
status: knowledge.status,
|
|
675
|
+
updated_at: knowledge.updated_at.toISOString(),
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Validate update knowledge request data
|
|
680
|
+
* Checks that knowledge_id exists in DB and is not associated with LEARNING embeddings
|
|
681
|
+
* Returns validation result with error message if validation fails
|
|
682
|
+
*/
|
|
683
|
+
async validate_update_knowledge_data(data) {
|
|
684
|
+
logger.info('🔍 Validating update knowledge data', {
|
|
685
|
+
knowledge_id: data.knowledge_id
|
|
686
|
+
});
|
|
687
|
+
// Validate that knowledge_id exists in DB
|
|
688
|
+
const knowledge = await models_1.KnowledgeModel.findByPk(data.knowledge_id, { paranoid: true });
|
|
689
|
+
if (!knowledge) {
|
|
690
|
+
logger.warn('❌ Knowledge not found', { knowledge_id: data.knowledge_id });
|
|
691
|
+
return {
|
|
692
|
+
isValid: false,
|
|
693
|
+
errorMessage: `Knowledge not found: ${data.knowledge_id}`,
|
|
694
|
+
errorDetails: { knowledge_id: data.knowledge_id, field: 'id' }
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
// Check if knowledge has LEARNING embeddings - these cannot be updated
|
|
698
|
+
const learning_embeddings_count = await models_1.EmbeddingModel.count({
|
|
699
|
+
where: {
|
|
700
|
+
knowledge_id: data.knowledge_id,
|
|
701
|
+
type: models_1.EmbeddingType.LEARNING
|
|
702
|
+
}
|
|
703
|
+
});
|
|
704
|
+
if (learning_embeddings_count > 0) {
|
|
705
|
+
logger.warn('❌ Cannot update knowledge with LEARNING embeddings', {
|
|
706
|
+
knowledge_id: data.knowledge_id,
|
|
707
|
+
learning_embeddings_count
|
|
708
|
+
});
|
|
709
|
+
return {
|
|
710
|
+
isValid: false,
|
|
711
|
+
errorMessage: `Knowledge cannot be updated: it is associated with ${learning_embeddings_count} LEARNING embedding(s). Learning knowledge is read-only and managed automatically by the execution learner.`,
|
|
712
|
+
errorDetails: {
|
|
713
|
+
knowledge_id: data.knowledge_id,
|
|
714
|
+
learning_embeddings_count,
|
|
715
|
+
reason: 'LEARNING_EMBEDDINGS_EXIST'
|
|
716
|
+
}
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
return { isValid: true };
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Get knowledge revision
|
|
723
|
+
*/
|
|
724
|
+
async get_knowledge_revision(payload) {
|
|
725
|
+
try {
|
|
726
|
+
logger.info("Getting knowledge revision", { knowledge_id: payload.knowledge_id, revision: payload.revision });
|
|
727
|
+
let where_clause = {
|
|
728
|
+
knowledge_id: payload.knowledge_id,
|
|
729
|
+
};
|
|
730
|
+
if (payload.revision !== undefined) {
|
|
731
|
+
where_clause.revision = payload.revision;
|
|
732
|
+
}
|
|
733
|
+
const revision = await models_1.KnowledgeRevisionModel.findOne({ where: where_clause, order: payload.revision === undefined ? [["revision", "DESC"]] : undefined });
|
|
734
|
+
if (!revision) {
|
|
735
|
+
const error_msg = payload.revision !== undefined
|
|
736
|
+
? `Revision ${payload.revision} not found for knowledge ${payload.knowledge_id}`
|
|
737
|
+
: `No revisions found for knowledge ${payload.knowledge_id}`;
|
|
738
|
+
throw new Error(error_msg);
|
|
739
|
+
}
|
|
740
|
+
logger.info("Knowledge revision retrieved", { knowledge_id: payload.knowledge_id, revision: revision.revision });
|
|
741
|
+
return revision.to_shared_type();
|
|
742
|
+
}
|
|
743
|
+
catch (error) {
|
|
744
|
+
logger.error("Failed to get knowledge revision", { knowledge_id: payload.knowledge_id, revision: payload.revision, error: error instanceof Error ? error.message : String(error) });
|
|
745
|
+
throw error;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Get knowledge by ID with latest revision info
|
|
750
|
+
*/
|
|
751
|
+
async get_knowledge_by_id_with_revision(id) {
|
|
752
|
+
try {
|
|
753
|
+
const knowledge = await models_1.KnowledgeModel.findByPk(id, {
|
|
754
|
+
paranoid: true,
|
|
755
|
+
include: [
|
|
756
|
+
{
|
|
757
|
+
model: models_1.KnowledgeRevisionModel,
|
|
758
|
+
as: "revisions",
|
|
759
|
+
limit: 1,
|
|
760
|
+
order: [["revision", "DESC"]],
|
|
761
|
+
attributes: ["id", "revision"],
|
|
762
|
+
},
|
|
763
|
+
],
|
|
764
|
+
});
|
|
765
|
+
if (!knowledge) {
|
|
766
|
+
throw new Error(`Knowledge not found: ${id}`);
|
|
767
|
+
}
|
|
768
|
+
const result = knowledge.to_shared_type();
|
|
769
|
+
// Add latest revision ID if available
|
|
770
|
+
const revisions = knowledge.revisions;
|
|
771
|
+
if (revisions && revisions.length > 0) {
|
|
772
|
+
result.latest_revision_id = revisions[0].id;
|
|
773
|
+
}
|
|
774
|
+
logger.info("Knowledge with revision info retrieved", { id });
|
|
775
|
+
return result;
|
|
776
|
+
}
|
|
777
|
+
catch (error) {
|
|
778
|
+
logger.error("Failed to get knowledge with revision info", error);
|
|
779
|
+
throw error;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
exports.KnowledgeService = KnowledgeService;
|
|
784
|
+
//# sourceMappingURL=knowledge.service.js.map
|