@tenex-chat/backend 0.9.5 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/daemon-wrapper.cjs +34 -0
- package/dist/index.js +59268 -0
- package/dist/wrapper.js +171 -0
- package/package.json +19 -27
- package/src/agents/AgentRegistry.ts +9 -7
- package/src/agents/AgentStorage.ts +24 -1
- package/src/agents/agent-installer.ts +6 -0
- package/src/agents/agent-loader.ts +7 -2
- package/src/agents/constants.ts +10 -2
- package/src/agents/execution/AgentExecutor.ts +35 -6
- package/src/agents/execution/StreamCallbacks.ts +53 -13
- package/src/agents/execution/StreamExecutionHandler.ts +110 -16
- package/src/agents/execution/StreamSetup.ts +19 -9
- package/src/agents/execution/ToolEventHandlers.ts +112 -0
- package/src/agents/role-categories.ts +53 -0
- package/src/agents/types/runtime.ts +7 -0
- package/src/agents/types/storage.ts +7 -0
- package/src/commands/agent/import/openclaw-distiller.ts +63 -7
- package/src/commands/agent/import/openclaw-reader.ts +54 -0
- package/src/commands/agent/import/openclaw.ts +120 -29
- package/src/commands/agent/index.ts +83 -2
- package/src/commands/setup/display.ts +123 -0
- package/src/commands/setup/embed.ts +13 -13
- package/src/commands/setup/global-system-prompt.ts +15 -17
- package/src/commands/setup/image.ts +17 -20
- package/src/commands/setup/interactive.ts +37 -20
- package/src/commands/setup/llm.ts +12 -7
- package/src/commands/setup/onboarding.ts +1580 -248
- package/src/commands/setup/providers.ts +3 -3
- package/src/conversations/ConversationStore.ts +23 -2
- package/src/conversations/MessageBuilder.ts +51 -73
- package/src/conversations/formatters/utils/conversation-transcript-formatter.ts +425 -0
- package/src/conversations/search/embeddings/ConversationEmbeddingService.ts +40 -98
- package/src/conversations/search/embeddings/ConversationIndexingJob.ts +40 -52
- package/src/conversations/services/ConversationSummarizer.ts +1 -2
- package/src/conversations/types.ts +11 -0
- package/src/daemon/Daemon.ts +78 -57
- package/src/daemon/ProjectRuntime.ts +6 -12
- package/src/daemon/SubscriptionManager.ts +13 -0
- package/src/daemon/index.ts +0 -1
- package/src/event-handler/index.ts +1 -0
- package/src/index.ts +20 -1
- package/src/llm/ChunkHandler.ts +1 -1
- package/src/llm/FinishHandler.ts +28 -4
- package/src/llm/LLMConfigEditor.ts +218 -106
- package/src/llm/index.ts +0 -4
- package/src/llm/meta/MetaModelResolver.ts +3 -18
- package/src/llm/middleware/message-sanitizer.ts +153 -0
- package/src/llm/providers/ollama-models.ts +0 -38
- package/src/llm/service.ts +50 -15
- package/src/llm/types.ts +0 -12
- package/src/llm/utils/ConfigurationManager.ts +88 -465
- package/src/llm/utils/ConfigurationTester.ts +42 -185
- package/src/llm/utils/ModelSelector.ts +156 -92
- package/src/llm/utils/ProviderConfigUI.ts +10 -141
- package/src/llm/utils/models-dev-cache.ts +102 -23
- package/src/llm/utils/provider-select-prompt.ts +284 -0
- package/src/llm/utils/provider-setup.ts +81 -34
- package/src/llm/utils/variant-list-prompt.ts +361 -0
- package/src/nostr/AgentEventDecoder.ts +1 -0
- package/src/nostr/AgentEventEncoder.ts +37 -0
- package/src/nostr/AgentProfilePublisher.ts +13 -0
- package/src/nostr/AgentPublisher.ts +26 -0
- package/src/nostr/kinds.ts +1 -0
- package/src/nostr/ndkClient.ts +4 -1
- package/src/nostr/types.ts +12 -0
- package/src/prompts/fragments/25-rag-instructions.ts +22 -21
- package/src/prompts/fragments/31-agents-md-guidance.ts +7 -21
- package/src/prompts/fragments/index.ts +2 -0
- package/src/prompts/utils/systemPromptBuilder.ts +18 -28
- package/src/services/AgentDefinitionMonitor.ts +8 -0
- package/src/services/ConfigService.ts +34 -0
- package/src/services/PubkeyService.ts +7 -1
- package/src/services/compression/CompressionService.ts +133 -74
- package/src/services/compression/compression-utils.ts +110 -19
- package/src/services/config/types.ts +0 -6
- package/src/services/dispatch/AgentDispatchService.ts +79 -0
- package/src/services/intervention/InterventionService.ts +78 -5
- package/src/services/nip46/Nip46SigningService.ts +30 -1
- package/src/services/projects/ProjectContext.ts +8 -6
- package/src/services/rag/RAGCollectionRegistry.ts +199 -0
- package/src/services/rag/RAGDatabaseService.ts +2 -7
- package/src/services/rag/RAGOperations.ts +25 -45
- package/src/services/rag/RAGService.ts +0 -31
- package/src/services/rag/RagSubscriptionService.ts +71 -122
- package/src/services/rag/rag-utils.ts +13 -0
- package/src/services/ral/RALRegistry.ts +25 -184
- package/src/services/reports/ReportEmbeddingService.ts +63 -113
- package/src/services/search/UnifiedSearchService.ts +115 -4
- package/src/services/search/index.ts +1 -0
- package/src/services/search/projectFilter.ts +20 -4
- package/src/services/search/providers/ConversationSearchProvider.ts +1 -0
- package/src/services/search/providers/GenericCollectionSearchProvider.ts +81 -0
- package/src/services/search/providers/LessonSearchProvider.ts +1 -8
- package/src/services/search/providers/ReportSearchProvider.ts +1 -0
- package/src/services/search/types.ts +24 -3
- package/src/services/trust-pubkeys/SystemPubkeyListService.ts +148 -0
- package/src/services/trust-pubkeys/TrustPubkeyService.ts +70 -9
- package/src/telemetry/setup.ts +2 -13
- package/src/tools/implementations/ask.ts +3 -3
- package/src/tools/implementations/conversation_get.ts +28 -268
- package/src/tools/implementations/fs_grep.ts +6 -6
- package/src/tools/implementations/fs_read.ts +2 -0
- package/src/tools/implementations/fs_write.ts +2 -0
- package/src/tools/implementations/learn.ts +38 -50
- package/src/tools/implementations/rag_add_documents.ts +6 -4
- package/src/tools/implementations/rag_create_collection.ts +37 -4
- package/src/tools/implementations/rag_delete_collection.ts +9 -0
- package/src/tools/implementations/{search.ts → rag_search.ts} +31 -25
- package/src/tools/registry.ts +7 -8
- package/src/tools/types.ts +11 -2
- package/src/tools/utils/transcript-args.ts +13 -0
- package/src/utils/cli-theme.ts +13 -0
- package/src/utils/logger.ts +55 -0
- package/src/utils/metadataKeys.ts +17 -0
- package/src/utils/sqlEscaping.ts +39 -0
- package/src/wrapper.ts +7 -3
- package/dist/src/index.js +0 -46790
- package/dist/tenex-backend-wrapper.cjs +0 -3
- package/src/agents/execution/constants.ts +0 -16
- package/src/agents/execution/index.ts +0 -3
- package/src/agents/index.ts +0 -4
- package/src/commands/agent.ts +0 -235
- package/src/conversations/formatters/DelegationXmlFormatter.ts +0 -64
- package/src/conversations/formatters/index.ts +0 -9
- package/src/conversations/index.ts +0 -2
- package/src/conversations/utils/content-utils.ts +0 -69
- package/src/daemon/UnixSocketTransport.ts +0 -318
- package/src/event-handler/newConversation.ts +0 -165
- package/src/events/NDKProjectStatus.ts +0 -384
- package/src/events/index.ts +0 -4
- package/src/lib/json-parser.ts +0 -30
- package/src/llm/RecordingState.ts +0 -37
- package/src/llm/StreamPublisher.ts +0 -40
- package/src/llm/middleware/flight-recorder.ts +0 -188
- package/src/llm/utils/claudeCodePromptCompiler.ts +0 -141
- package/src/nostr/constants.ts +0 -38
- package/src/prompts/core/index.ts +0 -3
- package/src/prompts/index.ts +0 -21
- package/src/services/image/index.ts +0 -12
- package/src/services/status/index.ts +0 -11
- package/src/telemetry/diagnostics.ts +0 -27
- package/src/tools/implementations/rag_query.ts +0 -107
- package/src/types/index.ts +0 -46
- package/src/utils/agentFetcher.ts +0 -107
- package/src/utils/conversation-utils.ts +0 -1
- package/src/utils/process.ts +0 -49
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import type { ModelMessage, TextPart, ImagePart } from "ai";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Extract text content from a message content field.
|
|
5
|
-
* Handles both string content and multimodal content (TextPart + ImagePart arrays).
|
|
6
|
-
*
|
|
7
|
-
* For multimodal content, extracts the text part and notes any images.
|
|
8
|
-
*/
|
|
9
|
-
function extractTextContent(content: ModelMessage["content"]): string {
|
|
10
|
-
if (typeof content === "string") {
|
|
11
|
-
return content;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (!Array.isArray(content)) {
|
|
15
|
-
return JSON.stringify(content);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Handle multimodal content (arrays of parts)
|
|
19
|
-
const parts: string[] = [];
|
|
20
|
-
let imageCount = 0;
|
|
21
|
-
|
|
22
|
-
for (const part of content) {
|
|
23
|
-
if ((part as TextPart).type === "text") {
|
|
24
|
-
parts.push((part as TextPart).text);
|
|
25
|
-
} else if ((part as ImagePart).type === "image") {
|
|
26
|
-
imageCount++;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// If there were images, note them at the end
|
|
31
|
-
if (imageCount > 0) {
|
|
32
|
-
parts.push(`[${imageCount} image${imageCount > 1 ? "s" : ""} attached]`);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return parts.join("\n");
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* System prompt type for Claude Code.
|
|
40
|
-
* Can be a string for custom system prompt, or use preset with append for
|
|
41
|
-
* Claude Code's built-in instructions plus custom content.
|
|
42
|
-
*/
|
|
43
|
-
export type ClaudeCodeSystemPrompt = string | {
|
|
44
|
-
type: "preset";
|
|
45
|
-
preset: "claude_code";
|
|
46
|
-
append?: string;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Compiles system messages for Claude Code's systemPrompt.append.
|
|
51
|
-
* Uses the new systemPrompt API (replacing deprecated customSystemPrompt/appendSystemPrompt).
|
|
52
|
-
*
|
|
53
|
-
* IMPORTANT: Only system messages are included in systemPrompt.append.
|
|
54
|
-
* User/assistant messages are passed separately via the messages array to streamText().
|
|
55
|
-
* This separation is critical for session resumption to work correctly - if conversation
|
|
56
|
-
* history is duplicated in both systemPrompt.append AND messages, it creates a session
|
|
57
|
-
* state that can't be reconstructed on resume.
|
|
58
|
-
*
|
|
59
|
-
* Note: Multimodal content (images) is converted to text descriptions since
|
|
60
|
-
* Claude Code uses a text-based prompt compilation approach.
|
|
61
|
-
*/
|
|
62
|
-
export function compileMessagesForClaudeCode(messages: ModelMessage[]): {
|
|
63
|
-
systemPrompt?: ClaudeCodeSystemPrompt;
|
|
64
|
-
} {
|
|
65
|
-
if (messages.length === 0) {
|
|
66
|
-
return { systemPrompt: undefined };
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Extract only system messages - user/assistant go in messages array
|
|
70
|
-
const systemMessages = messages.filter((m) => m.role === "system");
|
|
71
|
-
|
|
72
|
-
if (systemMessages.length === 0) {
|
|
73
|
-
return { systemPrompt: undefined };
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Combine all system messages into the append content
|
|
77
|
-
const appendParts: string[] = [];
|
|
78
|
-
|
|
79
|
-
for (const msg of systemMessages) {
|
|
80
|
-
const content =
|
|
81
|
-
typeof msg.content === "string"
|
|
82
|
-
? msg.content
|
|
83
|
-
: extractTextContent(msg.content);
|
|
84
|
-
appendParts.push(content);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const appendContent = appendParts.join("\n\n");
|
|
88
|
-
|
|
89
|
-
// Use Claude Code's built-in preset with our system content appended
|
|
90
|
-
return {
|
|
91
|
-
systemPrompt: {
|
|
92
|
-
type: "preset",
|
|
93
|
-
preset: "claude_code",
|
|
94
|
-
append: appendContent,
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Converts system messages to user messages for active Claude Code sessions.
|
|
101
|
-
* When resuming a session, Claude Code doesn't receive new system messages,
|
|
102
|
-
* so we convert them to user messages to ensure they're delivered.
|
|
103
|
-
*
|
|
104
|
-
* Note: Multimodal content is preserved for user messages (they support images),
|
|
105
|
-
* but system messages with multimodal content are converted to text descriptions.
|
|
106
|
-
*/
|
|
107
|
-
export function convertSystemMessagesForResume(messages: ModelMessage[]): ModelMessage[] {
|
|
108
|
-
// For resuming sessions, we need to convert system messages that appear
|
|
109
|
-
// after the conversation started into user messages
|
|
110
|
-
|
|
111
|
-
// Find the first non-system message (start of conversation)
|
|
112
|
-
const conversationStartIndex = messages.findIndex((m) => m.role !== "system");
|
|
113
|
-
|
|
114
|
-
if (conversationStartIndex === -1) {
|
|
115
|
-
// All messages are system messages, no conversion needed
|
|
116
|
-
return messages;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Convert messages, preserving order
|
|
120
|
-
const convertedMessages = messages.map((msg, index) => {
|
|
121
|
-
// Keep initial system messages as-is (they were part of initial prompt)
|
|
122
|
-
if (index < conversationStartIndex) {
|
|
123
|
-
return msg;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Convert subsequent system messages to user messages with clear marker
|
|
127
|
-
if (msg.role === "system") {
|
|
128
|
-
// Use extractTextContent to handle multimodal content gracefully
|
|
129
|
-
const content = extractTextContent(msg.content);
|
|
130
|
-
return {
|
|
131
|
-
role: "user" as const,
|
|
132
|
-
content: `[System Context]: ${content}`,
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Keep user and assistant messages as-is (preserving multimodal content)
|
|
137
|
-
return msg;
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
return convertedMessages as ModelMessage[];
|
|
141
|
-
}
|
package/src/nostr/constants.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Nostr event kinds used in the application
|
|
3
|
-
*/
|
|
4
|
-
export enum NostrKind {
|
|
5
|
-
// Standard kinds
|
|
6
|
-
TEXT_NOTE = 1,
|
|
7
|
-
REACTION = 7,
|
|
8
|
-
ARTICLE = 30023,
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Standard Nostr tag names
|
|
13
|
-
*/
|
|
14
|
-
export enum NostrTag {
|
|
15
|
-
// Standard tags
|
|
16
|
-
EVENT = "e",
|
|
17
|
-
PUBKEY = "p",
|
|
18
|
-
REPLACEABLE = "a",
|
|
19
|
-
|
|
20
|
-
// Application-specific tags
|
|
21
|
-
MODE = "mode",
|
|
22
|
-
PARTICIPANT = "participant",
|
|
23
|
-
REASON = "reason",
|
|
24
|
-
TOOL = "tool",
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Tag values for specific application modes
|
|
29
|
-
*/
|
|
30
|
-
export enum TagValue {
|
|
31
|
-
REACTION_POSITIVE = "+",
|
|
32
|
-
DELEGATE = "delegate",
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Maximum lengths for various fields
|
|
37
|
-
*/
|
|
38
|
-
export const MAX_REASON_LENGTH = 200;
|
package/src/prompts/index.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// Export core functionality
|
|
2
|
-
|
|
3
|
-
export { FragmentRegistry, fragmentRegistry } from "./core/FragmentRegistry";
|
|
4
|
-
export { PromptBuilder } from "./core/PromptBuilder";
|
|
5
|
-
export type { FragmentConfig, PromptFragment } from "./core/types";
|
|
6
|
-
|
|
7
|
-
// Import all fragments to ensure they're registered when the module is imported
|
|
8
|
-
// Priority 01 - Identity
|
|
9
|
-
import "./fragments/01-agent-identity";
|
|
10
|
-
|
|
11
|
-
// Priority 10 - Early context
|
|
12
|
-
import "./fragments/10-referenced-article"; // Conditional
|
|
13
|
-
|
|
14
|
-
// Priority 15 - Available agents
|
|
15
|
-
import "./fragments/15-available-agents";
|
|
16
|
-
|
|
17
|
-
// Priority 20 - Mode context
|
|
18
|
-
import "./fragments/20-voice-mode"; // Conditional
|
|
19
|
-
|
|
20
|
-
// Priority 24 - Lessons
|
|
21
|
-
import "./fragments/24-retrieved-lessons"; // Shared
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
ImageGenerationService,
|
|
3
|
-
type ImageConfig,
|
|
4
|
-
type ImageGenerationOptions,
|
|
5
|
-
type ImageResult,
|
|
6
|
-
type ImageConfigOptions,
|
|
7
|
-
type AspectRatio,
|
|
8
|
-
type ImageSize,
|
|
9
|
-
OPENROUTER_IMAGE_MODELS,
|
|
10
|
-
ASPECT_RATIOS,
|
|
11
|
-
IMAGE_SIZES,
|
|
12
|
-
} from "./ImageGenerationService";
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Status Publishing Services
|
|
3
|
-
*
|
|
4
|
-
* Handles broadcasting of status events for daemon, projects, and operations
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
// Project status (single project context)
|
|
8
|
-
export { ProjectStatusService } from "./ProjectStatusService";
|
|
9
|
-
|
|
10
|
-
// Operations status (LLM operations)
|
|
11
|
-
export { OperationsStatusService } from "./OperationsStatusService";
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Diagnostics Configuration - Feature flag for diagnostic instrumentation
|
|
3
|
-
*
|
|
4
|
-
* Controls whether detailed diagnostic telemetry is collected.
|
|
5
|
-
* Disable in production for performance; enable when investigating issues.
|
|
6
|
-
*
|
|
7
|
-
* Set TENEX_DIAGNOSTICS=true to enable all diagnostic instrumentation.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Check if diagnostics are enabled via environment variable.
|
|
12
|
-
* Caches the result at module load time.
|
|
13
|
-
*/
|
|
14
|
-
export function isDiagnosticsEnabled(): boolean {
|
|
15
|
-
return process.env.TENEX_DIAGNOSTICS === "true";
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Get the diagnostics enabled state (for logging/tracing).
|
|
20
|
-
*/
|
|
21
|
-
export function getDiagnosticsState(): { enabled: boolean; source: string } {
|
|
22
|
-
const enabled = isDiagnosticsEnabled();
|
|
23
|
-
return {
|
|
24
|
-
enabled,
|
|
25
|
-
source: enabled ? "TENEX_DIAGNOSTICS=true" : "default (disabled)",
|
|
26
|
-
};
|
|
27
|
-
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import type { ToolExecutionContext } from "@/tools/types";
|
|
2
|
-
import { type RAGQueryResult, RAGService } from "@/services/rag/RAGService";
|
|
3
|
-
import type { AISdkTool } from "@/tools/types";
|
|
4
|
-
import { type ToolResponse, executeToolWithErrorHandling } from "@/tools/utils";
|
|
5
|
-
import { tool } from "ai";
|
|
6
|
-
import { z } from "zod";
|
|
7
|
-
|
|
8
|
-
const ragQuerySchema = z.object({
|
|
9
|
-
description: z
|
|
10
|
-
.string()
|
|
11
|
-
.trim()
|
|
12
|
-
.min(1, "Description is required and cannot be empty")
|
|
13
|
-
.describe(
|
|
14
|
-
"REQUIRED: A clear, concise description of why you're querying this collection (5-10 words). Helps provide human-readable context for the operation."
|
|
15
|
-
),
|
|
16
|
-
collection: z.string().describe("Name of the collection to query"),
|
|
17
|
-
query_text: z.string().describe("The text query for semantic search"),
|
|
18
|
-
top_k: z
|
|
19
|
-
.number()
|
|
20
|
-
.int()
|
|
21
|
-
.min(1)
|
|
22
|
-
.max(100)
|
|
23
|
-
.optional()
|
|
24
|
-
.describe("Number of top results to return (default: 5, range: 1-100)"),
|
|
25
|
-
include_metadata: z
|
|
26
|
-
.boolean()
|
|
27
|
-
.optional()
|
|
28
|
-
.describe("Whether to include document metadata in results (default: true)"),
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Formatted result for tool response
|
|
33
|
-
*/
|
|
34
|
-
interface FormattedQueryResult {
|
|
35
|
-
rank: number;
|
|
36
|
-
score: number;
|
|
37
|
-
content: string;
|
|
38
|
-
metadata?: Record<string, unknown>;
|
|
39
|
-
source?: string;
|
|
40
|
-
id?: string;
|
|
41
|
-
timestamp?: string;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Format query results for response
|
|
46
|
-
*/
|
|
47
|
-
function formatResults(
|
|
48
|
-
results: RAGQueryResult[],
|
|
49
|
-
includeMetadata: boolean
|
|
50
|
-
): FormattedQueryResult[] {
|
|
51
|
-
return results.map((result, index) => ({
|
|
52
|
-
rank: index + 1,
|
|
53
|
-
score: result.score,
|
|
54
|
-
content:
|
|
55
|
-
result.document.content.length > 500
|
|
56
|
-
? `${result.document.content.substring(0, 500)}...`
|
|
57
|
-
: result.document.content,
|
|
58
|
-
...(includeMetadata && {
|
|
59
|
-
metadata: result.document.metadata,
|
|
60
|
-
source: result.document.source,
|
|
61
|
-
id: result.document.id,
|
|
62
|
-
timestamp: result.document.timestamp
|
|
63
|
-
? new Date(result.document.timestamp).toISOString()
|
|
64
|
-
: undefined,
|
|
65
|
-
}),
|
|
66
|
-
}));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Core implementation of RAG semantic search
|
|
71
|
-
*/
|
|
72
|
-
async function executeQuery(
|
|
73
|
-
input: z.infer<typeof ragQuerySchema>,
|
|
74
|
-
_context: ToolExecutionContext
|
|
75
|
-
): Promise<ToolResponse> {
|
|
76
|
-
const { collection, query_text } = input;
|
|
77
|
-
|
|
78
|
-
// Use provided top_k or default to 5
|
|
79
|
-
// The schema already validates the range (1-100) and integer constraint
|
|
80
|
-
const topK = input.top_k ?? 5;
|
|
81
|
-
const includeMetadata = input.include_metadata ?? true;
|
|
82
|
-
|
|
83
|
-
const ragService = RAGService.getInstance();
|
|
84
|
-
const results = await ragService.query(collection, query_text, topK);
|
|
85
|
-
|
|
86
|
-
return {
|
|
87
|
-
success: true,
|
|
88
|
-
collection: collection,
|
|
89
|
-
query: query_text,
|
|
90
|
-
results_count: results.length,
|
|
91
|
-
results: formatResults(results, includeMetadata),
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Query a RAG collection using semantic search
|
|
97
|
-
*/
|
|
98
|
-
export function createRAGQueryTool(context: ToolExecutionContext): AISdkTool {
|
|
99
|
-
return tool({
|
|
100
|
-
description:
|
|
101
|
-
"Perform semantic search on a RAG collection. Returns the most relevant documents based on vector similarity to the query.",
|
|
102
|
-
inputSchema: ragQuerySchema,
|
|
103
|
-
execute: async (input: unknown) => {
|
|
104
|
-
return executeToolWithErrorHandling("rag_query", input as z.infer<typeof ragQuerySchema>, context, executeQuery);
|
|
105
|
-
},
|
|
106
|
-
}) as AISdkTool;
|
|
107
|
-
}
|
package/src/types/index.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Types barrel export
|
|
3
|
-
*
|
|
4
|
-
* Centralized exports for all custom types used throughout the system.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
// Event ID types and utilities
|
|
8
|
-
export {
|
|
9
|
-
// Branded types
|
|
10
|
-
type FullEventId,
|
|
11
|
-
type ShortEventId,
|
|
12
|
-
type ShellTaskId,
|
|
13
|
-
type AnyEventId,
|
|
14
|
-
type AnyTaskId,
|
|
15
|
-
|
|
16
|
-
// Constants
|
|
17
|
-
FULL_EVENT_ID_LENGTH,
|
|
18
|
-
SHORT_EVENT_ID_LENGTH,
|
|
19
|
-
SHELL_TASK_ID_LENGTH,
|
|
20
|
-
|
|
21
|
-
// Type guards
|
|
22
|
-
isFullEventId,
|
|
23
|
-
isShortEventId,
|
|
24
|
-
isShellTaskId,
|
|
25
|
-
detectIdType,
|
|
26
|
-
|
|
27
|
-
// Factory functions
|
|
28
|
-
createFullEventId,
|
|
29
|
-
createShortEventId,
|
|
30
|
-
createShellTaskId,
|
|
31
|
-
tryCreateFullEventId,
|
|
32
|
-
tryCreateShortEventId,
|
|
33
|
-
tryCreateShellTaskId,
|
|
34
|
-
|
|
35
|
-
// Conversion functions
|
|
36
|
-
shortenEventId,
|
|
37
|
-
toRawString,
|
|
38
|
-
|
|
39
|
-
// Assertion functions
|
|
40
|
-
assertFullEventId,
|
|
41
|
-
assertShortEventId,
|
|
42
|
-
assertShellTaskId,
|
|
43
|
-
|
|
44
|
-
// Utility functions
|
|
45
|
-
parseEventId,
|
|
46
|
-
} from "./event-ids";
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import type NDK from "@nostr-dev-kit/ndk";
|
|
2
|
-
import type { NDKEvent } from "@nostr-dev-kit/ndk";
|
|
3
|
-
import { NDKAgentDefinition, type ETagReference } from "@/events/NDKAgentDefinition";
|
|
4
|
-
import { logger } from "./logger";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Represents the parsed data from an agent definition event.
|
|
8
|
-
* Contains all fields needed to instantiate or display an agent.
|
|
9
|
-
*/
|
|
10
|
-
export interface AgentDefinitionData {
|
|
11
|
-
/** The Nostr event ID of the agent definition */
|
|
12
|
-
id: string;
|
|
13
|
-
/** The slug identifier (d-tag) for versioning */
|
|
14
|
-
slug: string | undefined;
|
|
15
|
-
/** Display name of the agent */
|
|
16
|
-
title: string;
|
|
17
|
-
/** Short one-liner description */
|
|
18
|
-
description: string;
|
|
19
|
-
/** Extended markdown description from content field */
|
|
20
|
-
markdownDescription: string | undefined;
|
|
21
|
-
/** The agent's role/personality */
|
|
22
|
-
role: string;
|
|
23
|
-
/** Detailed operational instructions */
|
|
24
|
-
instructions: string;
|
|
25
|
-
/** Criteria for when to use this agent */
|
|
26
|
-
useCriteria: string;
|
|
27
|
-
/** Version number of the agent definition */
|
|
28
|
-
version: number;
|
|
29
|
-
/** Unix timestamp when the event was created */
|
|
30
|
-
created_at: number | undefined;
|
|
31
|
-
/** Pubkey of the agent definition author */
|
|
32
|
-
pubkey: string;
|
|
33
|
-
/** References to bundled file metadata events */
|
|
34
|
-
fileETags: ETagReference[];
|
|
35
|
-
/** Reference to the source agent if this is a fork */
|
|
36
|
-
forkSource: ETagReference | undefined;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Fetches an agent event from Nostr
|
|
41
|
-
* @param eventId - The ID of the event containing the agent
|
|
42
|
-
* @param ndk - The NDK instance to use for fetching
|
|
43
|
-
* @returns The agent event or null if not found
|
|
44
|
-
*/
|
|
45
|
-
export async function fetchAgent(eventId: string, ndk: NDK): Promise<NDKEvent | null> {
|
|
46
|
-
try {
|
|
47
|
-
// Strip "nostr:" prefix if present
|
|
48
|
-
const cleanEventId = eventId.startsWith("nostr:") ? eventId.substring(6) : eventId;
|
|
49
|
-
|
|
50
|
-
const event = await ndk.fetchEvent(cleanEventId, { groupable: false });
|
|
51
|
-
|
|
52
|
-
if (!event) {
|
|
53
|
-
logger.debug(`Agent event not found: ${cleanEventId}`);
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return event;
|
|
58
|
-
} catch (error) {
|
|
59
|
-
logger.error(`Failed to fetch agent event: ${eventId}`, error);
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Fetches an agent definition from a Nostr event
|
|
66
|
-
* @param eventId - The ID of the event containing the agent definition
|
|
67
|
-
* @param ndk - The NDK instance to use for fetching
|
|
68
|
-
* @returns The agent definition data or null if not found
|
|
69
|
-
*/
|
|
70
|
-
export async function fetchAgentDefinition(
|
|
71
|
-
eventId: string,
|
|
72
|
-
ndk: NDK
|
|
73
|
-
): Promise<AgentDefinitionData | null> {
|
|
74
|
-
try {
|
|
75
|
-
// Strip "nostr:" prefix if present
|
|
76
|
-
const cleanEventId = eventId.startsWith("nostr:") ? eventId.substring(6) : eventId;
|
|
77
|
-
|
|
78
|
-
const event = await ndk.fetchEvent(cleanEventId, { groupable: false });
|
|
79
|
-
|
|
80
|
-
if (!event) {
|
|
81
|
-
logger.warning(`Agent event not found: ${cleanEventId}`);
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Use NDKAgentDefinition for proper parsing
|
|
86
|
-
const agentDef = NDKAgentDefinition.from(event);
|
|
87
|
-
|
|
88
|
-
return {
|
|
89
|
-
id: event.id,
|
|
90
|
-
slug: agentDef.slug,
|
|
91
|
-
title: agentDef.title || "Unnamed Agent",
|
|
92
|
-
description: agentDef.description || "",
|
|
93
|
-
markdownDescription: agentDef.markdownDescription,
|
|
94
|
-
role: agentDef.role || "assistant",
|
|
95
|
-
instructions: agentDef.instructions || "",
|
|
96
|
-
useCriteria: agentDef.useCriteria || "",
|
|
97
|
-
version: agentDef.version,
|
|
98
|
-
created_at: event.created_at,
|
|
99
|
-
pubkey: event.pubkey,
|
|
100
|
-
fileETags: agentDef.getFileETags(),
|
|
101
|
-
forkSource: agentDef.getForkSource(),
|
|
102
|
-
};
|
|
103
|
-
} catch (error) {
|
|
104
|
-
logger.error(`Failed to fetch agent event: ${eventId}`, error);
|
|
105
|
-
return null;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
// Conversation utility functions
|
package/src/utils/process.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { logger } from "@/utils/logger";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Handler function called during graceful shutdown
|
|
5
|
-
*/
|
|
6
|
-
export type ShutdownHandler = (signal: string) => Promise<void>;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Sets up graceful shutdown handlers for various termination signals
|
|
10
|
-
* @param shutdownHandler - Async function to handle cleanup during shutdown
|
|
11
|
-
* @description Handles SIGTERM, SIGINT, SIGHUP signals and uncaught exceptions/rejections
|
|
12
|
-
*/
|
|
13
|
-
export function setupGracefulShutdown(shutdownHandler: ShutdownHandler): void {
|
|
14
|
-
let isShuttingDown = false;
|
|
15
|
-
|
|
16
|
-
const shutdown = async (signal: string): Promise<void> => {
|
|
17
|
-
if (isShuttingDown) return;
|
|
18
|
-
isShuttingDown = true;
|
|
19
|
-
|
|
20
|
-
logger.info(`Received ${signal}, shutting down gracefully...`);
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
await shutdownHandler(signal);
|
|
24
|
-
logger.info("Shutdown complete");
|
|
25
|
-
process.exit(0);
|
|
26
|
-
} catch (error) {
|
|
27
|
-
logger.error("Error during shutdown", { error });
|
|
28
|
-
process.exit(1);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
// Handle various termination signals
|
|
33
|
-
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
34
|
-
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
35
|
-
process.on("SIGHUP", () => shutdown("SIGHUP"));
|
|
36
|
-
|
|
37
|
-
// Handle uncaught errors
|
|
38
|
-
process.on("uncaughtException", (error) => {
|
|
39
|
-
logger.error("Uncaught exception", { error });
|
|
40
|
-
shutdown("uncaughtException");
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
process.on("unhandledRejection", (reason, promise) => {
|
|
44
|
-
logger.error("Unhandled rejection", { reason, promise });
|
|
45
|
-
// Don't shutdown for unhandled rejections - they're usually not critical
|
|
46
|
-
// e.g., relay rejections like "replaced: have newer event"
|
|
47
|
-
// Let the daemon's handler deal with these instead
|
|
48
|
-
});
|
|
49
|
-
}
|