@4da/mcp-server 3.2.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +234 -62
- package/dist/auth.d.ts +36 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +82 -0
- package/dist/auth.js.map +1 -0
- package/dist/db.d.ts +100 -2
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +707 -1
- package/dist/db.js.map +1 -1
- package/dist/doctor.d.ts +15 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +124 -0
- package/dist/doctor.js.map +1 -0
- package/dist/http-transport.d.ts +25 -0
- package/dist/http-transport.d.ts.map +1 -0
- package/dist/http-transport.js +143 -0
- package/dist/http-transport.js.map +1 -0
- package/dist/index.d.ts +15 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +195 -250
- package/dist/index.js.map +1 -1
- package/dist/live/cache.d.ts +16 -0
- package/dist/live/cache.d.ts.map +1 -0
- package/dist/live/cache.js +61 -0
- package/dist/live/cache.js.map +1 -0
- package/dist/live/hn-fetcher.d.ts +19 -0
- package/dist/live/hn-fetcher.d.ts.map +1 -0
- package/dist/live/hn-fetcher.js +123 -0
- package/dist/live/hn-fetcher.js.map +1 -0
- package/dist/live/index.d.ts +55 -0
- package/dist/live/index.d.ts.map +1 -0
- package/dist/live/index.js +131 -0
- package/dist/live/index.js.map +1 -0
- package/dist/live/osv-scanner.d.ts +19 -0
- package/dist/live/osv-scanner.d.ts.map +1 -0
- package/dist/live/osv-scanner.js +197 -0
- package/dist/live/osv-scanner.js.map +1 -0
- package/dist/live/rate-limiter.d.ts +19 -0
- package/dist/live/rate-limiter.d.ts.map +1 -0
- package/dist/live/rate-limiter.js +52 -0
- package/dist/live/rate-limiter.js.map +1 -0
- package/dist/live/types.d.ts +89 -0
- package/dist/live/types.d.ts.map +1 -0
- package/dist/live/types.js +3 -0
- package/dist/live/types.js.map +1 -0
- package/dist/live/version-resolver.d.ts +11 -0
- package/dist/live/version-resolver.d.ts.map +1 -0
- package/dist/live/version-resolver.js +321 -0
- package/dist/live/version-resolver.js.map +1 -0
- package/dist/live-singleton.d.ts +9 -0
- package/dist/live-singleton.d.ts.map +1 -0
- package/dist/live-singleton.js +14 -0
- package/dist/live-singleton.js.map +1 -0
- package/dist/llm.d.ts +20 -2
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +80 -22
- package/dist/llm.js.map +1 -1
- package/dist/output-manager.d.ts.map +1 -1
- package/dist/output-manager.js +1 -0
- package/dist/output-manager.js.map +1 -1
- package/dist/project-scanner.d.ts +27 -0
- package/dist/project-scanner.d.ts.map +1 -0
- package/dist/project-scanner.js +366 -0
- package/dist/project-scanner.js.map +1 -0
- package/dist/schema-registry.d.ts +31 -13
- package/dist/schema-registry.d.ts.map +1 -1
- package/dist/schema-registry.js +208 -32
- package/dist/schema-registry.js.map +1 -1
- package/dist/schemas/agent-feedback-stats.json +14 -0
- package/dist/schemas/agent-memory.json +49 -0
- package/dist/schemas/agent-session-brief.json +25 -0
- package/dist/schemas/attention-report.json +13 -0
- package/dist/schemas/autophagy-status.json +13 -0
- package/dist/schemas/compound-advantage.json +14 -0
- package/dist/schemas/decision-enforcement.json +22 -0
- package/dist/schemas/decision-memory.json +54 -0
- package/dist/schemas/decision-windows.json +22 -0
- package/dist/schemas/delegation-score.json +18 -0
- package/dist/schemas/developer-dna.json +219 -0
- package/dist/schemas/export-context.json +17 -0
- package/dist/schemas/knowledge-gaps.json +14 -0
- package/dist/schemas/preemption-feed.json +18 -0
- package/dist/schemas/project-health.json +13 -0
- package/dist/schemas/record-agent-feedback.json +28 -0
- package/dist/schemas/reverse-mentions.json +13 -0
- package/dist/schemas/semantic-shifts.json +17 -0
- package/dist/schemas/signal-chains.json +19 -0
- package/dist/schemas/tech-radar.json +23 -0
- package/dist/schemas/trust-summary.json +13 -0
- package/dist/schemas/vulnerability-scan.json +26 -0
- package/dist/schemas/what-should-i-know.json +19 -0
- package/dist/setup.d.ts +18 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +171 -0
- package/dist/setup.js.map +1 -0
- package/dist/tool-dispatch.d.ts +33 -0
- package/dist/tool-dispatch.d.ts.map +1 -0
- package/dist/tool-dispatch.js +87 -0
- package/dist/tool-dispatch.js.map +1 -0
- package/dist/tools/agent-feedback-stats.d.ts +30 -0
- package/dist/tools/agent-feedback-stats.d.ts.map +1 -0
- package/dist/tools/agent-feedback-stats.js +41 -0
- package/dist/tools/agent-feedback-stats.js.map +1 -0
- package/dist/tools/agent-memory.d.ts +94 -0
- package/dist/tools/agent-memory.d.ts.map +1 -0
- package/dist/tools/agent-memory.js +262 -0
- package/dist/tools/agent-memory.js.map +1 -0
- package/dist/tools/agent-session-brief.d.ts +44 -0
- package/dist/tools/agent-session-brief.d.ts.map +1 -0
- package/dist/tools/agent-session-brief.js +179 -0
- package/dist/tools/agent-session-brief.js.map +1 -0
- package/dist/tools/attention-report.d.ts +6 -5
- package/dist/tools/attention-report.d.ts.map +1 -1
- package/dist/tools/attention-report.js +1 -0
- package/dist/tools/attention-report.js.map +1 -1
- package/dist/tools/autophagy-status.d.ts +25 -0
- package/dist/tools/autophagy-status.d.ts.map +1 -0
- package/dist/tools/autophagy-status.js +56 -0
- package/dist/tools/autophagy-status.js.map +1 -0
- package/dist/tools/compound-advantage.d.ts +30 -0
- package/dist/tools/compound-advantage.d.ts.map +1 -0
- package/dist/tools/compound-advantage.js +133 -0
- package/dist/tools/compound-advantage.js.map +1 -0
- package/dist/tools/config-validator.d.ts.map +1 -1
- package/dist/tools/config-validator.js +31 -0
- package/dist/tools/config-validator.js.map +1 -1
- package/dist/tools/context-analysis.d.ts.map +1 -1
- package/dist/tools/context-analysis.js +1 -0
- package/dist/tools/context-analysis.js.map +1 -1
- package/dist/tools/daily-briefing.d.ts.map +1 -1
- package/dist/tools/daily-briefing.js +17 -1
- package/dist/tools/daily-briefing.js.map +1 -1
- package/dist/tools/decision-enforcement.d.ts +59 -0
- package/dist/tools/decision-enforcement.d.ts.map +1 -0
- package/dist/tools/decision-enforcement.js +185 -0
- package/dist/tools/decision-enforcement.js.map +1 -0
- package/dist/tools/decision-memory.d.ts +132 -0
- package/dist/tools/decision-memory.d.ts.map +1 -0
- package/dist/tools/decision-memory.js +345 -0
- package/dist/tools/decision-memory.js.map +1 -0
- package/dist/tools/decision-windows.d.ts +37 -0
- package/dist/tools/decision-windows.d.ts.map +1 -0
- package/dist/tools/decision-windows.js +67 -0
- package/dist/tools/decision-windows.js.map +1 -0
- package/dist/tools/delegation-score.d.ts +34 -0
- package/dist/tools/delegation-score.d.ts.map +1 -0
- package/dist/tools/delegation-score.js +251 -0
- package/dist/tools/delegation-score.js.map +1 -0
- package/dist/tools/developer-dna.d.ts +79 -0
- package/dist/tools/developer-dna.d.ts.map +1 -0
- package/dist/tools/developer-dna.js +378 -0
- package/dist/tools/developer-dna.js.map +1 -0
- package/dist/tools/explain-relevance.d.ts.map +1 -1
- package/dist/tools/explain-relevance.js +1 -0
- package/dist/tools/explain-relevance.js.map +1 -1
- package/dist/tools/export-context.d.ts +23 -6
- package/dist/tools/export-context.d.ts.map +1 -1
- package/dist/tools/export-context.js +58 -14
- package/dist/tools/export-context.js.map +1 -1
- package/dist/tools/get-actionable-signals.d.ts.map +1 -1
- package/dist/tools/get-actionable-signals.js +60 -9
- package/dist/tools/get-actionable-signals.js.map +1 -1
- package/dist/tools/get-context.d.ts.map +1 -1
- package/dist/tools/get-context.js +1 -0
- package/dist/tools/get-context.js.map +1 -1
- package/dist/tools/get-relevant-content.d.ts.map +1 -1
- package/dist/tools/get-relevant-content.js +3 -0
- package/dist/tools/get-relevant-content.js.map +1 -1
- package/dist/tools/index.d.ts +26 -16
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +35 -16
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/knowledge-gaps.d.ts +11 -1
- package/dist/tools/knowledge-gaps.d.ts.map +1 -1
- package/dist/tools/knowledge-gaps.js +9 -3
- package/dist/tools/knowledge-gaps.js.map +1 -1
- package/dist/tools/llm-status.d.ts.map +1 -1
- package/dist/tools/llm-status.js +1 -0
- package/dist/tools/llm-status.js.map +1 -1
- package/dist/tools/muse-context.d.ts +195 -0
- package/dist/tools/muse-context.d.ts.map +1 -0
- package/dist/tools/muse-context.js +284 -0
- package/dist/tools/muse-context.js.map +1 -0
- package/dist/tools/preemption-feed.d.ts +55 -0
- package/dist/tools/preemption-feed.d.ts.map +1 -0
- package/dist/tools/preemption-feed.js +124 -0
- package/dist/tools/preemption-feed.js.map +1 -0
- package/dist/tools/project-health.d.ts +12 -6
- package/dist/tools/project-health.d.ts.map +1 -1
- package/dist/tools/project-health.js +49 -10
- package/dist/tools/project-health.js.map +1 -1
- package/dist/tools/record-agent-feedback.d.ts +46 -0
- package/dist/tools/record-agent-feedback.d.ts.map +1 -0
- package/dist/tools/record-agent-feedback.js +71 -0
- package/dist/tools/record-agent-feedback.js.map +1 -0
- package/dist/tools/record-feedback.d.ts.map +1 -1
- package/dist/tools/record-feedback.js +1 -0
- package/dist/tools/record-feedback.js.map +1 -1
- package/dist/tools/reverse-mentions.d.ts +8 -8
- package/dist/tools/reverse-mentions.d.ts.map +1 -1
- package/dist/tools/reverse-mentions.js +1 -0
- package/dist/tools/reverse-mentions.js.map +1 -1
- package/dist/tools/score-autopsy.d.ts.map +1 -1
- package/dist/tools/score-autopsy.js +1 -0
- package/dist/tools/score-autopsy.js.map +1 -1
- package/dist/tools/semantic-shifts.d.ts +17 -1
- package/dist/tools/semantic-shifts.d.ts.map +1 -1
- package/dist/tools/semantic-shifts.js +1 -0
- package/dist/tools/semantic-shifts.js.map +1 -1
- package/dist/tools/signal-chains.d.ts +14 -7
- package/dist/tools/signal-chains.d.ts.map +1 -1
- package/dist/tools/signal-chains.js +5 -2
- package/dist/tools/signal-chains.js.map +1 -1
- package/dist/tools/source-health.d.ts.map +1 -1
- package/dist/tools/source-health.js +1 -0
- package/dist/tools/source-health.js.map +1 -1
- package/dist/tools/tech-radar.d.ts +38 -0
- package/dist/tools/tech-radar.d.ts.map +1 -0
- package/dist/tools/tech-radar.js +249 -0
- package/dist/tools/tech-radar.js.map +1 -0
- package/dist/tools/topic-connections.d.ts.map +1 -1
- package/dist/tools/topic-connections.js +1 -0
- package/dist/tools/topic-connections.js.map +1 -1
- package/dist/tools/trend-analysis.d.ts.map +1 -1
- package/dist/tools/trend-analysis.js +1 -0
- package/dist/tools/trend-analysis.js.map +1 -1
- package/dist/tools/trust-summary.d.ts +38 -0
- package/dist/tools/trust-summary.d.ts.map +1 -0
- package/dist/tools/trust-summary.js +89 -0
- package/dist/tools/trust-summary.js.map +1 -0
- package/dist/tools/vulnerability-scan.d.ts +89 -0
- package/dist/tools/vulnerability-scan.d.ts.map +1 -0
- package/dist/tools/vulnerability-scan.js +127 -0
- package/dist/tools/vulnerability-scan.js.map +1 -0
- package/dist/tools/what-should-i-know.d.ts +79 -0
- package/dist/tools/what-should-i-know.d.ts.map +1 -0
- package/dist/tools/what-should-i-know.js +376 -0
- package/dist/tools/what-should-i-know.js.map +1 -0
- package/dist/types.d.ts +221 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/package.json +53 -24
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Dispatch Registry
|
|
3
|
+
*
|
|
4
|
+
* Map-based dispatch replacing the monolithic switch statement in index.ts.
|
|
5
|
+
* All 33 execute functions are imported once and mapped by tool name.
|
|
6
|
+
*
|
|
7
|
+
* Adding a new tool = add to this map + schema-registry + barrel export.
|
|
8
|
+
*/
|
|
9
|
+
import type { FourDADatabase } from "./db.js";
|
|
10
|
+
/**
|
|
11
|
+
* Executor signature — all tool execute functions follow this shape.
|
|
12
|
+
* Awaiting a sync return resolves immediately, so we can await uniformly.
|
|
13
|
+
*
|
|
14
|
+
* Uses `any` for params because each tool defines its own strict param type —
|
|
15
|
+
* type safety is enforced inside each tool file, not at the dispatch boundary.
|
|
16
|
+
* (The original switch statement used `as unknown as XParams` on every call.)
|
|
17
|
+
*/
|
|
18
|
+
export type ToolExecutor = (db: FourDADatabase, params: any) => unknown | Promise<unknown>;
|
|
19
|
+
/**
|
|
20
|
+
* Dispatch a tool call by name. Awaits uniformly (no-op for sync executors).
|
|
21
|
+
* Returns MCP-formatted response with JSON-serialized result.
|
|
22
|
+
*/
|
|
23
|
+
export declare function dispatchTool(name: string, db: FourDADatabase, args: Record<string, unknown> | undefined): Promise<{
|
|
24
|
+
content: Array<{
|
|
25
|
+
type: string;
|
|
26
|
+
text: string;
|
|
27
|
+
}>;
|
|
28
|
+
}>;
|
|
29
|
+
/** Check if a tool exists in the dispatch map */
|
|
30
|
+
export declare function hasDispatchTool(name: string): boolean;
|
|
31
|
+
/** Get count of registered tool executors */
|
|
32
|
+
export declare function getDispatchToolCount(): number;
|
|
33
|
+
//# sourceMappingURL=tool-dispatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-dispatch.d.ts","sourceRoot":"","sources":["../src/tool-dispatch.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA2C9C;;;;;;;GAOG;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAoE3F;;;GAGG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACxC,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAU7D;AAED,iDAAiD;AACjD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,6CAA6C;AAC7C,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// SPDX-License-Identifier: FSL-1.1-Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Tool Dispatch Registry
|
|
4
|
+
*
|
|
5
|
+
* Map-based dispatch replacing the monolithic switch statement in index.ts.
|
|
6
|
+
* All 33 execute functions are imported once and mapped by tool name.
|
|
7
|
+
*
|
|
8
|
+
* Adding a new tool = add to this map + schema-registry + barrel export.
|
|
9
|
+
*/
|
|
10
|
+
import { executeGetRelevantContent, executeGetContext, executeExplainRelevance, executeRecordFeedback, executeScoreAutopsy, executeTrendAnalysis, executeDailyBriefing, executeContextAnalysis, executeSourceHealth, executeTopicConnections, executeConfigValidator, executeLLMStatus, executeGetActionableSignals, executeExportContextPacket, executeKnowledgeGaps, executeSignalChains, executeSemanticShifts, executeReverseMentions, executeAttentionReport, executeProjectHealth, executeDecisionMemory, executeTechRadar, executeCheckDecisionAlignment, executeAgentMemory, executeAgentSessionBrief, executeDelegationScore, executeDeveloperDna, executeAutophagyStatus, executeDecisionWindows, executeCompoundAdvantage, executeRecordAgentFeedback, executeGetAgentFeedbackStats, executeWhatShouldIKnow, executeTrustSummary, executePreemptionFeed, executeVulnerabilityScan, } from "./tools/index.js";
|
|
11
|
+
import { getLiveIntelligence } from "./live-singleton.js";
|
|
12
|
+
/**
|
|
13
|
+
* Dispatch map — tool name → execute function
|
|
14
|
+
*/
|
|
15
|
+
const DISPATCH_MAP = {
|
|
16
|
+
// Core
|
|
17
|
+
get_relevant_content: executeGetRelevantContent,
|
|
18
|
+
get_context: executeGetContext,
|
|
19
|
+
explain_relevance: executeExplainRelevance,
|
|
20
|
+
record_feedback: executeRecordFeedback,
|
|
21
|
+
// Intelligence
|
|
22
|
+
score_autopsy: executeScoreAutopsy,
|
|
23
|
+
trend_analysis: executeTrendAnalysis,
|
|
24
|
+
daily_briefing: executeDailyBriefing,
|
|
25
|
+
context_analysis: executeContextAnalysis,
|
|
26
|
+
topic_connections: executeTopicConnections,
|
|
27
|
+
get_actionable_signals: executeGetActionableSignals,
|
|
28
|
+
signal_chains: executeSignalChains,
|
|
29
|
+
semantic_shifts: executeSemanticShifts,
|
|
30
|
+
attention_report: executeAttentionReport,
|
|
31
|
+
// Diagnostic
|
|
32
|
+
source_health: executeSourceHealth,
|
|
33
|
+
config_validator: executeConfigValidator,
|
|
34
|
+
llm_status: executeLLMStatus,
|
|
35
|
+
// Knowledge & Health
|
|
36
|
+
export_context_packet: executeExportContextPacket,
|
|
37
|
+
knowledge_gaps: executeKnowledgeGaps,
|
|
38
|
+
reverse_mentions: executeReverseMentions,
|
|
39
|
+
project_health: executeProjectHealth,
|
|
40
|
+
// Decision Intelligence
|
|
41
|
+
decision_memory: executeDecisionMemory,
|
|
42
|
+
tech_radar: executeTechRadar,
|
|
43
|
+
check_decision_alignment: executeCheckDecisionAlignment,
|
|
44
|
+
// Agent Autonomy
|
|
45
|
+
agent_memory: executeAgentMemory,
|
|
46
|
+
agent_session_brief: executeAgentSessionBrief,
|
|
47
|
+
delegation_score: executeDelegationScore,
|
|
48
|
+
// Developer DNA
|
|
49
|
+
developer_dna: executeDeveloperDna,
|
|
50
|
+
// Intelligence Metabolism
|
|
51
|
+
autophagy_status: executeAutophagyStatus,
|
|
52
|
+
decision_windows: executeDecisionWindows,
|
|
53
|
+
compound_advantage: executeCompoundAdvantage,
|
|
54
|
+
// Agent Feedback
|
|
55
|
+
record_agent_feedback: executeRecordAgentFeedback,
|
|
56
|
+
get_agent_feedback_stats: executeGetAgentFeedbackStats,
|
|
57
|
+
// Synthesis
|
|
58
|
+
what_should_i_know: executeWhatShouldIKnow,
|
|
59
|
+
// Trust & Preemption
|
|
60
|
+
trust_summary: executeTrustSummary,
|
|
61
|
+
preemption_feed: executePreemptionFeed,
|
|
62
|
+
// Live Intelligence
|
|
63
|
+
vulnerability_scan: (db, params) => executeVulnerabilityScan(db, params, getLiveIntelligence()),
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Dispatch a tool call by name. Awaits uniformly (no-op for sync executors).
|
|
67
|
+
* Returns MCP-formatted response with JSON-serialized result.
|
|
68
|
+
*/
|
|
69
|
+
export async function dispatchTool(name, db, args) {
|
|
70
|
+
const executor = DISPATCH_MAP[name];
|
|
71
|
+
if (!executor) {
|
|
72
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
73
|
+
}
|
|
74
|
+
const result = await executor(db, (args || {}));
|
|
75
|
+
return {
|
|
76
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/** Check if a tool exists in the dispatch map */
|
|
80
|
+
export function hasDispatchTool(name) {
|
|
81
|
+
return name in DISPATCH_MAP;
|
|
82
|
+
}
|
|
83
|
+
/** Get count of registered tool executors */
|
|
84
|
+
export function getDispatchToolCount() {
|
|
85
|
+
return Object.keys(DISPATCH_MAP).length;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=tool-dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-dispatch.js","sourceRoot":"","sources":["../src/tool-dispatch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* get_agent_feedback_stats tool
|
|
3
|
+
*
|
|
4
|
+
* Get statistics on how agents have used 4DA recommendations.
|
|
5
|
+
* Shows which sources and topics are most valuable for AI-assisted development.
|
|
6
|
+
*/
|
|
7
|
+
import type { FourDADatabase } from "../db.js";
|
|
8
|
+
import type { GetAgentFeedbackStatsParams, AgentFeedbackStats } from "../types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Tool definition for MCP registration
|
|
11
|
+
*/
|
|
12
|
+
export declare const agentFeedbackStatsTool: {
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
inputSchema: {
|
|
16
|
+
type: "object";
|
|
17
|
+
properties: {
|
|
18
|
+
days: {
|
|
19
|
+
type: string;
|
|
20
|
+
description: string;
|
|
21
|
+
default: number;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Execute the get_agent_feedback_stats tool
|
|
28
|
+
*/
|
|
29
|
+
export declare function executeGetAgentFeedbackStats(db: FourDADatabase, params: GetAgentFeedbackStatsParams): AgentFeedbackStats;
|
|
30
|
+
//# sourceMappingURL=agent-feedback-stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-feedback-stats.d.ts","sourceRoot":"","sources":["../../src/tools/agent-feedback-stats.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEnF;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;CAsBlC,CAAC;AAEF;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,EAAE,EAAE,cAAc,EAClB,MAAM,EAAE,2BAA2B,GAClC,kBAAkB,CAGpB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// SPDX-License-Identifier: FSL-1.1-Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* get_agent_feedback_stats tool
|
|
4
|
+
*
|
|
5
|
+
* Get statistics on how agents have used 4DA recommendations.
|
|
6
|
+
* Shows which sources and topics are most valuable for AI-assisted development.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Tool definition for MCP registration
|
|
10
|
+
*/
|
|
11
|
+
export const agentFeedbackStatsTool = {
|
|
12
|
+
name: "get_agent_feedback_stats",
|
|
13
|
+
description: `Get statistics on how agents have used 4DA recommendations.
|
|
14
|
+
|
|
15
|
+
Shows which sources and topics are most valuable for AI-assisted development:
|
|
16
|
+
- Total recommendations: used / rejected / partially_used counts
|
|
17
|
+
- By source type: which sources produce the most agent-useful content
|
|
18
|
+
- Top used item IDs (most frequently recommended and accepted)
|
|
19
|
+
- Recent feedback entries
|
|
20
|
+
|
|
21
|
+
Use this to understand what content is actually being used by AI agents
|
|
22
|
+
and where PASIFA scoring can be improved.`,
|
|
23
|
+
inputSchema: {
|
|
24
|
+
type: "object",
|
|
25
|
+
properties: {
|
|
26
|
+
days: {
|
|
27
|
+
type: "number",
|
|
28
|
+
description: "Number of days to look back (default: 30, max: 365)",
|
|
29
|
+
default: 30,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Execute the get_agent_feedback_stats tool
|
|
36
|
+
*/
|
|
37
|
+
export function executeGetAgentFeedbackStats(db, params) {
|
|
38
|
+
const days = Math.max(1, Math.min(365, params.days ?? 30));
|
|
39
|
+
return db.getAgentFeedbackStats(days);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=agent-feedback-stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-feedback-stats.js","sourceRoot":"","sources":["../../src/tools/agent-feedback-stats.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C;;;;;GAKG;AAKH;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,IAAI,EAAE,0BAA0B;IAChC,WAAW,EAAE;;;;;;;;;0CAS2B;IACxC,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,qDAAqD;gBAClE,OAAO,EAAE,EAAE;aACZ;SACF;KACF;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAC1C,EAAkB,EAClB,MAAmC;IAEnC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D,OAAO,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent_memory tool
|
|
3
|
+
*
|
|
4
|
+
* Cross-agent persistent memory. What Claude Code learns, Cursor can access.
|
|
5
|
+
* Enables AI agents to store and recall memories across sessions and tools.
|
|
6
|
+
*/
|
|
7
|
+
import type { FourDADatabase } from "../db.js";
|
|
8
|
+
export interface AgentMemoryParams {
|
|
9
|
+
action: "store" | "recall" | "recall_by_tags" | "get_recent";
|
|
10
|
+
session_id?: string;
|
|
11
|
+
agent_type?: string;
|
|
12
|
+
memory_type?: string;
|
|
13
|
+
subject?: string;
|
|
14
|
+
content?: string;
|
|
15
|
+
context_tags?: string[];
|
|
16
|
+
expires_at?: string;
|
|
17
|
+
query?: string;
|
|
18
|
+
filter_agent?: string;
|
|
19
|
+
limit?: number;
|
|
20
|
+
tags?: string[];
|
|
21
|
+
since?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare const agentMemoryTool: {
|
|
24
|
+
name: string;
|
|
25
|
+
description: string;
|
|
26
|
+
inputSchema: {
|
|
27
|
+
type: "object";
|
|
28
|
+
properties: {
|
|
29
|
+
action: {
|
|
30
|
+
type: string;
|
|
31
|
+
enum: string[];
|
|
32
|
+
description: string;
|
|
33
|
+
};
|
|
34
|
+
session_id: {
|
|
35
|
+
type: string;
|
|
36
|
+
description: string;
|
|
37
|
+
};
|
|
38
|
+
agent_type: {
|
|
39
|
+
type: string;
|
|
40
|
+
description: string;
|
|
41
|
+
};
|
|
42
|
+
memory_type: {
|
|
43
|
+
type: string;
|
|
44
|
+
enum: string[];
|
|
45
|
+
description: string;
|
|
46
|
+
};
|
|
47
|
+
subject: {
|
|
48
|
+
type: string;
|
|
49
|
+
description: string;
|
|
50
|
+
};
|
|
51
|
+
content: {
|
|
52
|
+
type: string;
|
|
53
|
+
description: string;
|
|
54
|
+
};
|
|
55
|
+
context_tags: {
|
|
56
|
+
type: string;
|
|
57
|
+
items: {
|
|
58
|
+
type: string;
|
|
59
|
+
};
|
|
60
|
+
description: string;
|
|
61
|
+
};
|
|
62
|
+
expires_at: {
|
|
63
|
+
type: string;
|
|
64
|
+
description: string;
|
|
65
|
+
};
|
|
66
|
+
query: {
|
|
67
|
+
type: string;
|
|
68
|
+
description: string;
|
|
69
|
+
};
|
|
70
|
+
filter_agent: {
|
|
71
|
+
type: string;
|
|
72
|
+
description: string;
|
|
73
|
+
};
|
|
74
|
+
limit: {
|
|
75
|
+
type: string;
|
|
76
|
+
description: string;
|
|
77
|
+
};
|
|
78
|
+
tags: {
|
|
79
|
+
type: string;
|
|
80
|
+
items: {
|
|
81
|
+
type: string;
|
|
82
|
+
};
|
|
83
|
+
description: string;
|
|
84
|
+
};
|
|
85
|
+
since: {
|
|
86
|
+
type: string;
|
|
87
|
+
description: string;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
required: string[];
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
export declare function executeAgentMemory(db: FourDADatabase, params: AgentMemoryParams): object;
|
|
94
|
+
//# sourceMappingURL=agent-memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-memory.d.ts","sourceRoot":"","sources":["../../src/tools/agent-memory.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAM/C,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,gBAAgB,GAAG,YAAY,CAAC;IAE7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAmBD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmE3B,CAAC;AAkCF,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,cAAc,EAClB,MAAM,EAAE,iBAAiB,GACxB,MAAM,CA+LR"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
// SPDX-License-Identifier: FSL-1.1-Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* agent_memory tool
|
|
4
|
+
*
|
|
5
|
+
* Cross-agent persistent memory. What Claude Code learns, Cursor can access.
|
|
6
|
+
* Enables AI agents to store and recall memories across sessions and tools.
|
|
7
|
+
*/
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Tool Definition
|
|
10
|
+
// ============================================================================
|
|
11
|
+
export const agentMemoryTool = {
|
|
12
|
+
name: "agent_memory",
|
|
13
|
+
description: "Cross-agent persistent memory. Actions: store (save a memory), recall (search by subject), recall_by_tags (search by tags), get_recent (memories since timestamp). What one agent learns, all agents can access.",
|
|
14
|
+
inputSchema: {
|
|
15
|
+
type: "object",
|
|
16
|
+
properties: {
|
|
17
|
+
action: {
|
|
18
|
+
type: "string",
|
|
19
|
+
enum: ["store", "recall", "recall_by_tags", "get_recent"],
|
|
20
|
+
description: "Action to perform",
|
|
21
|
+
},
|
|
22
|
+
session_id: {
|
|
23
|
+
type: "string",
|
|
24
|
+
description: "Session identifier (for store)",
|
|
25
|
+
},
|
|
26
|
+
agent_type: {
|
|
27
|
+
type: "string",
|
|
28
|
+
description: "Agent identifier, e.g. claude_code, cursor, windsurf (for store)",
|
|
29
|
+
},
|
|
30
|
+
memory_type: {
|
|
31
|
+
type: "string",
|
|
32
|
+
enum: ["discovery", "decision", "context", "warning", "preference"],
|
|
33
|
+
description: "Type of memory (for store). Default: context",
|
|
34
|
+
},
|
|
35
|
+
subject: {
|
|
36
|
+
type: "string",
|
|
37
|
+
description: "Short subject line for the memory (for store)",
|
|
38
|
+
},
|
|
39
|
+
content: {
|
|
40
|
+
type: "string",
|
|
41
|
+
description: "Full memory content (for store)",
|
|
42
|
+
},
|
|
43
|
+
context_tags: {
|
|
44
|
+
type: "array",
|
|
45
|
+
items: { type: "string" },
|
|
46
|
+
description: "Tags for categorization (for store)",
|
|
47
|
+
},
|
|
48
|
+
expires_at: {
|
|
49
|
+
type: "string",
|
|
50
|
+
description: "ISO datetime when this memory expires (for store, optional)",
|
|
51
|
+
},
|
|
52
|
+
query: {
|
|
53
|
+
type: "string",
|
|
54
|
+
description: "Search term to match against subject and tags (for recall)",
|
|
55
|
+
},
|
|
56
|
+
filter_agent: {
|
|
57
|
+
type: "string",
|
|
58
|
+
description: "Filter results to a specific agent type (for recall, get_recent)",
|
|
59
|
+
},
|
|
60
|
+
limit: {
|
|
61
|
+
type: "number",
|
|
62
|
+
description: "Max results to return (default 20)",
|
|
63
|
+
},
|
|
64
|
+
tags: {
|
|
65
|
+
type: "array",
|
|
66
|
+
items: { type: "string" },
|
|
67
|
+
description: "Tags to search for (for recall_by_tags)",
|
|
68
|
+
},
|
|
69
|
+
since: {
|
|
70
|
+
type: "string",
|
|
71
|
+
description: "ISO datetime to get memories after (for get_recent)",
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
required: ["action"],
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// Size Limits
|
|
79
|
+
// ============================================================================
|
|
80
|
+
/** Maximum content size per entry: 10KB */
|
|
81
|
+
const MAX_CONTENT_BYTES = 10 * 1024;
|
|
82
|
+
/** Maximum entries per agent */
|
|
83
|
+
const MAX_ENTRIES_PER_AGENT = 1000;
|
|
84
|
+
// ============================================================================
|
|
85
|
+
// Helpers
|
|
86
|
+
// ============================================================================
|
|
87
|
+
function parseMemoryRow(row) {
|
|
88
|
+
return {
|
|
89
|
+
id: row.id,
|
|
90
|
+
session_id: row.session_id,
|
|
91
|
+
agent_type: row.agent_type,
|
|
92
|
+
memory_type: row.memory_type,
|
|
93
|
+
subject: row.subject,
|
|
94
|
+
content: row.content,
|
|
95
|
+
context_tags: JSON.parse(row.context_tags || "[]"),
|
|
96
|
+
created_at: row.created_at,
|
|
97
|
+
expires_at: row.expires_at,
|
|
98
|
+
promoted_to_decision_id: row.promoted_to_decision_id,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// ============================================================================
|
|
102
|
+
// Execute
|
|
103
|
+
// ============================================================================
|
|
104
|
+
export function executeAgentMemory(db, params) {
|
|
105
|
+
const rawDb = db.getRawDb();
|
|
106
|
+
switch (params.action) {
|
|
107
|
+
// ========================================================================
|
|
108
|
+
// STORE
|
|
109
|
+
// ========================================================================
|
|
110
|
+
case "store": {
|
|
111
|
+
if (!params.subject || !params.content) {
|
|
112
|
+
return { error: "subject and content are required for store action" };
|
|
113
|
+
}
|
|
114
|
+
// --- Size limit: max 10KB per entry ---
|
|
115
|
+
const contentBytes = new TextEncoder().encode(params.content).length;
|
|
116
|
+
if (contentBytes > MAX_CONTENT_BYTES) {
|
|
117
|
+
return {
|
|
118
|
+
error: `Content too large: ${contentBytes} bytes exceeds ${MAX_CONTENT_BYTES} byte limit (10KB)`,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
// --- Storage quota: max 1000 entries per agent ---
|
|
122
|
+
const agentType = params.agent_type || "unknown";
|
|
123
|
+
try {
|
|
124
|
+
const countRow = rawDb
|
|
125
|
+
.prepare(`SELECT COUNT(*) as cnt FROM agent_memory WHERE agent_type = ?`)
|
|
126
|
+
.get(agentType);
|
|
127
|
+
const currentCount = countRow?.cnt ?? 0;
|
|
128
|
+
if (currentCount >= MAX_ENTRIES_PER_AGENT) {
|
|
129
|
+
return {
|
|
130
|
+
error: `Storage quota exceeded: agent "${agentType}" has ${currentCount} entries (max ${MAX_ENTRIES_PER_AGENT}). Delete old entries before storing new ones.`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (quotaErr) {
|
|
135
|
+
return {
|
|
136
|
+
error: `Failed to check storage quota: ${quotaErr instanceof Error ? quotaErr.message : String(quotaErr)}`,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
const stmt = rawDb.prepare(`INSERT INTO agent_memory
|
|
141
|
+
(session_id, agent_type, memory_type, subject, content, context_tags, expires_at)
|
|
142
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`);
|
|
143
|
+
const result = stmt.run(params.session_id || "unknown", params.agent_type || "unknown", params.memory_type || "context", params.subject, params.content, JSON.stringify(params.context_tags || []), params.expires_at || null);
|
|
144
|
+
return {
|
|
145
|
+
success: true,
|
|
146
|
+
id: result.lastInsertRowid,
|
|
147
|
+
message: `Memory stored: ${params.subject}`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
return {
|
|
152
|
+
error: `Failed to store memory: ${error instanceof Error ? error.message : String(error)}`,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// ========================================================================
|
|
157
|
+
// RECALL
|
|
158
|
+
// ========================================================================
|
|
159
|
+
case "recall": {
|
|
160
|
+
if (!params.query) {
|
|
161
|
+
return { error: "query is required for recall action" };
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
const pattern = `%${params.query.toLowerCase()}%`;
|
|
165
|
+
let sql = `SELECT id, session_id, agent_type, memory_type, subject, content,
|
|
166
|
+
context_tags, created_at, expires_at, promoted_to_decision_id
|
|
167
|
+
FROM agent_memory
|
|
168
|
+
WHERE (LOWER(subject) LIKE ? OR LOWER(context_tags) LIKE ?)
|
|
169
|
+
AND (expires_at IS NULL OR expires_at > datetime('now'))`;
|
|
170
|
+
const sqlParams = [pattern, pattern];
|
|
171
|
+
if (params.filter_agent) {
|
|
172
|
+
sql += ` AND agent_type = ?`;
|
|
173
|
+
sqlParams.push(params.filter_agent);
|
|
174
|
+
}
|
|
175
|
+
sql += ` ORDER BY created_at DESC LIMIT ?`;
|
|
176
|
+
sqlParams.push(params.limit || 20);
|
|
177
|
+
const rows = rawDb.prepare(sql).all(...sqlParams);
|
|
178
|
+
return {
|
|
179
|
+
memories: rows.map(parseMemoryRow),
|
|
180
|
+
count: rows.length,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
return {
|
|
185
|
+
memories: [],
|
|
186
|
+
count: 0,
|
|
187
|
+
error: `Failed to recall memories: ${error instanceof Error ? error.message : String(error)}`,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// ========================================================================
|
|
192
|
+
// RECALL BY TAGS
|
|
193
|
+
// ========================================================================
|
|
194
|
+
case "recall_by_tags": {
|
|
195
|
+
if (!params.tags || params.tags.length === 0) {
|
|
196
|
+
return { error: "tags array is required for recall_by_tags action" };
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
// Build OR conditions for each tag
|
|
200
|
+
const conditions = params.tags.map(() => `LOWER(context_tags) LIKE ?`);
|
|
201
|
+
const tagParams = params.tags.map((t) => `%${t.toLowerCase()}%`);
|
|
202
|
+
const sql = `SELECT id, session_id, agent_type, memory_type, subject, content,
|
|
203
|
+
context_tags, created_at, expires_at, promoted_to_decision_id
|
|
204
|
+
FROM agent_memory
|
|
205
|
+
WHERE (${conditions.join(" OR ")})
|
|
206
|
+
AND (expires_at IS NULL OR expires_at > datetime('now'))
|
|
207
|
+
ORDER BY created_at DESC LIMIT ?`;
|
|
208
|
+
const rows = rawDb
|
|
209
|
+
.prepare(sql)
|
|
210
|
+
.all(...tagParams, params.limit || 20);
|
|
211
|
+
return {
|
|
212
|
+
memories: rows.map(parseMemoryRow),
|
|
213
|
+
count: rows.length,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
return {
|
|
218
|
+
memories: [],
|
|
219
|
+
count: 0,
|
|
220
|
+
error: `Failed to recall by tags: ${error instanceof Error ? error.message : String(error)}`,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// ========================================================================
|
|
225
|
+
// GET RECENT
|
|
226
|
+
// ========================================================================
|
|
227
|
+
case "get_recent": {
|
|
228
|
+
const since = params.since ||
|
|
229
|
+
new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
|
|
230
|
+
try {
|
|
231
|
+
let sql = `SELECT id, session_id, agent_type, memory_type, subject, content,
|
|
232
|
+
context_tags, created_at, expires_at, promoted_to_decision_id
|
|
233
|
+
FROM agent_memory
|
|
234
|
+
WHERE created_at > ?`;
|
|
235
|
+
const sqlParams = [since];
|
|
236
|
+
if (params.filter_agent) {
|
|
237
|
+
sql += ` AND agent_type = ?`;
|
|
238
|
+
sqlParams.push(params.filter_agent);
|
|
239
|
+
}
|
|
240
|
+
sql += ` ORDER BY created_at DESC LIMIT ?`;
|
|
241
|
+
sqlParams.push(params.limit || 50);
|
|
242
|
+
const rows = rawDb.prepare(sql).all(...sqlParams);
|
|
243
|
+
return {
|
|
244
|
+
memories: rows.map(parseMemoryRow),
|
|
245
|
+
count: rows.length,
|
|
246
|
+
since,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
return {
|
|
251
|
+
memories: [],
|
|
252
|
+
count: 0,
|
|
253
|
+
since,
|
|
254
|
+
error: `Failed to get recent memories: ${error instanceof Error ? error.message : String(error)}`,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
default:
|
|
259
|
+
return { error: `Unknown action: ${params.action}` };
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=agent-memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-memory.js","sourceRoot":"","sources":["../../src/tools/agent-memory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent_session_brief tool
|
|
3
|
+
*
|
|
4
|
+
* Tailored session startup context for AI agents.
|
|
5
|
+
* Call at the START of every agent session to get caught up on:
|
|
6
|
+
* - Active developer decisions
|
|
7
|
+
* - Ecosystem changes (security, breaking, releases)
|
|
8
|
+
* - Recent agent memories from all agents
|
|
9
|
+
* - Latest briefing text
|
|
10
|
+
*/
|
|
11
|
+
import type { FourDADatabase } from "../db.js";
|
|
12
|
+
export interface AgentSessionBriefParams {
|
|
13
|
+
agent_type?: string;
|
|
14
|
+
since?: string;
|
|
15
|
+
include_decisions?: boolean;
|
|
16
|
+
include_memories?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare const agentSessionBriefTool: {
|
|
19
|
+
name: string;
|
|
20
|
+
description: string;
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: "object";
|
|
23
|
+
properties: {
|
|
24
|
+
agent_type: {
|
|
25
|
+
type: string;
|
|
26
|
+
description: string;
|
|
27
|
+
};
|
|
28
|
+
since: {
|
|
29
|
+
type: string;
|
|
30
|
+
description: string;
|
|
31
|
+
};
|
|
32
|
+
include_decisions: {
|
|
33
|
+
type: string;
|
|
34
|
+
description: string;
|
|
35
|
+
};
|
|
36
|
+
include_memories: {
|
|
37
|
+
type: string;
|
|
38
|
+
description: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export declare function executeAgentSessionBrief(db: FourDADatabase, params: AgentSessionBriefParams): object;
|
|
44
|
+
//# sourceMappingURL=agent-session-brief.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-session-brief.d.ts","sourceRoot":"","sources":["../../src/tools/agent-session-brief.ts"],"names":[],"mappings":"AACA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAM/C,MAAM,WAAW,uBAAuB;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAmCD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;CA2BjC,CAAC;AAMF,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,cAAc,EAClB,MAAM,EAAE,uBAAuB,GAC9B,MAAM,CAwJR"}
|