-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgetPrompt.ts
More file actions
128 lines (102 loc) · 3.81 KB
/
Copy pathgetPrompt.ts
File metadata and controls
128 lines (102 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import type { Options } from "@anthropic-ai/claude-agent-sdk"
import { readFileSync } from "node:fs"
import { dirname, resolve } from "node:path"
import { fileURLToPath } from "node:url"
import type { AgentChatConfig, McpServerStatus } from "store"
const __dirname = dirname(fileURLToPath(import.meta.url))
export const getPrompt = (filename: string) => {
return async (): Promise<string> => {
const path = resolve(__dirname, "../prompts", filename)
return readFileSync(path, "utf-8").trim()
}
}
interface BuildSystemPromptProps {
config: AgentChatConfig
additionalSystemPrompt?: string
inferredServers?: Set<string>
mcpServers?: McpServerStatus[]
}
export const buildSystemPrompt = async ({
config,
additionalSystemPrompt = "",
inferredServers = new Set(),
mcpServers = [],
}: BuildSystemPromptProps): Promise<Options["systemPrompt"]> => {
const currentDate = new Date().toLocaleDateString("en-US", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
})
const dateHeader = `Current date: ${currentDate}`
const basePrompt = config.systemPrompt
? await config.systemPrompt()
: "You are a helpful agent."
const mcpPromptEntries = await Promise.all(
Object.entries(config.mcpServers)
.filter(
([_, serverConfig]) =>
serverConfig.enabled !== false && serverConfig.prompt
)
.map(async ([name, serverConfig]) => {
const prompt = serverConfig.prompt ? await serverConfig.prompt() : ""
return `# ${name} MCP Server\n\n${prompt}`
})
)
const mcpPrompts = mcpPromptEntries.join("\n\n")
const parts = [dateHeader]
if (additionalSystemPrompt) {
parts.push(additionalSystemPrompt)
}
parts.push(`# CRITICAL: MCP Server Connection Status Check
**BEFORE responding to ANY request involving an inferred MCP server, you MUST:**
1. Check the "Unavailable MCP Servers" section
2. If the requested server is listed as FAILED/unavailable:
- IMMEDIATELY inform the user the server failed to connect in a friendly way
- State that NO tools are available for that server
- DO NOT offer functionality or ask how they'd like to use it
- STOP processing that request
`)
if (mcpServers.length > 0) {
// Add connection status sections first as these are the source of truth.
// Inference is secondary.
const connectedServers = mcpServers
.filter((s) => s.status === "connected")
.map((s) => s.name)
const failedServers = mcpServers
.filter((s) => s.status === "failed")
.map((s) => s.name)
if (connectedServers.length > 0) {
parts.push(
`# Available MCP Servers
The following MCP servers are **currently connected**:
${connectedServers.map((s) => `- ${s}`).join("\n")}
These are the ONLY servers with available tools. Use mcp_[servername]_[toolname] to call their tools.
`
)
}
if (failedServers.length > 0) {
parts.push(
`# Unavailable MCP Servers
The following MCP servers **failed to connect**:
${failedServers.map((s) => `- ${s}`).join("\n")}
These servers have NO tools available. If a user requests functionality from these servers, inform them that the connection failed and the feature is temporarily unavailable.
`
)
}
}
const inferredMCPServers = Array.from(inferredServers).join(", ")
if (inferredMCPServers) {
parts.push(
`# Server Selection Context
The following servers were inferred as potentially needed: ${inferredMCPServers}
Note: This is context about what was _should_ connect based on inference from the users question, not about what has actually connected. **Refer to the "Available MCP Servers" and "Unavailable MCP Servers" sections above for which servers actually have tools.**
`
)
}
parts.push(basePrompt)
if (mcpPrompts) {
parts.push(mcpPrompts)
}
return parts.join("\n\n")
}