use forkScoped + Fiber.join for lazy init (match old Instance.state behavior)
This commit is contained in:
parent
df260fee45
commit
59cc1ebc27
1 changed files with 167 additions and 1 deletions
|
|
@ -2,7 +2,7 @@ import { BusEvent } from "@/bus/bus-event"
|
||||||
import { InstanceState } from "@/effect/instance-state"
|
import { InstanceState } from "@/effect/instance-state"
|
||||||
import { makeRunPromise } from "@/effect/run-service"
|
import { makeRunPromise } from "@/effect/run-service"
|
||||||
import { SessionID, MessageID } from "@/session/schema"
|
import { SessionID, MessageID } from "@/session/schema"
|
||||||
import { Effect, Layer, ServiceMap } from "effect"
|
import { Effect, Fiber, Layer, ServiceMap } from "effect"
|
||||||
import z from "zod"
|
import z from "zod"
|
||||||
import { Config } from "../config/config"
|
import { Config } from "../config/config"
|
||||||
import PROMPT_INITIALIZE from "./template/initialize.txt"
|
import PROMPT_INITIALIZE from "./template/initialize.txt"
|
||||||
|
|
@ -78,9 +78,17 @@ export namespace Command {
|
||||||
const commands: Record<string, Info> = {}
|
const commands: Record<string, Info> = {}
|
||||||
let task: Promise<void> | undefined
|
let task: Promise<void> | undefined
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
async function load() {
|
async function load() {
|
||||||
const cfg = await Config.get()
|
const cfg = await Config.get()
|
||||||
|
||||||| parent of 8e11a46fe (use forkScoped + Fiber.join for lazy init (match old Instance.state behavior))
|
||||||
|
const commands = yield* Effect.promise(async () => {
|
||||||
|
const cfg = await Config.get()
|
||||||
|
=======
|
||||||
|
const commands: Record<string, Info> = {}
|
||||||
|
>>>>>>> 8e11a46fe (use forkScoped + Fiber.join for lazy init (match old Instance.state behavior))
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
commands[Default.INIT] = {
|
commands[Default.INIT] = {
|
||||||
name: Default.INIT,
|
name: Default.INIT,
|
||||||
description: "create/update AGENTS.md",
|
description: "create/update AGENTS.md",
|
||||||
|
|
@ -153,8 +161,68 @@ export namespace Command {
|
||||||
hints: [],
|
hints: [],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
||||||| parent of 8e11a46fe (use forkScoped + Fiber.join for lazy init (match old Instance.state behavior))
|
||||||
|
const result: Record<string, Info> = {
|
||||||
|
[Default.INIT]: {
|
||||||
|
name: Default.INIT,
|
||||||
|
description: "create/update AGENTS.md",
|
||||||
|
source: "command",
|
||||||
|
get template() {
|
||||||
|
return PROMPT_INITIALIZE.replace("${path}", instance.worktree)
|
||||||
|
},
|
||||||
|
hints: hints(PROMPT_INITIALIZE),
|
||||||
|
},
|
||||||
|
[Default.REVIEW]: {
|
||||||
|
name: Default.REVIEW,
|
||||||
|
description: "review changes [commit|branch|pr], defaults to uncommitted",
|
||||||
|
source: "command",
|
||||||
|
get template() {
|
||||||
|
return PROMPT_REVIEW.replace("${path}", instance.worktree)
|
||||||
|
},
|
||||||
|
subtask: true,
|
||||||
|
hints: hints(PROMPT_REVIEW),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [name, command] of Object.entries(cfg.command ?? {})) {
|
||||||
|
result[name] = {
|
||||||
|
name,
|
||||||
|
agent: command.agent,
|
||||||
|
model: command.model,
|
||||||
|
description: command.description,
|
||||||
|
source: "command",
|
||||||
|
get template() {
|
||||||
|
return command.template
|
||||||
|
},
|
||||||
|
subtask: command.subtask,
|
||||||
|
hints: hints(command.template),
|
||||||
|
=======
|
||||||
|
const load = Effect.fn("Command.load")(function* () {
|
||||||
|
yield* Effect.promise(async () => {
|
||||||
|
const cfg = await Config.get()
|
||||||
|
|
||||||
|
commands[Default.INIT] = {
|
||||||
|
name: Default.INIT,
|
||||||
|
description: "create/update AGENTS.md",
|
||||||
|
source: "command",
|
||||||
|
get template() {
|
||||||
|
return PROMPT_INITIALIZE.replace("${path}", instance.worktree)
|
||||||
|
},
|
||||||
|
hints: hints(PROMPT_INITIALIZE),
|
||||||
|
}
|
||||||
|
commands[Default.REVIEW] = {
|
||||||
|
name: Default.REVIEW,
|
||||||
|
description: "review changes [commit|branch|pr], defaults to uncommitted",
|
||||||
|
source: "command",
|
||||||
|
get template() {
|
||||||
|
return PROMPT_REVIEW.replace("${path}", instance.worktree)
|
||||||
|
},
|
||||||
|
subtask: true,
|
||||||
|
hints: hints(PROMPT_REVIEW),
|
||||||
|
>>>>>>> 8e11a46fe (use forkScoped + Fiber.join for lazy init (match old Instance.state behavior))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
return {
|
return {
|
||||||
commands,
|
commands,
|
||||||
ensure: () => {
|
ensure: () => {
|
||||||
|
|
@ -166,20 +234,118 @@ export namespace Command {
|
||||||
)
|
)
|
||||||
return task
|
return task
|
||||||
},
|
},
|
||||||
|
||||||| parent of 8e11a46fe (use forkScoped + Fiber.join for lazy init (match old Instance.state behavior))
|
||||||
|
// Add skills as invokable commands
|
||||||
|
for (const skill of await Skill.all()) {
|
||||||
|
// Skip if a command with this name already exists
|
||||||
|
if (result[skill.name]) continue
|
||||||
|
result[skill.name] = {
|
||||||
|
name: skill.name,
|
||||||
|
description: skill.description,
|
||||||
|
source: "skill",
|
||||||
|
get template() {
|
||||||
|
return skill.content
|
||||||
|
},
|
||||||
|
hints: [],
|
||||||
|
=======
|
||||||
|
for (const [name, command] of Object.entries(cfg.command ?? {})) {
|
||||||
|
commands[name] = {
|
||||||
|
name,
|
||||||
|
agent: command.agent,
|
||||||
|
model: command.model,
|
||||||
|
description: command.description,
|
||||||
|
source: "command",
|
||||||
|
get template() {
|
||||||
|
return command.template
|
||||||
|
},
|
||||||
|
subtask: command.subtask,
|
||||||
|
hints: hints(command.template),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
for (const [name, prompt] of Object.entries(await MCP.prompts())) {
|
||||||
|
commands[name] = {
|
||||||
|
name,
|
||||||
|
source: "mcp",
|
||||||
|
description: prompt.description,
|
||||||
|
get template() {
|
||||||
|
// since a getter can't be async we need to manually return a promise here
|
||||||
|
return new Promise<string>(async (resolve, reject) => {
|
||||||
|
const template = await MCP.getPrompt(
|
||||||
|
prompt.client,
|
||||||
|
prompt.name,
|
||||||
|
prompt.arguments
|
||||||
|
? // substitute each argument with $1, $2, etc.
|
||||||
|
Object.fromEntries(prompt.arguments?.map((argument, i) => [argument.name, `$${i + 1}`]))
|
||||||
|
: {},
|
||||||
|
).catch(reject)
|
||||||
|
resolve(
|
||||||
|
template?.messages
|
||||||
|
.map((message) => (message.content.type === "text" ? message.content.text : ""))
|
||||||
|
.join("\n") || "",
|
||||||
|
)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
hints: prompt.arguments?.map((_, i) => `$${i + 1}`) ?? [],
|
||||||
|
}
|
||||||
|
>>>>>>> 8e11a46fe (use forkScoped + Fiber.join for lazy init (match old Instance.state behavior))
|
||||||
|
}
|
||||||
|
<<<<<<< HEAD
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
||||||| parent of 8e11a46fe (use forkScoped + Fiber.join for lazy init (match old Instance.state behavior))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
=======
|
||||||
|
|
||||||
|
// Add skills as invokable commands
|
||||||
|
for (const skill of await Skill.all()) {
|
||||||
|
// Skip if a command with this name already exists
|
||||||
|
if (commands[skill.name]) continue
|
||||||
|
commands[skill.name] = {
|
||||||
|
name: skill.name,
|
||||||
|
description: skill.description,
|
||||||
|
source: "skill",
|
||||||
|
get template() {
|
||||||
|
return skill.content
|
||||||
|
},
|
||||||
|
hints: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
>>>>>>> 8e11a46fe (use forkScoped + Fiber.join for lazy init (match old Instance.state behavior))
|
||||||
|
|
||||||
|
const loadFiber = yield* load().pipe(
|
||||||
|
Effect.catchCause(() => Effect.void),
|
||||||
|
Effect.forkScoped,
|
||||||
|
)
|
||||||
|
|
||||||
const get = Effect.fn("Command.get")(function* (name: string) {
|
const get = Effect.fn("Command.get")(function* (name: string) {
|
||||||
|
<<<<<<< HEAD
|
||||||
const state = yield* InstanceState.get(cache)
|
const state = yield* InstanceState.get(cache)
|
||||||
yield* Effect.promise(() => state.ensure())
|
yield* Effect.promise(() => state.ensure())
|
||||||
return state.commands[name]
|
return state.commands[name]
|
||||||
|
||||||| parent of 8e11a46fe (use forkScoped + Fiber.join for lazy init (match old Instance.state behavior))
|
||||||
|
return commands[name]
|
||||||
|
=======
|
||||||
|
yield* Fiber.join(loadFiber)
|
||||||
|
return commands[name]
|
||||||
|
>>>>>>> 8e11a46fe (use forkScoped + Fiber.join for lazy init (match old Instance.state behavior))
|
||||||
})
|
})
|
||||||
|
|
||||||
const list = Effect.fn("Command.list")(function* () {
|
const list = Effect.fn("Command.list")(function* () {
|
||||||
|
<<<<<<< HEAD
|
||||||
const state = yield* InstanceState.get(cache)
|
const state = yield* InstanceState.get(cache)
|
||||||
yield* Effect.promise(() => state.ensure())
|
yield* Effect.promise(() => state.ensure())
|
||||||
return Object.values(state.commands)
|
return Object.values(state.commands)
|
||||||
|
||||||| parent of 8e11a46fe (use forkScoped + Fiber.join for lazy init (match old Instance.state behavior))
|
||||||
|
return Object.values(commands)
|
||||||
|
=======
|
||||||
|
yield* Fiber.join(loadFiber)
|
||||||
|
return Object.values(commands)
|
||||||
|
>>>>>>> 8e11a46fe (use forkScoped + Fiber.join for lazy init (match old Instance.state behavior))
|
||||||
})
|
})
|
||||||
|
|
||||||
return Service.of({ get, list })
|
return Service.of({ get, list })
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue