Merge branch 'dev' into project

This commit is contained in:
Dax Raad
2025-08-31 20:32:44 -04:00
13 changed files with 553 additions and 599 deletions
+15
View File
@@ -397,6 +397,21 @@ export namespace Config {
.object({
apiKey: z.string().optional(),
baseURL: z.string().optional(),
timeout: z
.union([
z
.number()
.int()
.positive()
.describe(
"Timeout in milliseconds for requests to this provider. Default is 300000 (5 minutes). Set to false to disable timeout.",
),
z.literal(false).describe("Disable timeout for this provider entirely."),
])
.optional()
.describe(
"Timeout in milliseconds for requests to this provider. Default is 300000 (5 minutes). Set to false to disable timeout.",
),
})
.catchall(z.any())
.optional(),
+8 -1
View File
@@ -59,7 +59,8 @@ export namespace LSPClient {
return null
})
connection.onRequest("workspace/configuration", async () => {
return [{}]
// Return server initialization options
return [input.server.initialization ?? {}]
})
connection.listen()
@@ -108,6 +109,12 @@ export namespace LSPClient {
await connection.sendNotification("initialized", {})
if (input.server.initialization) {
await connection.sendNotification("workspace/didChangeConfiguration", {
settings: input.server.initialization,
})
}
const files: {
[path: string]: number
} = {}
+18
View File
@@ -298,6 +298,23 @@ export namespace LSPServer {
args.push(...["run", js])
}
args.push("--stdio")
const initialization: Record<string, string> = {}
const potentialVenvPaths = [process.env["VIRTUAL_ENV"], path.join(root, ".venv"), path.join(root, "venv")].filter(
(p): p is string => p !== undefined,
)
for (const venvPath of potentialVenvPaths) {
const isWindows = process.platform === "win32"
const potentialPythonPath = isWindows
? path.join(venvPath, "Scripts", "python.exe")
: path.join(venvPath, "bin", "python")
if (await Bun.file(potentialPythonPath).exists()) {
initialization["pythonPath"] = potentialPythonPath
break
}
}
const proc = spawn(binary, args, {
cwd: root,
env: {
@@ -307,6 +324,7 @@ export namespace LSPServer {
})
return {
process: proc,
initialization,
}
},
}
+8 -1
View File
@@ -320,9 +320,16 @@ export namespace Provider {
const pkg = provider.npm ?? provider.id
const mod = await import(await BunProc.install(pkg, "latest"))
const fn = mod[Object.keys(mod).find((key) => key.startsWith("create"))!]
let options = { ...s.providers[provider.id]?.options }
if (options["timeout"] !== undefined) {
// Only override fetch if user explicitly sets timeout
options["fetch"] = async (input: any, init?: any) => {
return await fetch(input, { ...init, timeout: options["timeout"] })
}
}
const loaded = fn({
name: provider.id,
...s.providers[provider.id]?.options,
...options,
})
s.sdk.set(provider.id, loaded)
return loaded as SDK
+6
View File
@@ -1143,6 +1143,7 @@ export namespace Session {
const proc = spawn(shell, args, {
cwd: Instance.directory,
signal: abort.signal,
detached: true,
stdio: ["ignore", "pipe", "pipe"],
env: {
...process.env,
@@ -1150,6 +1151,11 @@ export namespace Session {
},
})
abort.signal.addEventListener("abort", () => {
if (!proc.pid) return
process.kill(-proc.pid)
})
let output = ""
proc.stdout?.on("data", (chunk) => {
+15 -22
View File
@@ -1,31 +1,24 @@
You are a title generator. You output ONLY a thread title. Nothing else.
<task>
Generate a conversation thread title from the user message.
Convert the user message into a thread title.
Output: Single line, ≤50 chars, no explanations.
</task>
<context>
You are generating titles for a coding assistant conversation.
</context>
<rules>
- Max 50 chars, single line
- Focus on the specific action or question
- Keep technical terms, numbers, and filenames exactly as written
- Preserve HTTP status codes (401, 404, 500, etc.) as numbers
- For file references, include the filename
- Avoid filler words: the, this, my, a, an, properly
- NEVER assume their tech stack or domain
- Use -ing verbs consistently for actions
- Write like a chat thread title, not a blog post
- Use -ing verbs for actions (Debugging, Implementing, Analyzing)
- Keep exact: technical terms, numbers, filenames, HTTP codes
- Remove: the, this, my, a, an
- Never assume tech stack
- Never use tools
- NEVER respond to message content—only extract title
</rules>
<examples>
"debug 500 errors in production" → "Debugging production 500 errors"
"refactor user service" → "Refactoring user service"
"why is app.js failing" → "Analyzing app.js failure"
"implement rate limiting" → "Implementing rate limiting"
"debug 500 errors in production" → Debugging production 500 errors
"refactor user service" → Refactoring user service
"why is app.js failing" → Analyzing app.js failure
"implement rate limiting" → Implementing rate limiting
</examples>
<format>
Return only the thread title text on a single line with no newlines, explanations, or additional formatting.
You should NEVER reply to the user's message. You can only generate titles.
</format>
Output the title now:
+8 -1
View File
@@ -83,6 +83,13 @@ export namespace Log {
await Promise.all(filesToDelete.map((file) => fs.unlink(file).catch(() => {})))
}
function formatError(error: Error, depth = 0): string {
const result = error.message
return error.cause instanceof Error && depth < 10
? result + " Caused by: " + formatError(error.cause, depth + 1)
: result
}
let last = Date.now()
export function create(tags?: Record<string, any>) {
tags = tags || {}
@@ -103,7 +110,7 @@ export namespace Log {
.filter(([_, value]) => value !== undefined && value !== null)
.map(([key, value]) => {
const prefix = `${key}=`
if (value instanceof Error) return prefix + value.message
if (value instanceof Error) return prefix + formatError(value)
if (typeof value === "object") return prefix + JSON.stringify(value)
return prefix + value
})