mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-04-02 23:23:45 +00:00
feat: hooks
This commit is contained in:
@@ -313,7 +313,7 @@ export namespace Agent {
|
||||
available_to_agents?: string[]
|
||||
}
|
||||
|
||||
async function loadTFPrompts(): Promise<TFPrompt[]> {
|
||||
export async function loadTFPrompts(): Promise<TFPrompt[]> {
|
||||
const toolsPath = path.join(os.homedir(), ".tfcode", "tools.json")
|
||||
try {
|
||||
const content = await Bun.file(toolsPath).text()
|
||||
|
||||
@@ -54,7 +54,7 @@ function HookStatus(props: { hook: Hook }) {
|
||||
)
|
||||
}
|
||||
|
||||
export function DialogTfHooks() {
|
||||
export function DialogTfHooks(props: { onSelect?: (hook: Hook) => void }) {
|
||||
const toast = useToast()
|
||||
const { theme } = useTheme()
|
||||
const [, setRef] = createSignal<DialogSelectRef<unknown>>()
|
||||
@@ -86,7 +86,9 @@ export function DialogTfHooks() {
|
||||
const region = creds.region || TF_DEFAULT_REGION
|
||||
const baseUrl = REGION_API_URLS[region] || REGION_API_URLS[TF_DEFAULT_REGION]
|
||||
|
||||
const response = await fetch(`${baseUrl}/hook/list`, {
|
||||
const url = new URL(`${baseUrl}/hook/list`)
|
||||
url.searchParams.set("workspaceid", creds.workspace_id)
|
||||
const response = await fetch(url.toString(), {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"x-api-key": creds.api_key,
|
||||
@@ -98,8 +100,8 @@ export function DialogTfHooks() {
|
||||
throw new Error(`HTTP ${response.status}: ${errorText}`)
|
||||
}
|
||||
|
||||
const data = (await response.json()) as { success?: boolean; hooks?: Hook[] }
|
||||
return data.hooks || []
|
||||
const data = (await response.json()) as Hook[]
|
||||
return Array.isArray(data) ? data : []
|
||||
} catch (error) {
|
||||
toast.show({
|
||||
variant: "error",
|
||||
@@ -172,7 +174,7 @@ export function DialogTfHooks() {
|
||||
keybind={keybinds()}
|
||||
onSelect={(option) => {
|
||||
if (option.value.id === "loading" || option.value.id === "empty") return
|
||||
// Don't close on select - just show the hook details
|
||||
props.onSelect?.(option.value)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -374,7 +374,22 @@ export function Prompt(props: PromptProps) {
|
||||
name: "hooks",
|
||||
},
|
||||
onSelect: () => {
|
||||
dialog.replace(() => <DialogTfHooks />)
|
||||
dialog.replace(() => (
|
||||
<DialogTfHooks
|
||||
onSelect={(hook) => {
|
||||
const parts = []
|
||||
if (hook.code_execution_instructions) parts.push(hook.code_execution_instructions)
|
||||
if (hook.predefined_code_snippet) parts.push("\n\n```python\n" + hook.predefined_code_snippet + "\n```")
|
||||
const text = parts.join("")
|
||||
if (text) {
|
||||
input.setText(text)
|
||||
setStore("prompt", { input: text, parts: [] })
|
||||
input.gotoBufferEnd()
|
||||
}
|
||||
dialog.clear()
|
||||
}}
|
||||
/>
|
||||
))
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
@@ -454,6 +454,38 @@ export namespace Server {
|
||||
return c.json(skills)
|
||||
},
|
||||
)
|
||||
.get(
|
||||
"/prompts",
|
||||
describeRoute({
|
||||
summary: "List ToothFairyAI prompts",
|
||||
description: "Get prompts assigned to a specific agent or all prompts.",
|
||||
operationId: "app.prompts",
|
||||
responses: {
|
||||
200: {
|
||||
description: "List of prompts",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(
|
||||
z.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
label: z.string(),
|
||||
interpolation_string: z.string(),
|
||||
available_to_agents: z.array(z.string()).optional(),
|
||||
description: z.string().optional(),
|
||||
}),
|
||||
),
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
const prompts = await Agent.loadTFPrompts()
|
||||
return c.json(prompts)
|
||||
},
|
||||
)
|
||||
.get(
|
||||
"/lsp",
|
||||
describeRoute({
|
||||
|
||||
Reference in New Issue
Block a user