feat(hephaestus): add generic GPT prompt fallback with model-specific routing
Split monolithic hephaestus.ts into directory with model-specific prompt variants (gpt-5-4.ts, gpt-5-3-codex.ts, gpt.ts) mirroring the sisyphus-junior pattern. Generic gpt.ts uses pre-codex-tuning prompt as fallback for non-specific GPT models. Also adds isGpt5_4Model and isGpt5_3CodexModel helpers to types.ts.
This commit is contained in:
+52
-36
@@ -1,4 +1,4 @@
|
||||
import type { AgentConfig } from "@opencode-ai/sdk"
|
||||
import type { AgentConfig } from "@opencode-ai/sdk";
|
||||
|
||||
/**
|
||||
* Agent mode determines UI model selection behavior:
|
||||
@@ -6,34 +6,38 @@ import type { AgentConfig } from "@opencode-ai/sdk"
|
||||
* - "subagent": Uses own fallback chain, ignores UI selection (oracle, explore, etc.)
|
||||
* - "all": Available in both contexts (OpenCode compatibility)
|
||||
*/
|
||||
export type AgentMode = "primary" | "subagent" | "all"
|
||||
export type AgentMode = "primary" | "subagent" | "all";
|
||||
|
||||
/**
|
||||
* Agent factory function with static mode property.
|
||||
* Mode is exposed as static property for pre-instantiation access.
|
||||
*/
|
||||
export type AgentFactory = ((model: string) => AgentConfig) & {
|
||||
mode: AgentMode
|
||||
}
|
||||
mode: AgentMode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Agent category for grouping in Sisyphus prompt sections
|
||||
*/
|
||||
export type AgentCategory = "exploration" | "specialist" | "advisor" | "utility"
|
||||
export type AgentCategory =
|
||||
| "exploration"
|
||||
| "specialist"
|
||||
| "advisor"
|
||||
| "utility";
|
||||
|
||||
/**
|
||||
* Cost classification for Tool Selection table
|
||||
*/
|
||||
export type AgentCost = "FREE" | "CHEAP" | "EXPENSIVE"
|
||||
export type AgentCost = "FREE" | "CHEAP" | "EXPENSIVE";
|
||||
|
||||
/**
|
||||
* Delegation trigger for Sisyphus prompt's Delegation Table
|
||||
*/
|
||||
export interface DelegationTrigger {
|
||||
/** Domain of work (e.g., "Frontend UI/UX") */
|
||||
domain: string
|
||||
domain: string;
|
||||
/** When to delegate (e.g., "Visual changes only...") */
|
||||
trigger: string
|
||||
trigger: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,50 +46,62 @@ export interface DelegationTrigger {
|
||||
*/
|
||||
export interface AgentPromptMetadata {
|
||||
/** Category for grouping in prompt sections */
|
||||
category: AgentCategory
|
||||
category: AgentCategory;
|
||||
|
||||
/** Cost classification for Tool Selection table */
|
||||
cost: AgentCost
|
||||
cost: AgentCost;
|
||||
|
||||
/** Domain triggers for Delegation Table */
|
||||
triggers: DelegationTrigger[]
|
||||
triggers: DelegationTrigger[];
|
||||
|
||||
/** When to use this agent (for detailed sections) */
|
||||
useWhen?: string[]
|
||||
useWhen?: string[];
|
||||
|
||||
/** When NOT to use this agent */
|
||||
avoidWhen?: string[]
|
||||
avoidWhen?: string[];
|
||||
|
||||
/** Optional dedicated prompt section (markdown) - for agents like Oracle that have special sections */
|
||||
dedicatedSection?: string
|
||||
dedicatedSection?: string;
|
||||
|
||||
/** Nickname/alias used in prompt (e.g., "Oracle" instead of "oracle") */
|
||||
promptAlias?: string
|
||||
promptAlias?: string;
|
||||
|
||||
/** Key triggers that should appear in Phase 0 (e.g., "External library mentioned → fire librarian") */
|
||||
keyTrigger?: string
|
||||
keyTrigger?: string;
|
||||
}
|
||||
|
||||
function extractModelName(model: string): string {
|
||||
return model.includes("/") ? model.split("/").pop() ?? model : model
|
||||
return model.includes("/") ? (model.split("/").pop() ?? model) : model;
|
||||
}
|
||||
|
||||
export function isGptModel(model: string): boolean {
|
||||
const modelName = extractModelName(model).toLowerCase()
|
||||
return modelName.includes("gpt")
|
||||
const modelName = extractModelName(model).toLowerCase();
|
||||
return modelName.includes("gpt");
|
||||
}
|
||||
|
||||
const GEMINI_PROVIDERS = ["google/", "google-vertex/"]
|
||||
export function isGpt5_4Model(model: string): boolean {
|
||||
const modelName = extractModelName(model).toLowerCase();
|
||||
return modelName.includes("gpt-5.4") || modelName.includes("gpt-5-4");
|
||||
}
|
||||
|
||||
export function isGpt5_3CodexModel(model: string): boolean {
|
||||
const modelName = extractModelName(model).toLowerCase();
|
||||
return modelName.includes("gpt-5.3-codex") || modelName.includes("gpt-5-3-codex");
|
||||
}
|
||||
|
||||
const GEMINI_PROVIDERS = ["google/", "google-vertex/"];
|
||||
|
||||
export function isGeminiModel(model: string): boolean {
|
||||
if (GEMINI_PROVIDERS.some((prefix) => model.startsWith(prefix)))
|
||||
return true
|
||||
if (GEMINI_PROVIDERS.some((prefix) => model.startsWith(prefix))) return true;
|
||||
|
||||
if (model.startsWith("github-copilot/") && extractModelName(model).toLowerCase().startsWith("gemini"))
|
||||
return true
|
||||
if (
|
||||
model.startsWith("github-copilot/") &&
|
||||
extractModelName(model).toLowerCase().startsWith("gemini")
|
||||
)
|
||||
return true;
|
||||
|
||||
const modelName = extractModelName(model).toLowerCase()
|
||||
return modelName.startsWith("gemini-")
|
||||
const modelName = extractModelName(model).toLowerCase();
|
||||
return modelName.startsWith("gemini-");
|
||||
}
|
||||
|
||||
export type BuiltinAgentName =
|
||||
@@ -97,18 +113,18 @@ export type BuiltinAgentName =
|
||||
| "multimodal-looker"
|
||||
| "metis"
|
||||
| "momus"
|
||||
| "atlas"
|
||||
| "atlas";
|
||||
|
||||
export type OverridableAgentName =
|
||||
| "build"
|
||||
| BuiltinAgentName
|
||||
export type OverridableAgentName = "build" | BuiltinAgentName;
|
||||
|
||||
export type AgentName = BuiltinAgentName
|
||||
export type AgentName = BuiltinAgentName;
|
||||
|
||||
export type AgentOverrideConfig = Partial<AgentConfig> & {
|
||||
prompt_append?: string
|
||||
variant?: string
|
||||
fallback_models?: string | string[]
|
||||
}
|
||||
prompt_append?: string;
|
||||
variant?: string;
|
||||
fallback_models?: string | string[];
|
||||
};
|
||||
|
||||
export type AgentOverrides = Partial<Record<OverridableAgentName, AgentOverrideConfig>>
|
||||
export type AgentOverrides = Partial<
|
||||
Record<OverridableAgentName, AgentOverrideConfig>
|
||||
>;
|
||||
|
||||
Reference in New Issue
Block a user