centient 2.20.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/CHANGELOG.md +362 -0
- package/README.md +433 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +478 -0
- package/dist/server.js.map +1 -0
- package/dist/telemetry/index.d.ts +4 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +3 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/instrumentation.d.ts +10 -0
- package/dist/telemetry/instrumentation.d.ts.map +1 -0
- package/dist/telemetry/instrumentation.js +86 -0
- package/dist/telemetry/instrumentation.js.map +1 -0
- package/dist/telemetry/tracer.d.ts +6 -0
- package/dist/telemetry/tracer.d.ts.map +1 -0
- package/dist/telemetry/tracer.js +27 -0
- package/dist/telemetry/tracer.js.map +1 -0
- package/dist/tools/artifacts/diffSessions.d.ts +9 -0
- package/dist/tools/artifacts/diffSessions.d.ts.map +1 -0
- package/dist/tools/artifacts/diffSessions.js +320 -0
- package/dist/tools/artifacts/diffSessions.js.map +1 -0
- package/dist/tools/artifacts/extractSessionContext.d.ts +9 -0
- package/dist/tools/artifacts/extractSessionContext.d.ts.map +1 -0
- package/dist/tools/artifacts/extractSessionContext.js +291 -0
- package/dist/tools/artifacts/extractSessionContext.js.map +1 -0
- package/dist/tools/artifacts/getSessionCode.d.ts +9 -0
- package/dist/tools/artifacts/getSessionCode.d.ts.map +1 -0
- package/dist/tools/artifacts/getSessionCode.js +104 -0
- package/dist/tools/artifacts/getSessionCode.js.map +1 -0
- package/dist/tools/artifacts/loadSession.d.ts +9 -0
- package/dist/tools/artifacts/loadSession.d.ts.map +1 -0
- package/dist/tools/artifacts/loadSession.js +163 -0
- package/dist/tools/artifacts/loadSession.js.map +1 -0
- package/dist/tools/artifacts/searchArtifacts.d.ts +9 -0
- package/dist/tools/artifacts/searchArtifacts.d.ts.map +1 -0
- package/dist/tools/artifacts/searchArtifacts.js +98 -0
- package/dist/tools/artifacts/searchArtifacts.js.map +1 -0
- package/dist/tools/branching/closeBranch.d.ts +10 -0
- package/dist/tools/branching/closeBranch.d.ts.map +1 -0
- package/dist/tools/branching/closeBranch.js +193 -0
- package/dist/tools/branching/closeBranch.js.map +1 -0
- package/dist/tools/branching/createBranch.d.ts +10 -0
- package/dist/tools/branching/createBranch.d.ts.map +1 -0
- package/dist/tools/branching/createBranch.js +136 -0
- package/dist/tools/branching/createBranch.js.map +1 -0
- package/dist/tools/branching/listBranches.d.ts +9 -0
- package/dist/tools/branching/listBranches.d.ts.map +1 -0
- package/dist/tools/branching/listBranches.js +212 -0
- package/dist/tools/branching/listBranches.js.map +1 -0
- package/dist/tools/branching/listDecisionPoints.d.ts +9 -0
- package/dist/tools/branching/listDecisionPoints.d.ts.map +1 -0
- package/dist/tools/branching/listDecisionPoints.js +156 -0
- package/dist/tools/branching/listDecisionPoints.js.map +1 -0
- package/dist/tools/branching/markDecisionPoint.d.ts +10 -0
- package/dist/tools/branching/markDecisionPoint.d.ts.map +1 -0
- package/dist/tools/branching/markDecisionPoint.js +149 -0
- package/dist/tools/branching/markDecisionPoint.js.map +1 -0
- package/dist/tools/branching/switchBranch.d.ts +9 -0
- package/dist/tools/branching/switchBranch.d.ts.map +1 -0
- package/dist/tools/branching/switchBranch.js +153 -0
- package/dist/tools/branching/switchBranch.js.map +1 -0
- package/dist/tools/consultation/aggregateConsensus.d.ts +9 -0
- package/dist/tools/consultation/aggregateConsensus.d.ts.map +1 -0
- package/dist/tools/consultation/aggregateConsensus.js +259 -0
- package/dist/tools/consultation/aggregateConsensus.js.map +1 -0
- package/dist/tools/consultation/captureConsultationResponse.d.ts +11 -0
- package/dist/tools/consultation/captureConsultationResponse.d.ts.map +1 -0
- package/dist/tools/consultation/captureConsultationResponse.js +244 -0
- package/dist/tools/consultation/captureConsultationResponse.js.map +1 -0
- package/dist/tools/consultation/consultLlmStream.d.ts +9 -0
- package/dist/tools/consultation/consultLlmStream.d.ts.map +1 -0
- package/dist/tools/consultation/consultLlmStream.js +201 -0
- package/dist/tools/consultation/consultLlmStream.js.map +1 -0
- package/dist/tools/consultation/index.d.ts +8 -0
- package/dist/tools/consultation/index.d.ts.map +1 -0
- package/dist/tools/consultation/index.js +8 -0
- package/dist/tools/consultation/index.js.map +1 -0
- package/dist/tools/consultation/peerReviewContract.d.ts +146 -0
- package/dist/tools/consultation/peerReviewContract.d.ts.map +1 -0
- package/dist/tools/consultation/peerReviewContract.js +731 -0
- package/dist/tools/consultation/peerReviewContract.js.map +1 -0
- package/dist/tools/consultation/peerReviewSession.d.ts +9 -0
- package/dist/tools/consultation/peerReviewSession.d.ts.map +1 -0
- package/dist/tools/consultation/peerReviewSession.js +433 -0
- package/dist/tools/consultation/peerReviewSession.js.map +1 -0
- package/dist/tools/consultation/prepareConsultationContext.d.ts +9 -0
- package/dist/tools/consultation/prepareConsultationContext.d.ts.map +1 -0
- package/dist/tools/consultation/prepareConsultationContext.js +263 -0
- package/dist/tools/consultation/prepareConsultationContext.js.map +1 -0
- package/dist/tools/consultation/seekConsensus.d.ts +9 -0
- package/dist/tools/consultation/seekConsensus.d.ts.map +1 -0
- package/dist/tools/consultation/seekConsensus.js +358 -0
- package/dist/tools/consultation/seekConsensus.js.map +1 -0
- package/dist/tools/consultation/validateDecision.d.ts +9 -0
- package/dist/tools/consultation/validateDecision.d.ts.map +1 -0
- package/dist/tools/consultation/validateDecision.js +253 -0
- package/dist/tools/consultation/validateDecision.js.map +1 -0
- package/dist/tools/consultation/validateReviewResponse.d.ts +9 -0
- package/dist/tools/consultation/validateReviewResponse.d.ts.map +1 -0
- package/dist/tools/consultation/validateReviewResponse.js +105 -0
- package/dist/tools/consultation/validateReviewResponse.js.map +1 -0
- package/dist/tools/graph/addNoteRelationship.d.ts +9 -0
- package/dist/tools/graph/addNoteRelationship.d.ts.map +1 -0
- package/dist/tools/graph/addNoteRelationship.js +120 -0
- package/dist/tools/graph/addNoteRelationship.js.map +1 -0
- package/dist/tools/graph/linkSessions.d.ts +9 -0
- package/dist/tools/graph/linkSessions.d.ts.map +1 -0
- package/dist/tools/graph/linkSessions.js +126 -0
- package/dist/tools/graph/linkSessions.js.map +1 -0
- package/dist/tools/graph/queryTemporalGraph.d.ts +9 -0
- package/dist/tools/graph/queryTemporalGraph.d.ts.map +1 -0
- package/dist/tools/graph/queryTemporalGraph.js +339 -0
- package/dist/tools/graph/queryTemporalGraph.js.map +1 -0
- package/dist/tools/health/getCircuitBreakerStats.d.ts +9 -0
- package/dist/tools/health/getCircuitBreakerStats.d.ts.map +1 -0
- package/dist/tools/health/getCircuitBreakerStats.js +195 -0
- package/dist/tools/health/getCircuitBreakerStats.js.map +1 -0
- package/dist/tools/health/getContextHealth.d.ts +9 -0
- package/dist/tools/health/getContextHealth.d.ts.map +1 -0
- package/dist/tools/health/getContextHealth.js +331 -0
- package/dist/tools/health/getContextHealth.js.map +1 -0
- package/dist/tools/health/getQdrantHealth.d.ts +9 -0
- package/dist/tools/health/getQdrantHealth.d.ts.map +1 -0
- package/dist/tools/health/getQdrantHealth.js +144 -0
- package/dist/tools/health/getQdrantHealth.js.map +1 -0
- package/dist/tools/health/getRateLimitStats.d.ts +9 -0
- package/dist/tools/health/getRateLimitStats.d.ts.map +1 -0
- package/dist/tools/health/getRateLimitStats.js +191 -0
- package/dist/tools/health/getRateLimitStats.js.map +1 -0
- package/dist/tools/knowledge/index.d.ts +4 -0
- package/dist/tools/knowledge/index.d.ts.map +1 -0
- package/dist/tools/knowledge/index.js +4 -0
- package/dist/tools/knowledge/index.js.map +1 -0
- package/dist/tools/knowledge/promoteDecision.d.ts +9 -0
- package/dist/tools/knowledge/promoteDecision.d.ts.map +1 -0
- package/dist/tools/knowledge/promoteDecision.js +139 -0
- package/dist/tools/knowledge/promoteDecision.js.map +1 -0
- package/dist/tools/knowledge/promoteLearning.d.ts +9 -0
- package/dist/tools/knowledge/promoteLearning.d.ts.map +1 -0
- package/dist/tools/knowledge/promoteLearning.js +132 -0
- package/dist/tools/knowledge/promoteLearning.js.map +1 -0
- package/dist/tools/knowledge/searchMetaKnowledge.d.ts +9 -0
- package/dist/tools/knowledge/searchMetaKnowledge.d.ts.map +1 -0
- package/dist/tools/knowledge/searchMetaKnowledge.js +120 -0
- package/dist/tools/knowledge/searchMetaKnowledge.js.map +1 -0
- package/dist/tools/memory/addNote.d.ts +9 -0
- package/dist/tools/memory/addNote.d.ts.map +1 -0
- package/dist/tools/memory/addNote.js +105 -0
- package/dist/tools/memory/addNote.js.map +1 -0
- package/dist/tools/memory/getDecisions.d.ts +9 -0
- package/dist/tools/memory/getDecisions.d.ts.map +1 -0
- package/dist/tools/memory/getDecisions.js +93 -0
- package/dist/tools/memory/getDecisions.js.map +1 -0
- package/dist/tools/memory/getHypotheses.d.ts +9 -0
- package/dist/tools/memory/getHypotheses.d.ts.map +1 -0
- package/dist/tools/memory/getHypotheses.js +93 -0
- package/dist/tools/memory/getHypotheses.js.map +1 -0
- package/dist/tools/memory-bank/memoryBankList.d.ts +9 -0
- package/dist/tools/memory-bank/memoryBankList.d.ts.map +1 -0
- package/dist/tools/memory-bank/memoryBankList.js +108 -0
- package/dist/tools/memory-bank/memoryBankList.js.map +1 -0
- package/dist/tools/memory-bank/memoryBankSearch.d.ts +9 -0
- package/dist/tools/memory-bank/memoryBankSearch.d.ts.map +1 -0
- package/dist/tools/memory-bank/memoryBankSearch.js +128 -0
- package/dist/tools/memory-bank/memoryBankSearch.js.map +1 -0
- package/dist/tools/metrics/getAuditLog.d.ts +9 -0
- package/dist/tools/metrics/getAuditLog.d.ts.map +1 -0
- package/dist/tools/metrics/getAuditLog.js +172 -0
- package/dist/tools/metrics/getAuditLog.js.map +1 -0
- package/dist/tools/metrics/getCompressionRatio.d.ts +9 -0
- package/dist/tools/metrics/getCompressionRatio.d.ts.map +1 -0
- package/dist/tools/metrics/getCompressionRatio.js +112 -0
- package/dist/tools/metrics/getCompressionRatio.js.map +1 -0
- package/dist/tools/metrics/getCostDashboard.d.ts +9 -0
- package/dist/tools/metrics/getCostDashboard.d.ts.map +1 -0
- package/dist/tools/metrics/getCostDashboard.js +126 -0
- package/dist/tools/metrics/getCostDashboard.js.map +1 -0
- package/dist/tools/metrics/getPatternAnalytics.d.ts +9 -0
- package/dist/tools/metrics/getPatternAnalytics.d.ts.map +1 -0
- package/dist/tools/metrics/getPatternAnalytics.js +192 -0
- package/dist/tools/metrics/getPatternAnalytics.js.map +1 -0
- package/dist/tools/metrics/getPatternReuse.d.ts +9 -0
- package/dist/tools/metrics/getPatternReuse.d.ts.map +1 -0
- package/dist/tools/metrics/getPatternReuse.js +130 -0
- package/dist/tools/metrics/getPatternReuse.js.map +1 -0
- package/dist/tools/patterns/createPatternVersion.d.ts +9 -0
- package/dist/tools/patterns/createPatternVersion.d.ts.map +1 -0
- package/dist/tools/patterns/createPatternVersion.js +137 -0
- package/dist/tools/patterns/createPatternVersion.js.map +1 -0
- package/dist/tools/patterns/deprecatePatternVersion.d.ts +9 -0
- package/dist/tools/patterns/deprecatePatternVersion.d.ts.map +1 -0
- package/dist/tools/patterns/deprecatePatternVersion.js +131 -0
- package/dist/tools/patterns/deprecatePatternVersion.js.map +1 -0
- package/dist/tools/patterns/diffPatterns.d.ts +9 -0
- package/dist/tools/patterns/diffPatterns.d.ts.map +1 -0
- package/dist/tools/patterns/diffPatterns.js +402 -0
- package/dist/tools/patterns/diffPatterns.js.map +1 -0
- package/dist/tools/patterns/executeSkill.d.ts +9 -0
- package/dist/tools/patterns/executeSkill.d.ts.map +1 -0
- package/dist/tools/patterns/executeSkill.js +230 -0
- package/dist/tools/patterns/executeSkill.js.map +1 -0
- package/dist/tools/patterns/findPatterns.d.ts +9 -0
- package/dist/tools/patterns/findPatterns.d.ts.map +1 -0
- package/dist/tools/patterns/findPatterns.js +164 -0
- package/dist/tools/patterns/findPatterns.js.map +1 -0
- package/dist/tools/patterns/getPatternVersions.d.ts +9 -0
- package/dist/tools/patterns/getPatternVersions.d.ts.map +1 -0
- package/dist/tools/patterns/getPatternVersions.js +114 -0
- package/dist/tools/patterns/getPatternVersions.js.map +1 -0
- package/dist/tools/patterns/indexPatternLibrary.d.ts +9 -0
- package/dist/tools/patterns/indexPatternLibrary.d.ts.map +1 -0
- package/dist/tools/patterns/indexPatternLibrary.js +228 -0
- package/dist/tools/patterns/indexPatternLibrary.js.map +1 -0
- package/dist/tools/patterns/loadSkill.d.ts +9 -0
- package/dist/tools/patterns/loadSkill.d.ts.map +1 -0
- package/dist/tools/patterns/loadSkill.js +229 -0
- package/dist/tools/patterns/loadSkill.js.map +1 -0
- package/dist/tools/patterns/predictOutcome.d.ts +9 -0
- package/dist/tools/patterns/predictOutcome.d.ts.map +1 -0
- package/dist/tools/patterns/predictOutcome.js +256 -0
- package/dist/tools/patterns/predictOutcome.js.map +1 -0
- package/dist/tools/patterns/recommendPatterns.d.ts +9 -0
- package/dist/tools/patterns/recommendPatterns.d.ts.map +1 -0
- package/dist/tools/patterns/recommendPatterns.js +278 -0
- package/dist/tools/patterns/recommendPatterns.js.map +1 -0
- package/dist/tools/patterns/searchPatterns.d.ts +9 -0
- package/dist/tools/patterns/searchPatterns.d.ts.map +1 -0
- package/dist/tools/patterns/searchPatterns.js +144 -0
- package/dist/tools/patterns/searchPatterns.js.map +1 -0
- package/dist/tools/patterns/signPattern.d.ts +9 -0
- package/dist/tools/patterns/signPattern.d.ts.map +1 -0
- package/dist/tools/patterns/signPattern.js +147 -0
- package/dist/tools/patterns/signPattern.js.map +1 -0
- package/dist/tools/patterns/trackPatternUsage.d.ts +9 -0
- package/dist/tools/patterns/trackPatternUsage.d.ts.map +1 -0
- package/dist/tools/patterns/trackPatternUsage.js +126 -0
- package/dist/tools/patterns/trackPatternUsage.js.map +1 -0
- package/dist/tools/research/approveResearchPlan.d.ts +9 -0
- package/dist/tools/research/approveResearchPlan.d.ts.map +1 -0
- package/dist/tools/research/approveResearchPlan.js +204 -0
- package/dist/tools/research/approveResearchPlan.js.map +1 -0
- package/dist/tools/research/generateResearchPlan.d.ts +9 -0
- package/dist/tools/research/generateResearchPlan.d.ts.map +1 -0
- package/dist/tools/research/generateResearchPlan.js +347 -0
- package/dist/tools/research/generateResearchPlan.js.map +1 -0
- package/dist/tools/research/listResearchSessions.d.ts +9 -0
- package/dist/tools/research/listResearchSessions.d.ts.map +1 -0
- package/dist/tools/research/listResearchSessions.js +108 -0
- package/dist/tools/research/listResearchSessions.js.map +1 -0
- package/dist/tools/research/suggestModelForResearch.d.ts +9 -0
- package/dist/tools/research/suggestModelForResearch.d.ts.map +1 -0
- package/dist/tools/research/suggestModelForResearch.js +416 -0
- package/dist/tools/research/suggestModelForResearch.js.map +1 -0
- package/dist/tools/research/trackResearchProgress.d.ts +9 -0
- package/dist/tools/research/trackResearchProgress.d.ts.map +1 -0
- package/dist/tools/research/trackResearchProgress.js +177 -0
- package/dist/tools/research/trackResearchProgress.js.map +1 -0
- package/dist/tools/rlvr/rlvrExecute.d.ts +9 -0
- package/dist/tools/rlvr/rlvrExecute.d.ts.map +1 -0
- package/dist/tools/rlvr/rlvrExecute.js +296 -0
- package/dist/tools/rlvr/rlvrExecute.js.map +1 -0
- package/dist/tools/search/getSearchStats.d.ts +9 -0
- package/dist/tools/search/getSearchStats.d.ts.map +1 -0
- package/dist/tools/search/getSearchStats.js +107 -0
- package/dist/tools/search/getSearchStats.js.map +1 -0
- package/dist/tools/search/index.d.ts +4 -0
- package/dist/tools/search/index.d.ts.map +1 -0
- package/dist/tools/search/index.js +4 -0
- package/dist/tools/search/index.js.map +1 -0
- package/dist/tools/search/indexSession.d.ts +9 -0
- package/dist/tools/search/indexSession.d.ts.map +1 -0
- package/dist/tools/search/indexSession.js +254 -0
- package/dist/tools/search/indexSession.js.map +1 -0
- package/dist/tools/search/semanticSearch.d.ts +9 -0
- package/dist/tools/search/semanticSearch.d.ts.map +1 -0
- package/dist/tools/search/semanticSearch.js +171 -0
- package/dist/tools/search/semanticSearch.js.map +1 -0
- package/dist/tools/session/askSession.d.ts +9 -0
- package/dist/tools/session/askSession.d.ts.map +1 -0
- package/dist/tools/session/askSession.js +311 -0
- package/dist/tools/session/askSession.js.map +1 -0
- package/dist/tools/session/checkClaimConsistency.d.ts +9 -0
- package/dist/tools/session/checkClaimConsistency.d.ts.map +1 -0
- package/dist/tools/session/checkClaimConsistency.js +343 -0
- package/dist/tools/session/checkClaimConsistency.js.map +1 -0
- package/dist/tools/session/checkCodeFeasibility.d.ts +19 -0
- package/dist/tools/session/checkCodeFeasibility.d.ts.map +1 -0
- package/dist/tools/session/checkCodeFeasibility.js +766 -0
- package/dist/tools/session/checkCodeFeasibility.js.map +1 -0
- package/dist/tools/session/checkConstraintViolation.d.ts +9 -0
- package/dist/tools/session/checkConstraintViolation.d.ts.map +1 -0
- package/dist/tools/session/checkConstraintViolation.js +98 -0
- package/dist/tools/session/checkConstraintViolation.js.map +1 -0
- package/dist/tools/session/checkDuplicateWork.d.ts +9 -0
- package/dist/tools/session/checkDuplicateWork.d.ts.map +1 -0
- package/dist/tools/session/checkDuplicateWork.js +105 -0
- package/dist/tools/session/checkDuplicateWork.js.map +1 -0
- package/dist/tools/session/extractSessionMemories.d.ts +9 -0
- package/dist/tools/session/extractSessionMemories.d.ts.map +1 -0
- package/dist/tools/session/extractSessionMemories.js +203 -0
- package/dist/tools/session/extractSessionMemories.js.map +1 -0
- package/dist/tools/session/finalizeSessionCoordination.d.ts +9 -0
- package/dist/tools/session/finalizeSessionCoordination.d.ts.map +1 -0
- package/dist/tools/session/finalizeSessionCoordination.js +85 -0
- package/dist/tools/session/finalizeSessionCoordination.js.map +1 -0
- package/dist/tools/session/flagForVerification.d.ts +17 -0
- package/dist/tools/session/flagForVerification.d.ts.map +1 -0
- package/dist/tools/session/flagForVerification.js +232 -0
- package/dist/tools/session/flagForVerification.js.map +1 -0
- package/dist/tools/session/getConstraints.d.ts +9 -0
- package/dist/tools/session/getConstraints.d.ts.map +1 -0
- package/dist/tools/session/getConstraints.js +84 -0
- package/dist/tools/session/getConstraints.js.map +1 -0
- package/dist/tools/session/getSessionStats.d.ts +9 -0
- package/dist/tools/session/getSessionStats.d.ts.map +1 -0
- package/dist/tools/session/getSessionStats.js +86 -0
- package/dist/tools/session/getSessionStats.js.map +1 -0
- package/dist/tools/session/getSessionSummary.d.ts +9 -0
- package/dist/tools/session/getSessionSummary.d.ts.map +1 -0
- package/dist/tools/session/getSessionSummary.js +360 -0
- package/dist/tools/session/getSessionSummary.js.map +1 -0
- package/dist/tools/session/getVerificationPrompt.d.ts +9 -0
- package/dist/tools/session/getVerificationPrompt.d.ts.map +1 -0
- package/dist/tools/session/getVerificationPrompt.js +210 -0
- package/dist/tools/session/getVerificationPrompt.js.map +1 -0
- package/dist/tools/session/liftConstraint.d.ts +9 -0
- package/dist/tools/session/liftConstraint.d.ts.map +1 -0
- package/dist/tools/session/liftConstraint.js +94 -0
- package/dist/tools/session/liftConstraint.js.map +1 -0
- package/dist/tools/session/recordVerificationOutcome.d.ts +24 -0
- package/dist/tools/session/recordVerificationOutcome.d.ts.map +1 -0
- package/dist/tools/session/recordVerificationOutcome.js +237 -0
- package/dist/tools/session/recordVerificationOutcome.js.map +1 -0
- package/dist/tools/session/saveSessionNote.d.ts +9 -0
- package/dist/tools/session/saveSessionNote.d.ts.map +1 -0
- package/dist/tools/session/saveSessionNote.js +213 -0
- package/dist/tools/session/saveSessionNote.js.map +1 -0
- package/dist/tools/session/sessionSearch.d.ts +9 -0
- package/dist/tools/session/sessionSearch.d.ts.map +1 -0
- package/dist/tools/session/sessionSearch.js +116 -0
- package/dist/tools/session/sessionSearch.js.map +1 -0
- package/dist/tools/session/startSessionCoordination.d.ts +13 -0
- package/dist/tools/session/startSessionCoordination.d.ts.map +1 -0
- package/dist/tools/session/startSessionCoordination.js +126 -0
- package/dist/tools/session/startSessionCoordination.js.map +1 -0
- package/dist/tools/session/trackApprovalFingerprint.d.ts +19 -0
- package/dist/tools/session/trackApprovalFingerprint.d.ts.map +1 -0
- package/dist/tools/session/trackApprovalFingerprint.js +172 -0
- package/dist/tools/session/trackApprovalFingerprint.js.map +1 -0
- package/dist/tools/session/trackConstraint.d.ts +9 -0
- package/dist/tools/session/trackConstraint.d.ts.map +1 -0
- package/dist/tools/session/trackConstraint.js +101 -0
- package/dist/tools/session/trackConstraint.js.map +1 -0
- package/dist/tools/session/validateCitation.d.ts +9 -0
- package/dist/tools/session/validateCitation.d.ts.map +1 -0
- package/dist/tools/session/validateCitation.js +450 -0
- package/dist/tools/session/validateCitation.js.map +1 -0
- package/dist/tools/stuck/checkStuckPattern.d.ts +9 -0
- package/dist/tools/stuck/checkStuckPattern.d.ts.map +1 -0
- package/dist/tools/stuck/checkStuckPattern.js +93 -0
- package/dist/tools/stuck/checkStuckPattern.js.map +1 -0
- package/dist/tools/stuck/getRecoverySuggestions.d.ts +9 -0
- package/dist/tools/stuck/getRecoverySuggestions.d.ts.map +1 -0
- package/dist/tools/stuck/getRecoverySuggestions.js +132 -0
- package/dist/tools/stuck/getRecoverySuggestions.js.map +1 -0
- package/dist/types/research.d.ts +76 -0
- package/dist/types/research.d.ts.map +1 -0
- package/dist/types/research.js +2 -0
- package/dist/types/research.js.map +1 -0
- package/dist/types/temporal-graph.d.ts +97 -0
- package/dist/types/temporal-graph.d.ts.map +1 -0
- package/dist/types/temporal-graph.js +2 -0
- package/dist/types/temporal-graph.js.map +1 -0
- package/dist/utils/AuditLogger.d.ts +99 -0
- package/dist/utils/AuditLogger.d.ts.map +1 -0
- package/dist/utils/AuditLogger.js +303 -0
- package/dist/utils/AuditLogger.js.map +1 -0
- package/dist/utils/CacheManager.d.ts +56 -0
- package/dist/utils/CacheManager.d.ts.map +1 -0
- package/dist/utils/CacheManager.js +184 -0
- package/dist/utils/CacheManager.js.map +1 -0
- package/dist/utils/CircuitBreaker.d.ts +76 -0
- package/dist/utils/CircuitBreaker.d.ts.map +1 -0
- package/dist/utils/CircuitBreaker.js +236 -0
- package/dist/utils/CircuitBreaker.js.map +1 -0
- package/dist/utils/CostTracker.d.ts +83 -0
- package/dist/utils/CostTracker.d.ts.map +1 -0
- package/dist/utils/CostTracker.js +228 -0
- package/dist/utils/CostTracker.js.map +1 -0
- package/dist/utils/DockerSandbox.d.ts +39 -0
- package/dist/utils/DockerSandbox.d.ts.map +1 -0
- package/dist/utils/DockerSandbox.js +277 -0
- package/dist/utils/DockerSandbox.js.map +1 -0
- package/dist/utils/FinalizationCompressor.d.ts +70 -0
- package/dist/utils/FinalizationCompressor.d.ts.map +1 -0
- package/dist/utils/FinalizationCompressor.js +295 -0
- package/dist/utils/FinalizationCompressor.js.map +1 -0
- package/dist/utils/MetaKnowledgeManager.d.ts +63 -0
- package/dist/utils/MetaKnowledgeManager.d.ts.map +1 -0
- package/dist/utils/MetaKnowledgeManager.js +152 -0
- package/dist/utils/MetaKnowledgeManager.js.map +1 -0
- package/dist/utils/PatternIndexer.d.ts +83 -0
- package/dist/utils/PatternIndexer.d.ts.map +1 -0
- package/dist/utils/PatternIndexer.js +730 -0
- package/dist/utils/PatternIndexer.js.map +1 -0
- package/dist/utils/PatternUsageTracker.d.ts +97 -0
- package/dist/utils/PatternUsageTracker.d.ts.map +1 -0
- package/dist/utils/PatternUsageTracker.js +352 -0
- package/dist/utils/PatternUsageTracker.js.map +1 -0
- package/dist/utils/PatternVerifier.d.ts +71 -0
- package/dist/utils/PatternVerifier.d.ts.map +1 -0
- package/dist/utils/PatternVerifier.js +328 -0
- package/dist/utils/PatternVerifier.js.map +1 -0
- package/dist/utils/PatternVersionManager.d.ts +47 -0
- package/dist/utils/PatternVersionManager.d.ts.map +1 -0
- package/dist/utils/PatternVersionManager.js +308 -0
- package/dist/utils/PatternVersionManager.js.map +1 -0
- package/dist/utils/QdrantConnectionManager.d.ts +47 -0
- package/dist/utils/QdrantConnectionManager.d.ts.map +1 -0
- package/dist/utils/QdrantConnectionManager.js +228 -0
- package/dist/utils/QdrantConnectionManager.js.map +1 -0
- package/dist/utils/RateLimiter.d.ts +85 -0
- package/dist/utils/RateLimiter.d.ts.map +1 -0
- package/dist/utils/RateLimiter.js +300 -0
- package/dist/utils/RateLimiter.js.map +1 -0
- package/dist/utils/RecoveryEngine.d.ts +45 -0
- package/dist/utils/RecoveryEngine.d.ts.map +1 -0
- package/dist/utils/RecoveryEngine.js +268 -0
- package/dist/utils/RecoveryEngine.js.map +1 -0
- package/dist/utils/ResearchCoordinator.d.ts +30 -0
- package/dist/utils/ResearchCoordinator.d.ts.map +1 -0
- package/dist/utils/ResearchCoordinator.js +197 -0
- package/dist/utils/ResearchCoordinator.js.map +1 -0
- package/dist/utils/SessionCoordinator.d.ts +111 -0
- package/dist/utils/SessionCoordinator.d.ts.map +1 -0
- package/dist/utils/SessionCoordinator.js +1062 -0
- package/dist/utils/SessionCoordinator.js.map +1 -0
- package/dist/utils/SkillExecutor.d.ts +50 -0
- package/dist/utils/SkillExecutor.d.ts.map +1 -0
- package/dist/utils/SkillExecutor.js +396 -0
- package/dist/utils/SkillExecutor.js.map +1 -0
- package/dist/utils/StuckDetector.d.ts +43 -0
- package/dist/utils/StuckDetector.d.ts.map +1 -0
- package/dist/utils/StuckDetector.js +336 -0
- package/dist/utils/StuckDetector.js.map +1 -0
- package/dist/utils/TemporalGraphIndex.d.ts +33 -0
- package/dist/utils/TemporalGraphIndex.d.ts.map +1 -0
- package/dist/utils/TemporalGraphIndex.js +218 -0
- package/dist/utils/TemporalGraphIndex.js.map +1 -0
- package/dist/utils/artifacts.d.ts +35 -0
- package/dist/utils/artifacts.d.ts.map +1 -0
- package/dist/utils/artifacts.js +294 -0
- package/dist/utils/artifacts.js.map +1 -0
- package/dist/utils/consensusAggregator.d.ts +50 -0
- package/dist/utils/consensusAggregator.d.ts.map +1 -0
- package/dist/utils/consensusAggregator.js +195 -0
- package/dist/utils/consensusAggregator.js.map +1 -0
- package/dist/utils/contextBuilder.d.ts +58 -0
- package/dist/utils/contextBuilder.d.ts.map +1 -0
- package/dist/utils/contextBuilder.js +221 -0
- package/dist/utils/contextBuilder.js.map +1 -0
- package/dist/utils/costPricing.d.ts +11 -0
- package/dist/utils/costPricing.d.ts.map +1 -0
- package/dist/utils/costPricing.js +86 -0
- package/dist/utils/costPricing.js.map +1 -0
- package/dist/utils/filesystem.d.ts +16 -0
- package/dist/utils/filesystem.d.ts.map +1 -0
- package/dist/utils/filesystem.js +184 -0
- package/dist/utils/filesystem.js.map +1 -0
- package/dist/utils/llmStreamClient.d.ts +41 -0
- package/dist/utils/llmStreamClient.d.ts.map +1 -0
- package/dist/utils/llmStreamClient.js +257 -0
- package/dist/utils/llmStreamClient.js.map +1 -0
- package/dist/utils/memory.d.ts +22 -0
- package/dist/utils/memory.d.ts.map +1 -0
- package/dist/utils/memory.js +67 -0
- package/dist/utils/memory.js.map +1 -0
- package/dist/utils/memoryBank.d.ts +18 -0
- package/dist/utils/memoryBank.d.ts.map +1 -0
- package/dist/utils/memoryBank.js +128 -0
- package/dist/utils/memoryBank.js.map +1 -0
- package/dist/utils/metrics.d.ts +30 -0
- package/dist/utils/metrics.d.ts.map +1 -0
- package/dist/utils/metrics.js +208 -0
- package/dist/utils/metrics.js.map +1 -0
- package/dist/utils/pythonRunner.d.ts +7 -0
- package/dist/utils/pythonRunner.d.ts.map +1 -0
- package/dist/utils/pythonRunner.js +72 -0
- package/dist/utils/pythonRunner.js.map +1 -0
- package/dist/utils/responseParser.d.ts +15 -0
- package/dist/utils/responseParser.d.ts.map +1 -0
- package/dist/utils/responseParser.js +306 -0
- package/dist/utils/responseParser.js.map +1 -0
- package/dist/utils/rlvr/PythonSandbox.d.ts +16 -0
- package/dist/utils/rlvr/PythonSandbox.d.ts.map +1 -0
- package/dist/utils/rlvr/PythonSandbox.js +203 -0
- package/dist/utils/rlvr/PythonSandbox.js.map +1 -0
- package/dist/utils/rlvr/RewardComputer.d.ts +28 -0
- package/dist/utils/rlvr/RewardComputer.d.ts.map +1 -0
- package/dist/utils/rlvr/RewardComputer.js +227 -0
- package/dist/utils/rlvr/RewardComputer.js.map +1 -0
- package/dist/utils/rlvr/RewardHistoryStore.d.ts +48 -0
- package/dist/utils/rlvr/RewardHistoryStore.d.ts.map +1 -0
- package/dist/utils/rlvr/RewardHistoryStore.js +428 -0
- package/dist/utils/rlvr/RewardHistoryStore.js.map +1 -0
- package/dist/utils/rlvr/SQLSandbox.d.ts +21 -0
- package/dist/utils/rlvr/SQLSandbox.d.ts.map +1 -0
- package/dist/utils/rlvr/SQLSandbox.js +199 -0
- package/dist/utils/rlvr/SQLSandbox.js.map +1 -0
- package/dist/utils/rlvr/TestGenerator.d.ts +8 -0
- package/dist/utils/rlvr/TestGenerator.d.ts.map +1 -0
- package/dist/utils/rlvr/TestGenerator.js +216 -0
- package/dist/utils/rlvr/TestGenerator.js.map +1 -0
- package/dist/utils/rlvr/TestOrchestrator.d.ts +45 -0
- package/dist/utils/rlvr/TestOrchestrator.d.ts.map +1 -0
- package/dist/utils/rlvr/TestOrchestrator.js +331 -0
- package/dist/utils/rlvr/TestOrchestrator.js.map +1 -0
- package/dist/utils/rlvr/TypeScriptSandbox.d.ts +16 -0
- package/dist/utils/rlvr/TypeScriptSandbox.d.ts.map +1 -0
- package/dist/utils/rlvr/TypeScriptSandbox.js +244 -0
- package/dist/utils/rlvr/TypeScriptSandbox.js.map +1 -0
- package/dist/utils/rlvr/index.d.ts +9 -0
- package/dist/utils/rlvr/index.d.ts.map +1 -0
- package/dist/utils/rlvr/index.js +9 -0
- package/dist/utils/rlvr/index.js.map +1 -0
- package/dist/utils/rlvr/python_executor.py +309 -0
- package/dist/utils/rlvr/sql_executor.py +233 -0
- package/dist/utils/rlvr/test-orchestrator.d.ts +2 -0
- package/dist/utils/rlvr/test-orchestrator.d.ts.map +1 -0
- package/dist/utils/rlvr/test-orchestrator.js +200 -0
- package/dist/utils/rlvr/test-orchestrator.js.map +1 -0
- package/dist/utils/rlvr/test-persistence.d.ts +2 -0
- package/dist/utils/rlvr/test-persistence.d.ts.map +1 -0
- package/dist/utils/rlvr/test-persistence.js +175 -0
- package/dist/utils/rlvr/test-persistence.js.map +1 -0
- package/dist/utils/rlvr/test-rlvr.d.ts +2 -0
- package/dist/utils/rlvr/test-rlvr.d.ts.map +1 -0
- package/dist/utils/rlvr/test-rlvr.js +286 -0
- package/dist/utils/rlvr/test-rlvr.js.map +1 -0
- package/dist/utils/rlvr/test-sql.d.ts +2 -0
- package/dist/utils/rlvr/test-sql.d.ts.map +1 -0
- package/dist/utils/rlvr/test-sql.js +63 -0
- package/dist/utils/rlvr/test-sql.js.map +1 -0
- package/dist/utils/rlvr/types.d.ts +133 -0
- package/dist/utils/rlvr/types.d.ts.map +1 -0
- package/dist/utils/rlvr/types.js +8 -0
- package/dist/utils/rlvr/types.js.map +1 -0
- package/dist/utils/tokenEstimator.d.ts +4 -0
- package/dist/utils/tokenEstimator.d.ts.map +1 -0
- package/dist/utils/tokenEstimator.js +14 -0
- package/dist/utils/tokenEstimator.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,1062 @@
|
|
|
1
|
+
import { QdrantClient } from "@qdrant/js-client-rest";
|
|
2
|
+
import { GoogleGenAI } from "@google/genai";
|
|
3
|
+
import { readFile } from "fs/promises";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { homedir } from "os";
|
|
6
|
+
import { embeddingCache, embeddingCacheKey, } from "./CacheManager.js";
|
|
7
|
+
import { withExternalSpan } from "../telemetry/index.js";
|
|
8
|
+
import { getCostTracker } from "./CostTracker.js";
|
|
9
|
+
import { ServiceCircuitBreakers } from "./CircuitBreaker.js";
|
|
10
|
+
import { ServiceRateLimiters } from "./RateLimiter.js";
|
|
11
|
+
export class SessionCoordinator {
|
|
12
|
+
qdrant;
|
|
13
|
+
genai;
|
|
14
|
+
sessionId;
|
|
15
|
+
projectPath;
|
|
16
|
+
collectionName;
|
|
17
|
+
constructor(sessionId, projectPath) {
|
|
18
|
+
const qdrantUrl = process.env.QDRANT_URL;
|
|
19
|
+
const qdrantApiKey = process.env.QDRANT_API_KEY;
|
|
20
|
+
const geminiApiKey = process.env.GEMINI_API_KEY;
|
|
21
|
+
console.error("[SessionCoordinator] Environment check:", {
|
|
22
|
+
hasQdrantUrl: !!qdrantUrl,
|
|
23
|
+
hasQdrantApiKey: !!qdrantApiKey,
|
|
24
|
+
hasGeminiKey: !!geminiApiKey,
|
|
25
|
+
qdrantUrlLength: qdrantUrl?.length || 0,
|
|
26
|
+
allEnvKeys: Object.keys(process.env).filter((k) => k.includes("QDRANT") || k.includes("GEMINI")),
|
|
27
|
+
});
|
|
28
|
+
if (!qdrantUrl || !qdrantApiKey) {
|
|
29
|
+
throw new Error("Missing QDRANT_URL or QDRANT_API_KEY environment variables");
|
|
30
|
+
}
|
|
31
|
+
if (!geminiApiKey) {
|
|
32
|
+
throw new Error("Missing GEMINI_API_KEY environment variable");
|
|
33
|
+
}
|
|
34
|
+
this.sessionId = sessionId;
|
|
35
|
+
this.projectPath = projectPath;
|
|
36
|
+
const projectName = projectPath.split("/").pop() || "default";
|
|
37
|
+
this.collectionName = `session-${projectName}-${sessionId}`;
|
|
38
|
+
this.qdrant = new QdrantClient({
|
|
39
|
+
url: qdrantUrl,
|
|
40
|
+
apiKey: qdrantApiKey,
|
|
41
|
+
});
|
|
42
|
+
this.genai = new GoogleGenAI({ apiKey: geminiApiKey });
|
|
43
|
+
}
|
|
44
|
+
async withQdrantCircuitBreaker(operation) {
|
|
45
|
+
const rateLimiter = ServiceRateLimiters.qdrant();
|
|
46
|
+
await rateLimiter.acquire(1);
|
|
47
|
+
const qdrantBreaker = ServiceCircuitBreakers.qdrant();
|
|
48
|
+
return qdrantBreaker.execute(operation);
|
|
49
|
+
}
|
|
50
|
+
async initialize(seedTopic) {
|
|
51
|
+
const result = {};
|
|
52
|
+
try {
|
|
53
|
+
const collections = await this.withQdrantCircuitBreaker(() => this.qdrant.getCollections());
|
|
54
|
+
const exists = collections.collections.some((c) => c.name === this.collectionName);
|
|
55
|
+
if (exists) {
|
|
56
|
+
console.error(`📦 Session collection already exists: ${this.collectionName}`);
|
|
57
|
+
await this.ensurePayloadIndex();
|
|
58
|
+
if (seedTopic) {
|
|
59
|
+
result.memoryBankSeeding = await this.seedFromMemoryBank(seedTopic);
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
await this.withQdrantCircuitBreaker(() => this.qdrant.createCollection(this.collectionName, {
|
|
64
|
+
vectors: {
|
|
65
|
+
size: 3072,
|
|
66
|
+
distance: "Cosine",
|
|
67
|
+
},
|
|
68
|
+
}));
|
|
69
|
+
console.error(`✅ Session collection created: ${this.collectionName}`);
|
|
70
|
+
await this.ensurePayloadIndex();
|
|
71
|
+
if (seedTopic) {
|
|
72
|
+
result.memoryBankSeeding = await this.seedFromMemoryBank(seedTopic);
|
|
73
|
+
}
|
|
74
|
+
await this.seedFromArchive();
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
console.error(`❌ Failed to initialize session: ${error.message}`);
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async ensurePayloadIndex() {
|
|
83
|
+
try {
|
|
84
|
+
await this.qdrant.createPayloadIndex(this.collectionName, {
|
|
85
|
+
field_name: "type",
|
|
86
|
+
field_schema: "keyword",
|
|
87
|
+
});
|
|
88
|
+
console.error(`✅ Created payload index on 'type' field`);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
if (error.message?.includes("already exists")) {
|
|
92
|
+
console.error(` Payload index already exists (OK)`);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
console.error(`⚠️ Failed to create payload index: ${error.message}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async seedFromMemoryBank(topic) {
|
|
100
|
+
console.error(`🧠 Seeding session from Memory Bank: "${topic}"...`);
|
|
101
|
+
try {
|
|
102
|
+
const projectName = this.projectPath.split("/").pop()?.toLowerCase() || "default";
|
|
103
|
+
const scriptPath = join(homedir(), "Dev/ClaudeDev/scripts/memory-bank/query-memories.py");
|
|
104
|
+
const { runPythonScriptJSON } = await import("./pythonRunner.js");
|
|
105
|
+
const result = await runPythonScriptJSON(scriptPath, [
|
|
106
|
+
"--query",
|
|
107
|
+
topic,
|
|
108
|
+
"--project-name",
|
|
109
|
+
projectName,
|
|
110
|
+
"--top-k",
|
|
111
|
+
"5",
|
|
112
|
+
"--format",
|
|
113
|
+
"json",
|
|
114
|
+
]);
|
|
115
|
+
if (!result.success || !result.memories || result.memories.length === 0) {
|
|
116
|
+
console.error(` ℹ️ No Memory Bank results for "${topic}" in project "${projectName}"`);
|
|
117
|
+
return { query: topic, count: 0 };
|
|
118
|
+
}
|
|
119
|
+
let seededCount = 0;
|
|
120
|
+
for (const memory of result.memories) {
|
|
121
|
+
try {
|
|
122
|
+
await this.saveNote({
|
|
123
|
+
type: "prior_knowledge",
|
|
124
|
+
content: memory.fact,
|
|
125
|
+
metadata: {
|
|
126
|
+
source: "memory_bank",
|
|
127
|
+
source_query: topic,
|
|
128
|
+
memory_name: memory.name,
|
|
129
|
+
similarity_distance: memory.distance,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
seededCount++;
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
console.error(` ⚠️ Failed to save memory: ${error}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
console.error(` ✅ Seeded ${seededCount} memories from Memory Bank`);
|
|
139
|
+
return { query: topic, count: seededCount };
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
console.error(` ⚠️ Memory Bank seeding failed: ${error.message}`);
|
|
143
|
+
return { query: topic, count: 0 };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async seedFromArchive() {
|
|
147
|
+
console.error("🌱 Seeding session with past knowledge...");
|
|
148
|
+
try {
|
|
149
|
+
const geminiApiKey = process.env.GEMINI_API_KEY;
|
|
150
|
+
if (!geminiApiKey) {
|
|
151
|
+
console.error(" ⚠️ GEMINI_API_KEY not set - skipping archive seeding");
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const expandedPath = this.projectPath.replace(/^~/, homedir());
|
|
155
|
+
const configPath = join(expandedPath, ".gemini-config.json");
|
|
156
|
+
let config;
|
|
157
|
+
try {
|
|
158
|
+
const configContent = await readFile(configPath, "utf-8");
|
|
159
|
+
config = JSON.parse(configContent);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
console.error(" ℹ️ No .gemini-config.json found - skipping archive seeding");
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (!config.enabled) {
|
|
166
|
+
console.error(" ℹ️ Google File Search disabled in config - skipping archive seeding");
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const ai = new GoogleGenAI({ apiKey: geminiApiKey });
|
|
170
|
+
const storesResponse = await ai.fileSearchStores.list();
|
|
171
|
+
const stores = [];
|
|
172
|
+
for await (const store of storesResponse) {
|
|
173
|
+
stores.push(store);
|
|
174
|
+
}
|
|
175
|
+
const store = stores.find((s) => s.displayName === config.store_name);
|
|
176
|
+
if (!store) {
|
|
177
|
+
console.error(` ℹ️ File Search store "${config.store_name}" not found - skipping archive seeding`);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const projectName = this.projectPath.split("/").pop() || "project";
|
|
181
|
+
const query = `What are the key decisions, patterns, and learnings from recent sessions in ${projectName}? Focus on architectural decisions, design patterns used, and lessons learned.`;
|
|
182
|
+
console.error(` 🔍 Querying archive for relevant context...`);
|
|
183
|
+
const response = await ai.models.generateContent({
|
|
184
|
+
model: "gemini-2.5-flash",
|
|
185
|
+
contents: query,
|
|
186
|
+
config: {
|
|
187
|
+
tools: [
|
|
188
|
+
{
|
|
189
|
+
fileSearch: {
|
|
190
|
+
fileSearchStoreNames: [store.name],
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
const answer = response.text || "";
|
|
197
|
+
const groundingChunks = response.candidates?.[0]?.groundingMetadata?.groundingChunks || [];
|
|
198
|
+
if (!answer || answer.length < 50) {
|
|
199
|
+
console.error(" ℹ️ No relevant archive content found");
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const sessionIds = groundingChunks
|
|
203
|
+
.map((chunk) => {
|
|
204
|
+
const source = chunk.uri || "";
|
|
205
|
+
const match = source.match(/([^/]+?)(?:-compressed)?\.(?:json|md)$/);
|
|
206
|
+
return match
|
|
207
|
+
? match[1].replace(/-(?:finalization-pack|session-summary|compressed)$/, "")
|
|
208
|
+
: null;
|
|
209
|
+
})
|
|
210
|
+
.filter((id) => id !== null)
|
|
211
|
+
.slice(0, 3);
|
|
212
|
+
const insights = this.extractInsightsFromAnswer(answer);
|
|
213
|
+
let seededCount = 0;
|
|
214
|
+
for (const insight of insights.slice(0, 5)) {
|
|
215
|
+
try {
|
|
216
|
+
await this.saveNote({
|
|
217
|
+
type: "prior_knowledge",
|
|
218
|
+
content: insight.content,
|
|
219
|
+
metadata: {
|
|
220
|
+
source: "archive_seeding",
|
|
221
|
+
source_sessions: sessionIds,
|
|
222
|
+
insight_type: insight.type,
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
seededCount++;
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
console.error(` ⚠️ Failed to save insight: ${error}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
console.error(` ✅ Seeded ${seededCount} prior knowledge items from ${sessionIds.length} sessions`);
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
console.error(` ⚠️ Archive seeding failed: ${error.message}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
extractInsightsFromAnswer(answer) {
|
|
238
|
+
const insights = [];
|
|
239
|
+
const segments = answer.split(/(?<=[.!?])\s+/).filter((s) => s.length > 20);
|
|
240
|
+
for (const segment of segments) {
|
|
241
|
+
const lowerSegment = segment.toLowerCase();
|
|
242
|
+
let type = "general";
|
|
243
|
+
if (lowerSegment.includes("decided") ||
|
|
244
|
+
lowerSegment.includes("decision") ||
|
|
245
|
+
lowerSegment.includes("chose")) {
|
|
246
|
+
type = "decision";
|
|
247
|
+
}
|
|
248
|
+
else if (lowerSegment.includes("pattern") ||
|
|
249
|
+
lowerSegment.includes("approach")) {
|
|
250
|
+
type = "pattern";
|
|
251
|
+
}
|
|
252
|
+
else if (lowerSegment.includes("learned") ||
|
|
253
|
+
lowerSegment.includes("lesson") ||
|
|
254
|
+
lowerSegment.includes("discovered")) {
|
|
255
|
+
type = "learning";
|
|
256
|
+
}
|
|
257
|
+
else if (lowerSegment.includes("implemented") ||
|
|
258
|
+
lowerSegment.includes("created") ||
|
|
259
|
+
lowerSegment.includes("added")) {
|
|
260
|
+
type = "implementation";
|
|
261
|
+
}
|
|
262
|
+
if (segment.length >= 30 && segment.length <= 300) {
|
|
263
|
+
insights.push({ type, content: segment.trim() });
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const unique = [];
|
|
267
|
+
for (const insight of insights) {
|
|
268
|
+
const isDuplicate = unique.some((u) => u.content
|
|
269
|
+
.toLowerCase()
|
|
270
|
+
.includes(insight.content.toLowerCase().slice(0, 30)) ||
|
|
271
|
+
insight.content
|
|
272
|
+
.toLowerCase()
|
|
273
|
+
.includes(u.content.toLowerCase().slice(0, 30)));
|
|
274
|
+
if (!isDuplicate) {
|
|
275
|
+
unique.push(insight);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return unique;
|
|
279
|
+
}
|
|
280
|
+
async saveNote(note) {
|
|
281
|
+
try {
|
|
282
|
+
const embedding = await this.generateEmbedding(note.content);
|
|
283
|
+
const pointId = Date.now() * 1000 + Math.floor(Math.random() * 1000);
|
|
284
|
+
await withExternalSpan("qdrant", {
|
|
285
|
+
operation: "upsert",
|
|
286
|
+
collection: this.collectionName,
|
|
287
|
+
}, async (span) => {
|
|
288
|
+
span.setAttribute("service.note_type", note.type);
|
|
289
|
+
span.setAttribute("service.content_length", note.content.length);
|
|
290
|
+
await this.withQdrantCircuitBreaker(() => this.qdrant.upsert(this.collectionName, {
|
|
291
|
+
points: [
|
|
292
|
+
{
|
|
293
|
+
id: pointId,
|
|
294
|
+
vector: embedding,
|
|
295
|
+
payload: {
|
|
296
|
+
type: note.type,
|
|
297
|
+
content: note.content,
|
|
298
|
+
timestamp: new Date().toISOString(),
|
|
299
|
+
session_id: this.sessionId,
|
|
300
|
+
project_path: this.projectPath,
|
|
301
|
+
...note.metadata,
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
],
|
|
305
|
+
}));
|
|
306
|
+
});
|
|
307
|
+
console.error(`📝 Saved ${note.type}: ${note.content.slice(0, 60)}${note.content.length > 60 ? "..." : ""}`);
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
console.error(`❌ Failed to save note: ${error.message}`);
|
|
311
|
+
throw error;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
async search(query, limit = 5) {
|
|
315
|
+
try {
|
|
316
|
+
const embedding = await this.generateEmbedding(query);
|
|
317
|
+
const results = await withExternalSpan("qdrant", {
|
|
318
|
+
operation: "search",
|
|
319
|
+
collection: this.collectionName,
|
|
320
|
+
}, async (span) => {
|
|
321
|
+
const searchResults = await this.withQdrantCircuitBreaker(() => this.qdrant.search(this.collectionName, {
|
|
322
|
+
vector: embedding,
|
|
323
|
+
limit,
|
|
324
|
+
with_payload: true,
|
|
325
|
+
}));
|
|
326
|
+
span.setAttribute("service.result_count", searchResults.length);
|
|
327
|
+
return searchResults;
|
|
328
|
+
});
|
|
329
|
+
return results.map((r) => ({
|
|
330
|
+
score: r.score || 0,
|
|
331
|
+
type: r.payload?.type || "unknown",
|
|
332
|
+
content: r.payload?.content || "",
|
|
333
|
+
timestamp: r.payload?.timestamp || "",
|
|
334
|
+
metadata: r.payload,
|
|
335
|
+
}));
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
console.error(`❌ Search failed: ${error.message}`);
|
|
339
|
+
return [];
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
async checkDuplicate(description, threshold = 0.75) {
|
|
343
|
+
const results = await this.search(description, 5);
|
|
344
|
+
const duplicates = results.filter((r) => r.score >= threshold);
|
|
345
|
+
if (duplicates.length > 0) {
|
|
346
|
+
console.error(`⚠️ Found ${duplicates.length} potential duplicate(s):`);
|
|
347
|
+
duplicates.forEach((dup, i) => {
|
|
348
|
+
console.error(` ${i + 1}. [${(dup.score * 100).toFixed(1)}% similar] ${dup.content.slice(0, 60)}...`);
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
return duplicates;
|
|
352
|
+
}
|
|
353
|
+
async getNotesByType(type) {
|
|
354
|
+
try {
|
|
355
|
+
const result = await this.qdrant.scroll(this.collectionName, {
|
|
356
|
+
limit: 100,
|
|
357
|
+
with_payload: true,
|
|
358
|
+
with_vector: false,
|
|
359
|
+
filter: {
|
|
360
|
+
must: [
|
|
361
|
+
{
|
|
362
|
+
key: "type",
|
|
363
|
+
match: { value: type },
|
|
364
|
+
},
|
|
365
|
+
],
|
|
366
|
+
},
|
|
367
|
+
});
|
|
368
|
+
const points = result.points || [];
|
|
369
|
+
return points.map((point) => ({
|
|
370
|
+
score: 1.0,
|
|
371
|
+
type: point.payload?.type || "unknown",
|
|
372
|
+
content: point.payload?.content || "",
|
|
373
|
+
timestamp: point.payload?.timestamp || "",
|
|
374
|
+
metadata: point.payload,
|
|
375
|
+
}));
|
|
376
|
+
}
|
|
377
|
+
catch (error) {
|
|
378
|
+
console.error(`❌ Failed to get notes by type: ${error.message}`);
|
|
379
|
+
return [];
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
async extractValuableMemories() {
|
|
383
|
+
console.error("💎 Extracting high-value memories...");
|
|
384
|
+
const allTypes = [
|
|
385
|
+
"decision",
|
|
386
|
+
"hypothesis",
|
|
387
|
+
"blocker",
|
|
388
|
+
"learning",
|
|
389
|
+
"pattern",
|
|
390
|
+
"finding",
|
|
391
|
+
"prior_knowledge",
|
|
392
|
+
"decision_point",
|
|
393
|
+
"branch",
|
|
394
|
+
];
|
|
395
|
+
const allNotes = [];
|
|
396
|
+
for (const type of allTypes) {
|
|
397
|
+
const notes = await this.getNotesByType(type);
|
|
398
|
+
allNotes.push(...notes);
|
|
399
|
+
}
|
|
400
|
+
allNotes.sort((a, b) => {
|
|
401
|
+
return new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();
|
|
402
|
+
});
|
|
403
|
+
console.error(` Found ${allNotes.length} total notes`);
|
|
404
|
+
return allNotes;
|
|
405
|
+
}
|
|
406
|
+
async cleanup() {
|
|
407
|
+
try {
|
|
408
|
+
await this.qdrant.deleteCollection(this.collectionName);
|
|
409
|
+
console.error(`🗑️ Cleaned up session collection: ${this.collectionName}`);
|
|
410
|
+
}
|
|
411
|
+
catch (error) {
|
|
412
|
+
if (error.message?.includes("Not found")) {
|
|
413
|
+
console.error(`ℹ️ Session collection already removed: ${this.collectionName}`);
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
console.error(`⚠️ Failed to cleanup session: ${error.message}`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
async generateEmbedding(text) {
|
|
421
|
+
const MODEL = "gemini-embedding-001";
|
|
422
|
+
const DIMENSIONS = 3072;
|
|
423
|
+
const truncatedText = text.slice(0, 8000);
|
|
424
|
+
const cacheKey = embeddingCacheKey(truncatedText, MODEL);
|
|
425
|
+
const cached = embeddingCache.get(cacheKey);
|
|
426
|
+
if (cached) {
|
|
427
|
+
console.error(` 📦 Embedding cache hit`);
|
|
428
|
+
return cached.embedding;
|
|
429
|
+
}
|
|
430
|
+
const rateLimiter = ServiceRateLimiters.gemini();
|
|
431
|
+
await rateLimiter.acquire(1);
|
|
432
|
+
const geminiBreaker = ServiceCircuitBreakers.gemini();
|
|
433
|
+
return geminiBreaker.execute(async () => {
|
|
434
|
+
return withExternalSpan("gemini", {
|
|
435
|
+
operation: "embedding",
|
|
436
|
+
model: MODEL,
|
|
437
|
+
}, async (span) => {
|
|
438
|
+
try {
|
|
439
|
+
const response = await this.genai.models.embedContent({
|
|
440
|
+
model: MODEL,
|
|
441
|
+
contents: truncatedText,
|
|
442
|
+
config: {
|
|
443
|
+
outputDimensionality: DIMENSIONS,
|
|
444
|
+
},
|
|
445
|
+
});
|
|
446
|
+
const embedding = response.embeddings?.[0]?.values;
|
|
447
|
+
if (!embedding) {
|
|
448
|
+
throw new Error("No embedding returned from Gemini");
|
|
449
|
+
}
|
|
450
|
+
span.setAttribute("service.input_chars", truncatedText.length);
|
|
451
|
+
span.setAttribute("service.dimensions", embedding.length);
|
|
452
|
+
const cacheEntry = {
|
|
453
|
+
embedding,
|
|
454
|
+
model: MODEL,
|
|
455
|
+
dimensions: embedding.length,
|
|
456
|
+
};
|
|
457
|
+
embeddingCache.set(cacheKey, cacheEntry);
|
|
458
|
+
console.error(` 💾 Embedding cached (${embedding.length} dims)`);
|
|
459
|
+
const inputTokens = Math.ceil(truncatedText.length / 4);
|
|
460
|
+
getCostTracker().recordCost({
|
|
461
|
+
service: "google",
|
|
462
|
+
operation: "embedding",
|
|
463
|
+
model: MODEL,
|
|
464
|
+
inputTokens,
|
|
465
|
+
outputTokens: 0,
|
|
466
|
+
cached: false,
|
|
467
|
+
duration: 0,
|
|
468
|
+
module: "session",
|
|
469
|
+
});
|
|
470
|
+
return embedding;
|
|
471
|
+
}
|
|
472
|
+
catch (error) {
|
|
473
|
+
console.error(`❌ Failed to generate embedding: ${error.message}`);
|
|
474
|
+
throw error;
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
async getStats() {
|
|
480
|
+
const collectionInfo = await this.qdrant.getCollection(this.collectionName);
|
|
481
|
+
const notesByType = {};
|
|
482
|
+
const allTypes = [
|
|
483
|
+
"decision",
|
|
484
|
+
"hypothesis",
|
|
485
|
+
"blocker",
|
|
486
|
+
"learning",
|
|
487
|
+
"pattern",
|
|
488
|
+
"constraint",
|
|
489
|
+
"finding",
|
|
490
|
+
"prior_knowledge",
|
|
491
|
+
"decision_point",
|
|
492
|
+
"branch",
|
|
493
|
+
];
|
|
494
|
+
for (const type of allTypes) {
|
|
495
|
+
const notes = await this.getNotesByType(type);
|
|
496
|
+
notesByType[type] = notes.length;
|
|
497
|
+
}
|
|
498
|
+
return {
|
|
499
|
+
collection: this.collectionName,
|
|
500
|
+
sessionId: this.sessionId,
|
|
501
|
+
totalNotes: collectionInfo.points_count || 0,
|
|
502
|
+
notesByType,
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
async trackConstraint(content, detectedFrom = "explicit", scope = "session", keywords) {
|
|
506
|
+
const constraint = {
|
|
507
|
+
id: `constraint-${Date.now()}`,
|
|
508
|
+
content,
|
|
509
|
+
detected_from: detectedFrom,
|
|
510
|
+
timestamp: new Date().toISOString(),
|
|
511
|
+
scope,
|
|
512
|
+
status: "active",
|
|
513
|
+
keywords: keywords || this.extractKeywords(content),
|
|
514
|
+
violated_count: 0,
|
|
515
|
+
};
|
|
516
|
+
const embedding = await this.generateEmbedding(content);
|
|
517
|
+
const pointId = Date.now() * 1000 + Math.floor(Math.random() * 1000);
|
|
518
|
+
await this.qdrant.upsert(this.collectionName, {
|
|
519
|
+
points: [
|
|
520
|
+
{
|
|
521
|
+
id: pointId,
|
|
522
|
+
vector: embedding,
|
|
523
|
+
payload: {
|
|
524
|
+
type: "constraint",
|
|
525
|
+
content,
|
|
526
|
+
timestamp: constraint.timestamp,
|
|
527
|
+
session_id: this.sessionId,
|
|
528
|
+
project_path: this.projectPath,
|
|
529
|
+
constraint_id: constraint.id,
|
|
530
|
+
detected_from: detectedFrom,
|
|
531
|
+
scope,
|
|
532
|
+
status: "active",
|
|
533
|
+
keywords: constraint.keywords,
|
|
534
|
+
point_id: pointId,
|
|
535
|
+
},
|
|
536
|
+
},
|
|
537
|
+
],
|
|
538
|
+
});
|
|
539
|
+
console.log(`🔒 Tracked constraint: ${content}`);
|
|
540
|
+
return constraint;
|
|
541
|
+
}
|
|
542
|
+
async getActiveConstraints() {
|
|
543
|
+
const constraintNotes = await this.getNotesByType("constraint");
|
|
544
|
+
return constraintNotes
|
|
545
|
+
.filter((note) => note.metadata?.status === "active")
|
|
546
|
+
.map((note) => ({
|
|
547
|
+
id: note.metadata?.constraint_id || `constraint-${Date.now()}`,
|
|
548
|
+
content: note.content,
|
|
549
|
+
detected_from: note.metadata?.detected_from || "explicit",
|
|
550
|
+
timestamp: note.timestamp,
|
|
551
|
+
scope: note.metadata?.scope || "session",
|
|
552
|
+
status: "active",
|
|
553
|
+
keywords: note.metadata?.keywords || [],
|
|
554
|
+
violated_count: note.metadata?.violated_count || 0,
|
|
555
|
+
metadata: note.metadata,
|
|
556
|
+
}));
|
|
557
|
+
}
|
|
558
|
+
async liftConstraint(constraintId) {
|
|
559
|
+
const constraintNotes = await this.getNotesByType("constraint");
|
|
560
|
+
const constraint = constraintNotes.find((n) => n.metadata?.constraint_id === constraintId);
|
|
561
|
+
if (!constraint) {
|
|
562
|
+
throw new Error(`Constraint not found: ${constraintId}`);
|
|
563
|
+
}
|
|
564
|
+
const pointId = constraint.metadata?.point_id;
|
|
565
|
+
if (!pointId) {
|
|
566
|
+
throw new Error(`Constraint missing point_id: ${constraintId}`);
|
|
567
|
+
}
|
|
568
|
+
await this.qdrant.setPayload(this.collectionName, {
|
|
569
|
+
points: [pointId],
|
|
570
|
+
payload: {
|
|
571
|
+
status: "lifted",
|
|
572
|
+
lifted_at: new Date().toISOString(),
|
|
573
|
+
},
|
|
574
|
+
});
|
|
575
|
+
console.log(`🔓 Lifted constraint: ${constraint.content}`);
|
|
576
|
+
}
|
|
577
|
+
async checkViolation(proposedAction) {
|
|
578
|
+
const activeConstraints = await this.getActiveConstraints();
|
|
579
|
+
if (activeConstraints.length === 0) {
|
|
580
|
+
return { violated: false, violations: [] };
|
|
581
|
+
}
|
|
582
|
+
const actionEmbedding = await this.generateEmbedding(proposedAction);
|
|
583
|
+
const constraintScores = [];
|
|
584
|
+
for (const constraint of activeConstraints) {
|
|
585
|
+
const constraintEmbedding = await this.generateEmbedding(constraint.content);
|
|
586
|
+
const semanticScore = this.cosineSimilarity(actionEmbedding, constraintEmbedding);
|
|
587
|
+
const keywordScore = this.calculateKeywordScore(proposedAction, constraint.keywords);
|
|
588
|
+
constraintScores.push({
|
|
589
|
+
constraint,
|
|
590
|
+
semanticScore,
|
|
591
|
+
keywordScore,
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
const semanticRanks = this.rankByScore(constraintScores, (s) => s.semanticScore);
|
|
595
|
+
const keywordRanks = this.rankByScore(constraintScores, (s) => s.keywordScore);
|
|
596
|
+
const RRF_THRESHOLD = 0.02;
|
|
597
|
+
const violations = [];
|
|
598
|
+
for (const scored of constraintScores) {
|
|
599
|
+
const semRank = semanticRanks.get(scored) ?? activeConstraints.length;
|
|
600
|
+
const kwRank = keywordRanks.get(scored) ?? activeConstraints.length;
|
|
601
|
+
const rrfScore = this.calculateRRFScore([semRank, kwRank]);
|
|
602
|
+
const hasSemanticSignal = scored.semanticScore > 0.4;
|
|
603
|
+
const hasKeywordSignal = scored.keywordScore > 0.3;
|
|
604
|
+
if (rrfScore >= RRF_THRESHOLD &&
|
|
605
|
+
(hasSemanticSignal || hasKeywordSignal)) {
|
|
606
|
+
let severity;
|
|
607
|
+
if (scored.constraint.scope === "session" && rrfScore > 0.025) {
|
|
608
|
+
severity = "high";
|
|
609
|
+
}
|
|
610
|
+
else if (scored.constraint.scope === "session" || rrfScore > 0.025) {
|
|
611
|
+
severity = "medium";
|
|
612
|
+
}
|
|
613
|
+
else {
|
|
614
|
+
severity = "low";
|
|
615
|
+
}
|
|
616
|
+
const reasons = [];
|
|
617
|
+
if (hasSemanticSignal) {
|
|
618
|
+
reasons.push(`semantic: ${(scored.semanticScore * 100).toFixed(0)}%`);
|
|
619
|
+
}
|
|
620
|
+
if (hasKeywordSignal) {
|
|
621
|
+
reasons.push(`keywords: [${scored.constraint.keywords.slice(0, 3).join(", ")}]`);
|
|
622
|
+
}
|
|
623
|
+
violations.push({
|
|
624
|
+
constraint: scored.constraint,
|
|
625
|
+
severity,
|
|
626
|
+
reason: `RRF hybrid match (${reasons.join(", ")})`,
|
|
627
|
+
scores: {
|
|
628
|
+
semantic: scored.semanticScore,
|
|
629
|
+
keyword: scored.keywordScore,
|
|
630
|
+
rrf: rrfScore,
|
|
631
|
+
},
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
violations.sort((a, b) => b.scores.rrf - a.scores.rrf);
|
|
636
|
+
return {
|
|
637
|
+
violated: violations.length > 0,
|
|
638
|
+
violations,
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
extractKeywords(text) {
|
|
642
|
+
const keywords = [];
|
|
643
|
+
const lowerText = text.toLowerCase();
|
|
644
|
+
const stopwords = new Set([
|
|
645
|
+
"no",
|
|
646
|
+
"not",
|
|
647
|
+
"don't",
|
|
648
|
+
"doesn't",
|
|
649
|
+
"never",
|
|
650
|
+
"must",
|
|
651
|
+
"always",
|
|
652
|
+
"require",
|
|
653
|
+
"should",
|
|
654
|
+
"avoid",
|
|
655
|
+
"prevent",
|
|
656
|
+
"prohibit",
|
|
657
|
+
"forbidden",
|
|
658
|
+
"the",
|
|
659
|
+
"a",
|
|
660
|
+
"an",
|
|
661
|
+
"and",
|
|
662
|
+
"or",
|
|
663
|
+
"but",
|
|
664
|
+
"in",
|
|
665
|
+
"on",
|
|
666
|
+
"at",
|
|
667
|
+
"to",
|
|
668
|
+
"for",
|
|
669
|
+
"of",
|
|
670
|
+
"with",
|
|
671
|
+
"by",
|
|
672
|
+
"from",
|
|
673
|
+
"as",
|
|
674
|
+
"is",
|
|
675
|
+
"was",
|
|
676
|
+
"are",
|
|
677
|
+
"were",
|
|
678
|
+
"been",
|
|
679
|
+
"be",
|
|
680
|
+
"have",
|
|
681
|
+
"has",
|
|
682
|
+
"had",
|
|
683
|
+
"do",
|
|
684
|
+
"does",
|
|
685
|
+
"did",
|
|
686
|
+
"will",
|
|
687
|
+
"would",
|
|
688
|
+
"could",
|
|
689
|
+
"should",
|
|
690
|
+
"may",
|
|
691
|
+
"might",
|
|
692
|
+
"can",
|
|
693
|
+
"this",
|
|
694
|
+
"that",
|
|
695
|
+
"these",
|
|
696
|
+
"those",
|
|
697
|
+
"it",
|
|
698
|
+
"its",
|
|
699
|
+
"if",
|
|
700
|
+
"then",
|
|
701
|
+
"else",
|
|
702
|
+
"when",
|
|
703
|
+
"where",
|
|
704
|
+
"which",
|
|
705
|
+
"while",
|
|
706
|
+
"during",
|
|
707
|
+
"before",
|
|
708
|
+
"after",
|
|
709
|
+
"above",
|
|
710
|
+
"below",
|
|
711
|
+
"between",
|
|
712
|
+
"into",
|
|
713
|
+
"through",
|
|
714
|
+
"about",
|
|
715
|
+
"against",
|
|
716
|
+
"without",
|
|
717
|
+
"within",
|
|
718
|
+
]);
|
|
719
|
+
const indicators = [
|
|
720
|
+
"no ",
|
|
721
|
+
"not ",
|
|
722
|
+
"don't ",
|
|
723
|
+
"doesn't ",
|
|
724
|
+
"never ",
|
|
725
|
+
"must ",
|
|
726
|
+
"always ",
|
|
727
|
+
"require ",
|
|
728
|
+
"should ",
|
|
729
|
+
"avoid ",
|
|
730
|
+
"prevent ",
|
|
731
|
+
"prohibit ",
|
|
732
|
+
"forbidden ",
|
|
733
|
+
];
|
|
734
|
+
for (const indicator of indicators) {
|
|
735
|
+
const index = lowerText.indexOf(indicator);
|
|
736
|
+
if (index !== -1) {
|
|
737
|
+
const afterIndicator = lowerText.slice(index + indicator.length);
|
|
738
|
+
const words = afterIndicator.split(/\s+/).slice(0, 5);
|
|
739
|
+
const domainWords = words.filter((w) => w.length > 2 && !stopwords.has(w));
|
|
740
|
+
keywords.push(...domainWords);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return [...new Set(keywords)];
|
|
744
|
+
}
|
|
745
|
+
calculateKeywordScore(text, keywords) {
|
|
746
|
+
if (keywords.length === 0)
|
|
747
|
+
return 0;
|
|
748
|
+
const lowerText = text.toLowerCase();
|
|
749
|
+
let matchCount = 0;
|
|
750
|
+
let weightedScore = 0;
|
|
751
|
+
const priorityKeywords = [
|
|
752
|
+
"no",
|
|
753
|
+
"not",
|
|
754
|
+
"don't",
|
|
755
|
+
"never",
|
|
756
|
+
"must",
|
|
757
|
+
"always",
|
|
758
|
+
"require",
|
|
759
|
+
"avoid",
|
|
760
|
+
"prevent",
|
|
761
|
+
"prohibit",
|
|
762
|
+
];
|
|
763
|
+
for (const keyword of keywords) {
|
|
764
|
+
const lowerKeyword = keyword.toLowerCase();
|
|
765
|
+
if (lowerText.includes(lowerKeyword)) {
|
|
766
|
+
matchCount++;
|
|
767
|
+
const weight = priorityKeywords.includes(lowerKeyword) ? 2.0 : 1.0;
|
|
768
|
+
const position = lowerText.indexOf(lowerKeyword);
|
|
769
|
+
const positionBonus = 1 - (position / lowerText.length) * 0.3;
|
|
770
|
+
weightedScore += weight * positionBonus;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
const matchRatio = matchCount / keywords.length;
|
|
774
|
+
const avgWeight = matchCount > 0 ? weightedScore / matchCount : 0;
|
|
775
|
+
return Math.min(1.0, matchRatio * avgWeight);
|
|
776
|
+
}
|
|
777
|
+
calculateRRFScore(ranks, k = 60) {
|
|
778
|
+
return ranks.reduce((sum, rank) => sum + 1 / (k + rank), 0);
|
|
779
|
+
}
|
|
780
|
+
rankByScore(items, scoreGetter) {
|
|
781
|
+
const sorted = [...items].sort((a, b) => scoreGetter(b) - scoreGetter(a));
|
|
782
|
+
const ranks = new Map();
|
|
783
|
+
sorted.forEach((item, index) => ranks.set(item, index + 1));
|
|
784
|
+
return ranks;
|
|
785
|
+
}
|
|
786
|
+
cosineSimilarity(a, b) {
|
|
787
|
+
if (a.length !== b.length)
|
|
788
|
+
return 0;
|
|
789
|
+
let dotProduct = 0;
|
|
790
|
+
let normA = 0;
|
|
791
|
+
let normB = 0;
|
|
792
|
+
for (let i = 0; i < a.length; i++) {
|
|
793
|
+
const aVal = a[i] ?? 0;
|
|
794
|
+
const bVal = b[i] ?? 0;
|
|
795
|
+
dotProduct += aVal * bVal;
|
|
796
|
+
normA += aVal * aVal;
|
|
797
|
+
normB += bVal * bVal;
|
|
798
|
+
}
|
|
799
|
+
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
|
|
800
|
+
}
|
|
801
|
+
async saveNoteWithId(note, relationships) {
|
|
802
|
+
try {
|
|
803
|
+
const embedding = await this.generateEmbedding(note.content);
|
|
804
|
+
const pointId = Date.now() * 1000 + Math.floor(Math.random() * 1000);
|
|
805
|
+
const payload = {
|
|
806
|
+
type: note.type,
|
|
807
|
+
content: note.content,
|
|
808
|
+
timestamp: new Date().toISOString(),
|
|
809
|
+
session_id: this.sessionId,
|
|
810
|
+
project_path: this.projectPath,
|
|
811
|
+
point_id: pointId,
|
|
812
|
+
...note.metadata,
|
|
813
|
+
};
|
|
814
|
+
if (relationships) {
|
|
815
|
+
payload.relationships = relationships;
|
|
816
|
+
}
|
|
817
|
+
await this.qdrant.upsert(this.collectionName, {
|
|
818
|
+
points: [
|
|
819
|
+
{
|
|
820
|
+
id: pointId,
|
|
821
|
+
vector: embedding,
|
|
822
|
+
payload,
|
|
823
|
+
},
|
|
824
|
+
],
|
|
825
|
+
});
|
|
826
|
+
console.error(`📝 Saved ${note.type} (id: ${pointId}): ${note.content.slice(0, 60)}${note.content.length > 60 ? "..." : ""}`);
|
|
827
|
+
return pointId;
|
|
828
|
+
}
|
|
829
|
+
catch (error) {
|
|
830
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
831
|
+
console.error(`❌ Failed to save note: ${errorMessage}`);
|
|
832
|
+
throw error;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
async addRelationship(sourceNoteId, targetNoteId, relationshipType) {
|
|
836
|
+
try {
|
|
837
|
+
const sourceNotes = await this.qdrant.retrieve(this.collectionName, {
|
|
838
|
+
ids: [sourceNoteId],
|
|
839
|
+
with_payload: true,
|
|
840
|
+
});
|
|
841
|
+
if (sourceNotes.length === 0) {
|
|
842
|
+
throw new Error(`Source note not found: ${sourceNoteId}`);
|
|
843
|
+
}
|
|
844
|
+
const targetNotes = await this.qdrant.retrieve(this.collectionName, {
|
|
845
|
+
ids: [targetNoteId],
|
|
846
|
+
with_payload: true,
|
|
847
|
+
});
|
|
848
|
+
if (targetNotes.length === 0) {
|
|
849
|
+
throw new Error(`Target note not found: ${targetNoteId}`);
|
|
850
|
+
}
|
|
851
|
+
const sourcePayload = sourceNotes[0]?.payload || {};
|
|
852
|
+
const existingRelationships = sourcePayload.relationships || {};
|
|
853
|
+
if (relationshipType === "superseded_by") {
|
|
854
|
+
existingRelationships[relationshipType] = targetNoteId;
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
const existingArray = existingRelationships[relationshipType] || [];
|
|
858
|
+
if (!existingArray.includes(targetNoteId)) {
|
|
859
|
+
existingArray.push(targetNoteId);
|
|
860
|
+
}
|
|
861
|
+
existingRelationships[relationshipType] = existingArray;
|
|
862
|
+
}
|
|
863
|
+
await this.qdrant.setPayload(this.collectionName, {
|
|
864
|
+
points: [sourceNoteId],
|
|
865
|
+
payload: {
|
|
866
|
+
relationships: existingRelationships,
|
|
867
|
+
},
|
|
868
|
+
});
|
|
869
|
+
console.error(`🔗 Added relationship: ${sourceNoteId} --[${relationshipType}]--> ${targetNoteId}`);
|
|
870
|
+
}
|
|
871
|
+
catch (error) {
|
|
872
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
873
|
+
console.error(`❌ Failed to add relationship: ${errorMessage}`);
|
|
874
|
+
throw error;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
async getNoteById(pointId) {
|
|
878
|
+
try {
|
|
879
|
+
const notes = await this.qdrant.retrieve(this.collectionName, {
|
|
880
|
+
ids: [pointId],
|
|
881
|
+
with_payload: true,
|
|
882
|
+
});
|
|
883
|
+
if (notes.length === 0) {
|
|
884
|
+
return null;
|
|
885
|
+
}
|
|
886
|
+
const note = notes[0];
|
|
887
|
+
return {
|
|
888
|
+
score: 1.0,
|
|
889
|
+
type: note?.payload?.type || "unknown",
|
|
890
|
+
content: note?.payload?.content || "",
|
|
891
|
+
timestamp: note?.payload?.timestamp || "",
|
|
892
|
+
metadata: note?.payload,
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
catch (error) {
|
|
896
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
897
|
+
console.error(`❌ Failed to get note by ID: ${errorMessage}`);
|
|
898
|
+
return null;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
async getRelatedNotes(pointId, relationshipType) {
|
|
902
|
+
try {
|
|
903
|
+
const sourceNote = await this.getNoteById(pointId);
|
|
904
|
+
if (!sourceNote) {
|
|
905
|
+
throw new Error(`Note not found: ${pointId}`);
|
|
906
|
+
}
|
|
907
|
+
const relationships = sourceNote.metadata?.relationships || {};
|
|
908
|
+
const relatedNotes = [];
|
|
909
|
+
const typesToQuery = relationshipType
|
|
910
|
+
? [relationshipType]
|
|
911
|
+
: [
|
|
912
|
+
"preceded_by",
|
|
913
|
+
"caused_by",
|
|
914
|
+
"validated_by",
|
|
915
|
+
"superseded_by",
|
|
916
|
+
"related_to",
|
|
917
|
+
];
|
|
918
|
+
for (const relType of typesToQuery) {
|
|
919
|
+
const relatedIds = relationships[relType];
|
|
920
|
+
if (!relatedIds)
|
|
921
|
+
continue;
|
|
922
|
+
const idsArray = Array.isArray(relatedIds) ? relatedIds : [relatedIds];
|
|
923
|
+
if (idsArray.length > 0) {
|
|
924
|
+
const notes = await this.qdrant.retrieve(this.collectionName, {
|
|
925
|
+
ids: idsArray,
|
|
926
|
+
with_payload: true,
|
|
927
|
+
});
|
|
928
|
+
for (const note of notes) {
|
|
929
|
+
relatedNotes.push({
|
|
930
|
+
score: 1.0,
|
|
931
|
+
type: note?.payload?.type || "unknown",
|
|
932
|
+
content: note?.payload?.content || "",
|
|
933
|
+
timestamp: note?.payload?.timestamp || "",
|
|
934
|
+
metadata: note?.payload,
|
|
935
|
+
relationship: relType,
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
return relatedNotes;
|
|
941
|
+
}
|
|
942
|
+
catch (error) {
|
|
943
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
944
|
+
console.error(`❌ Failed to get related notes: ${errorMessage}`);
|
|
945
|
+
return [];
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
async searchWithRelationships(query, limit = 5, includeRelationships = false) {
|
|
949
|
+
const results = await this.search(query, limit);
|
|
950
|
+
if (!includeRelationships) {
|
|
951
|
+
return results;
|
|
952
|
+
}
|
|
953
|
+
const enrichedResults = [];
|
|
954
|
+
for (const result of results) {
|
|
955
|
+
const pointId = result.metadata?.point_id;
|
|
956
|
+
let relatedNotes = [];
|
|
957
|
+
if (pointId) {
|
|
958
|
+
relatedNotes = await this.getRelatedNotes(pointId);
|
|
959
|
+
}
|
|
960
|
+
enrichedResults.push({
|
|
961
|
+
...result,
|
|
962
|
+
relatedNotes: relatedNotes.length > 0 ? relatedNotes : undefined,
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
return enrichedResults;
|
|
966
|
+
}
|
|
967
|
+
async getCausalChain(startPointId, maxDepth = 5) {
|
|
968
|
+
const chain = [];
|
|
969
|
+
const visited = new Set();
|
|
970
|
+
const traverse = async (pointId, depth) => {
|
|
971
|
+
if (depth > maxDepth || visited.has(pointId))
|
|
972
|
+
return;
|
|
973
|
+
visited.add(pointId);
|
|
974
|
+
const note = await this.getNoteById(pointId);
|
|
975
|
+
if (!note)
|
|
976
|
+
return;
|
|
977
|
+
if (depth > 0) {
|
|
978
|
+
chain.push({
|
|
979
|
+
...note,
|
|
980
|
+
depth,
|
|
981
|
+
relationship: "caused_by",
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
const relationships = note.metadata?.relationships || {};
|
|
985
|
+
const causedBy = relationships.caused_by || [];
|
|
986
|
+
const precededBy = relationships.preceded_by || [];
|
|
987
|
+
for (const relatedId of [...causedBy, ...precededBy]) {
|
|
988
|
+
await traverse(relatedId, depth + 1);
|
|
989
|
+
}
|
|
990
|
+
};
|
|
991
|
+
const startNote = await this.getNoteById(startPointId);
|
|
992
|
+
if (startNote) {
|
|
993
|
+
chain.push({
|
|
994
|
+
...startNote,
|
|
995
|
+
depth: 0,
|
|
996
|
+
relationship: "start",
|
|
997
|
+
});
|
|
998
|
+
await traverse(startPointId, 0);
|
|
999
|
+
}
|
|
1000
|
+
chain.sort((a, b) => b.depth - a.depth);
|
|
1001
|
+
return chain;
|
|
1002
|
+
}
|
|
1003
|
+
async getValidatingNotes(decisionId, maxResults = 20) {
|
|
1004
|
+
try {
|
|
1005
|
+
const validatingNotes = [];
|
|
1006
|
+
let offset = null;
|
|
1007
|
+
let found = 0;
|
|
1008
|
+
while (found < maxResults) {
|
|
1009
|
+
const scrollResult = await this.qdrant.scroll(this.collectionName, {
|
|
1010
|
+
with_payload: true,
|
|
1011
|
+
limit: 100,
|
|
1012
|
+
offset: offset ?? undefined,
|
|
1013
|
+
});
|
|
1014
|
+
if (!scrollResult.points || scrollResult.points.length === 0) {
|
|
1015
|
+
break;
|
|
1016
|
+
}
|
|
1017
|
+
for (const point of scrollResult.points) {
|
|
1018
|
+
if (found >= maxResults)
|
|
1019
|
+
break;
|
|
1020
|
+
const relationships = point.payload?.relationships;
|
|
1021
|
+
if (!relationships)
|
|
1022
|
+
continue;
|
|
1023
|
+
const validatedBy = relationships.validated_by;
|
|
1024
|
+
const relatedTo = relationships.related_to;
|
|
1025
|
+
const hasValidatedBy = validatedBy && validatedBy.includes(decisionId);
|
|
1026
|
+
const hasRelatedTo = relatedTo && relatedTo.includes(decisionId);
|
|
1027
|
+
if (hasValidatedBy || hasRelatedTo) {
|
|
1028
|
+
validatingNotes.push({
|
|
1029
|
+
score: 1.0,
|
|
1030
|
+
type: point.payload?.type || "unknown",
|
|
1031
|
+
content: point.payload?.content || "",
|
|
1032
|
+
timestamp: point.payload?.timestamp || "",
|
|
1033
|
+
metadata: {
|
|
1034
|
+
point_id: point.id,
|
|
1035
|
+
session_id: point.payload?.session_id,
|
|
1036
|
+
relationships,
|
|
1037
|
+
},
|
|
1038
|
+
relationship: hasValidatedBy ? "validated_by" : "related_to",
|
|
1039
|
+
});
|
|
1040
|
+
found++;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
const nextOffset = scrollResult.next_page_offset;
|
|
1044
|
+
if (typeof nextOffset === "string" || typeof nextOffset === "number") {
|
|
1045
|
+
offset = nextOffset;
|
|
1046
|
+
}
|
|
1047
|
+
else {
|
|
1048
|
+
offset = null;
|
|
1049
|
+
}
|
|
1050
|
+
if (!offset)
|
|
1051
|
+
break;
|
|
1052
|
+
}
|
|
1053
|
+
validatingNotes.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
1054
|
+
return validatingNotes;
|
|
1055
|
+
}
|
|
1056
|
+
catch (error) {
|
|
1057
|
+
console.error("Failed to get validating notes:", error);
|
|
1058
|
+
return [];
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
//# sourceMappingURL=SessionCoordinator.js.map
|