fix(coding-agent): rehome TITLE_SYSTEM.md discovery and reload it on cwd change
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
- Added `python.interpreter` to pin eval's Python backend to an explicit interpreter and skip automatic runtime discovery ([#1802](https://github.com/can1357/oh-my-pi/issues/1802)).
|
||||
- Added `!command` resolution for `models.yml` provider `apiKey` values and provider/model headers ([#1888](https://github.com/can1357/oh-my-pi/issues/1888)).
|
||||
- Documented the oMLX setup path through existing OpenAI-compatible local discovery ([#1957](https://github.com/can1357/oh-my-pi/issues/1957)).
|
||||
- Added `TITLE_SYSTEM.md` discovery so users can override the automatic session-title generation prompt for online and local tiny title models without patching installed prompt files.
|
||||
- Added `TITLE_SYSTEM.md` discovery so users can override the automatic session-title generation prompt for online and local tiny title models without patching installed prompt files. The override is re-discovered when the session working directory changes via `/cwd`.
|
||||
- Added a structured memory runtime surface for extensions and UI integrations to query backend status, search memories, and save explicit memories across the configured memory backend.
|
||||
- Added support for Git repositories using the `reftable` storage format by detecting `extensions.refStorage = reftable` in the repository configuration and falling back to shelling out to Git commands (`git symbolic-ref`, `git rev-parse`) for reference and HEAD resolution.
|
||||
- Added `/setup providers` (also available as `/setup` or `/providers`) to reopen the interactive provider setup scene from an active TUI session, letting users sign in and choose a web search provider without rerunning the full onboarding flow.
|
||||
|
||||
@@ -67,7 +67,7 @@ import {
|
||||
import type { AgentSession } from "./session/agent-session";
|
||||
import type { AuthStorage } from "./session/auth-storage";
|
||||
import { resolveResumableSession, type SessionInfo, SessionManager } from "./session/session-manager";
|
||||
import { resolvePromptInput } from "./system-prompt";
|
||||
import { discoverTitleSystemPromptFile, resolvePromptInput } from "./system-prompt";
|
||||
import { initTelemetryExport, isTelemetryExportEnabled } from "./telemetry-export";
|
||||
import { AUTO_THINKING } from "./thinking";
|
||||
import { discoverStartupLspServers, type LspStartupServerInfo } from "./tools";
|
||||
@@ -721,19 +721,6 @@ function discoverAppendSystemPromptFile(): string | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Discover TITLE_SYSTEM.md file for automatic session-title prompt overrides */
|
||||
export function discoverTitleSystemPromptFile(cwd?: string): string | undefined {
|
||||
const projectPath = findConfigFile("TITLE_SYSTEM.md", { user: false, cwd });
|
||||
if (projectPath) {
|
||||
return projectPath;
|
||||
}
|
||||
const globalPath = findConfigFile("TITLE_SYSTEM.md", { user: true, cwd });
|
||||
if (globalPath) {
|
||||
return globalPath;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async function buildSessionOptions(
|
||||
parsed: Args,
|
||||
scopedModels: ScopedModel[],
|
||||
|
||||
@@ -78,6 +78,7 @@ import type { ShakeMode } from "../session/shake-types";
|
||||
import { BUILTIN_SLASH_COMMAND_RESERVED_NAMES } from "../slash-commands/builtin-registry";
|
||||
import { formatDuration } from "../slash-commands/helpers/format";
|
||||
import { STTController, type SttState } from "../stt";
|
||||
import { discoverTitleSystemPromptFile, resolvePromptInput } from "../system-prompt";
|
||||
import type { LspStartupServerInfo } from "../tools";
|
||||
import { normalizeLocalScheme } from "../tools/path-utils";
|
||||
import { setAutoQaConsentHandler } from "../tools/report-tool-issue";
|
||||
@@ -684,6 +685,13 @@ export class InteractiveMode implements InteractiveModeContext {
|
||||
this.updateEditorTopBorder();
|
||||
}
|
||||
|
||||
/** Reload the title-generation system prompt override for the provided working directory. */
|
||||
async refreshTitleSystemPrompt(cwd?: string): Promise<void> {
|
||||
const basePath = cwd ?? this.sessionManager.getCwd();
|
||||
const titleSystemPromptSource = discoverTitleSystemPromptFile(basePath);
|
||||
this.titleSystemPrompt = await resolvePromptInput(titleSystemPromptSource, "title system prompt");
|
||||
}
|
||||
|
||||
/** Reload slash commands and autocomplete for the provided working directory. */
|
||||
async refreshSlashCommandState(cwd?: string): Promise<void> {
|
||||
const basePath = cwd ?? this.sessionManager.getCwd();
|
||||
@@ -718,6 +726,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
||||
// Re-warm plugin roots, capabilities, slash commands, and the ssh tool so
|
||||
// the next prompt sees everything scoped to the new project directory.
|
||||
clearClaudePluginRootsCache();
|
||||
await this.refreshTitleSystemPrompt(newCwd);
|
||||
resetCapabilities();
|
||||
await this.refreshSlashCommandState(newCwd);
|
||||
await this.session.refreshSshTool({ activateIfAvailable: true });
|
||||
|
||||
@@ -8,6 +8,7 @@ import { $env, getGpuCachePath, getProjectDir, hasFsCode, isEnoent, logger, prom
|
||||
import { $ } from "bun";
|
||||
import { contextFileCapability } from "./capability/context-file";
|
||||
import { systemPromptCapability } from "./capability/system-prompt";
|
||||
import { findConfigFile } from "./config";
|
||||
import type { SkillsSettings } from "./config/settings";
|
||||
import { type ContextFile, loadCapability, type SystemPrompt as SystemPromptFile } from "./discovery";
|
||||
import { expandAtImports } from "./discovery/at-imports";
|
||||
@@ -208,6 +209,19 @@ async function getEnvironmentInfo(): Promise<Array<{ label: string; value: strin
|
||||
return entries.filter((e): e is { label: string; value: string } => !!e.value);
|
||||
}
|
||||
|
||||
/** Discover TITLE_SYSTEM.md file for automatic session-title prompt overrides */
|
||||
export function discoverTitleSystemPromptFile(cwd?: string): string | undefined {
|
||||
const projectPath = findConfigFile("TITLE_SYSTEM.md", { user: false, cwd });
|
||||
if (projectPath) {
|
||||
return projectPath;
|
||||
}
|
||||
const globalPath = findConfigFile("TITLE_SYSTEM.md", { user: true, cwd });
|
||||
if (globalPath) {
|
||||
return globalPath;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Resolve input as file path or literal string */
|
||||
export async function resolvePromptInput(input: string | undefined, description: string): Promise<string | undefined> {
|
||||
if (!input) {
|
||||
|
||||
@@ -2,8 +2,9 @@ import { afterEach, describe, expect, it, vi } from "bun:test";
|
||||
import * as fs from "node:fs/promises";
|
||||
import * as os from "node:os";
|
||||
import * as path from "node:path";
|
||||
import { discoverTitleSystemPromptFile, submitInteractiveInput } from "@oh-my-pi/pi-coding-agent/main";
|
||||
import { submitInteractiveInput } from "@oh-my-pi/pi-coding-agent/main";
|
||||
import type { SubmittedUserInput } from "@oh-my-pi/pi-coding-agent/modes/types";
|
||||
import { discoverTitleSystemPromptFile } from "@oh-my-pi/pi-coding-agent/system-prompt";
|
||||
|
||||
const cleanupDirs: string[] = [];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user