sync
parent
8ca4343053
commit
aeca8051d5
|
|
@ -42,20 +42,19 @@ export namespace Agent {
|
|||
|
||||
const state = Instance.state(async () => {
|
||||
const cfg = await Config.get()
|
||||
const permission: PermissionNext.Ruleset = PermissionNext.merge(
|
||||
PermissionNext.fromConfig({
|
||||
"*": "allow",
|
||||
doom_loop: "ask",
|
||||
external_directory: "ask",
|
||||
}),
|
||||
PermissionNext.fromConfig(cfg.permission ?? {}),
|
||||
)
|
||||
|
||||
const defaults = PermissionNext.fromConfig({
|
||||
"*": "allow",
|
||||
doom_loop: "ask",
|
||||
external_directory: "ask",
|
||||
})
|
||||
const user = PermissionNext.fromConfig(cfg.permission ?? {})
|
||||
|
||||
const result: Record<string, Info> = {
|
||||
build: {
|
||||
name: "build",
|
||||
options: {},
|
||||
permission,
|
||||
permission: PermissionNext.merge(defaults, user),
|
||||
mode: "primary",
|
||||
native: true,
|
||||
},
|
||||
|
|
@ -63,13 +62,14 @@ export namespace Agent {
|
|||
name: "plan",
|
||||
options: {},
|
||||
permission: PermissionNext.merge(
|
||||
permission,
|
||||
defaults,
|
||||
PermissionNext.fromConfig({
|
||||
edit: {
|
||||
"*": "deny",
|
||||
".opencode/plan/*.md": "allow",
|
||||
},
|
||||
}),
|
||||
user,
|
||||
),
|
||||
mode: "primary",
|
||||
native: true,
|
||||
|
|
@ -78,11 +78,12 @@ export namespace Agent {
|
|||
name: "general",
|
||||
description: `General-purpose agent for researching complex questions and executing multi-step tasks. Use this agent to execute multiple units of work in parallel.`,
|
||||
permission: PermissionNext.merge(
|
||||
permission,
|
||||
defaults,
|
||||
PermissionNext.fromConfig({
|
||||
todoread: "deny",
|
||||
todowrite: "deny",
|
||||
}),
|
||||
user,
|
||||
),
|
||||
options: {},
|
||||
mode: "subagent",
|
||||
|
|
@ -92,7 +93,7 @@ export namespace Agent {
|
|||
explore: {
|
||||
name: "explore",
|
||||
permission: PermissionNext.merge(
|
||||
permission,
|
||||
defaults,
|
||||
PermissionNext.fromConfig({
|
||||
"*": "deny",
|
||||
grep: "allow",
|
||||
|
|
@ -104,6 +105,7 @@ export namespace Agent {
|
|||
codesearch: "allow",
|
||||
read: "allow",
|
||||
}),
|
||||
user,
|
||||
),
|
||||
description: `Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. "src/components/**/*.tsx"), search code for keywords (eg. "API endpoints"), or answer questions about the codebase (eg. "how do API endpoints work?"). When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions.`,
|
||||
prompt: PROMPT_EXPLORE,
|
||||
|
|
@ -117,9 +119,13 @@ export namespace Agent {
|
|||
native: true,
|
||||
hidden: true,
|
||||
prompt: PROMPT_COMPACTION,
|
||||
permission: PermissionNext.fromConfig({
|
||||
"*": "deny",
|
||||
}),
|
||||
permission: PermissionNext.merge(
|
||||
defaults,
|
||||
PermissionNext.fromConfig({
|
||||
"*": "deny",
|
||||
}),
|
||||
user,
|
||||
),
|
||||
options: {},
|
||||
},
|
||||
title: {
|
||||
|
|
@ -128,9 +134,13 @@ export namespace Agent {
|
|||
options: {},
|
||||
native: true,
|
||||
hidden: true,
|
||||
permission: PermissionNext.fromConfig({
|
||||
"*": "deny",
|
||||
}),
|
||||
permission: PermissionNext.merge(
|
||||
defaults,
|
||||
PermissionNext.fromConfig({
|
||||
"*": "deny",
|
||||
}),
|
||||
user,
|
||||
),
|
||||
prompt: PROMPT_TITLE,
|
||||
},
|
||||
summary: {
|
||||
|
|
@ -139,9 +149,13 @@ export namespace Agent {
|
|||
options: {},
|
||||
native: true,
|
||||
hidden: true,
|
||||
permission: PermissionNext.fromConfig({
|
||||
"*": "deny",
|
||||
}),
|
||||
permission: PermissionNext.merge(
|
||||
defaults,
|
||||
PermissionNext.fromConfig({
|
||||
"*": "deny",
|
||||
}),
|
||||
user,
|
||||
),
|
||||
prompt: PROMPT_SUMMARY,
|
||||
},
|
||||
}
|
||||
|
|
@ -156,7 +170,7 @@ export namespace Agent {
|
|||
item = result[key] = {
|
||||
name: key,
|
||||
mode: "all",
|
||||
permission,
|
||||
permission: PermissionNext.merge(defaults, user),
|
||||
options: {},
|
||||
native: false,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,10 +161,9 @@ export function PermissionPrompt(props: { request: PermissionRequest }) {
|
|||
</Match>
|
||||
<Match when={props.request.permission === "task"}>
|
||||
<TextBody
|
||||
icon="◉"
|
||||
title={
|
||||
`${Locale.titlecase(input().subagent_type as string)} Task "` + (input().description ?? "") + `"`
|
||||
}
|
||||
icon="#"
|
||||
title={`${Locale.titlecase((input().subagent_type as string) ?? "Unknown")} Task`}
|
||||
description={"◉ " + input().description}
|
||||
/>
|
||||
</Match>
|
||||
<Match when={props.request.permission === "webfetch"}>
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ export namespace SessionProcessor {
|
|||
JSON.stringify(p.state.input) === JSON.stringify(value.input),
|
||||
)
|
||||
) {
|
||||
const agent = await Agent.get(input.assistantMessage.mode)
|
||||
const agent = await Agent.get(input.assistantMessage.agent)
|
||||
await PermissionNext.ask({
|
||||
permission: "doom_loop",
|
||||
patterns: [value.toolName],
|
||||
|
|
|
|||
|
|
@ -241,6 +241,7 @@ export namespace SessionPrompt {
|
|||
using _ = defer(() => cancel(sessionID))
|
||||
|
||||
let step = 0
|
||||
const session = await Session.get(sessionID)
|
||||
while (true) {
|
||||
SessionStatus.set(sessionID, { type: "busy" })
|
||||
log.info("loop", { step, sessionID })
|
||||
|
|
@ -277,7 +278,7 @@ export namespace SessionPrompt {
|
|||
step++
|
||||
if (step === 1)
|
||||
ensureTitle({
|
||||
session: await Session.get(sessionID),
|
||||
session,
|
||||
modelID: lastUser.model.modelID,
|
||||
providerID: lastUser.model.providerID,
|
||||
message: msgs.find((m) => m.info.role === "user")!,
|
||||
|
|
@ -519,7 +520,7 @@ export namespace SessionPrompt {
|
|||
})
|
||||
const tools = await resolveTools({
|
||||
agent,
|
||||
sessionID,
|
||||
session,
|
||||
model,
|
||||
tools: lastUser.tools,
|
||||
processor,
|
||||
|
|
@ -589,7 +590,7 @@ export namespace SessionPrompt {
|
|||
async function resolveTools(input: {
|
||||
agent: Agent.Info
|
||||
model: Provider.Model
|
||||
sessionID: string
|
||||
session: Session.Info
|
||||
tools?: Record<string, boolean>
|
||||
processor: SessionProcessor.Info
|
||||
}) {
|
||||
|
|
@ -606,7 +607,7 @@ export namespace SessionPrompt {
|
|||
"tool.execute.before",
|
||||
{
|
||||
tool: item.id,
|
||||
sessionID: input.sessionID,
|
||||
sessionID: input.session.id,
|
||||
callID: options.toolCallId,
|
||||
},
|
||||
{
|
||||
|
|
@ -614,7 +615,7 @@ export namespace SessionPrompt {
|
|||
},
|
||||
)
|
||||
const ctx: Tool.Context = {
|
||||
sessionID: input.sessionID,
|
||||
sessionID: input.session.id,
|
||||
abort: options.abortSignal!,
|
||||
messageID: input.processor.message.id,
|
||||
callID: options.toolCallId,
|
||||
|
|
@ -640,7 +641,7 @@ export namespace SessionPrompt {
|
|||
async ask(req) {
|
||||
await PermissionNext.ask({
|
||||
...req,
|
||||
sessionID: input.sessionID,
|
||||
sessionID: input.session.parentID ?? input.session.id,
|
||||
tool: { messageID: input.processor.message.id, callID: options.toolCallId },
|
||||
ruleset: input.agent.permission,
|
||||
})
|
||||
|
|
@ -651,7 +652,7 @@ export namespace SessionPrompt {
|
|||
"tool.execute.after",
|
||||
{
|
||||
tool: item.id,
|
||||
sessionID: input.sessionID,
|
||||
sessionID: input.session.id,
|
||||
callID: options.toolCallId,
|
||||
},
|
||||
result,
|
||||
|
|
@ -676,7 +677,7 @@ export namespace SessionPrompt {
|
|||
"tool.execute.before",
|
||||
{
|
||||
tool: key,
|
||||
sessionID: input.sessionID,
|
||||
sessionID: input.session.id,
|
||||
callID: opts.toolCallId,
|
||||
},
|
||||
{
|
||||
|
|
@ -689,7 +690,7 @@ export namespace SessionPrompt {
|
|||
"tool.execute.after",
|
||||
{
|
||||
tool: key,
|
||||
sessionID: input.sessionID,
|
||||
sessionID: input.session.id,
|
||||
callID: opts.toolCallId,
|
||||
},
|
||||
result,
|
||||
|
|
@ -704,7 +705,7 @@ export namespace SessionPrompt {
|
|||
} else if (contentItem.type === "image") {
|
||||
attachments.push({
|
||||
id: Identifier.ascending("part"),
|
||||
sessionID: input.sessionID,
|
||||
sessionID: input.session.id,
|
||||
messageID: input.processor.message.id,
|
||||
type: "file",
|
||||
mime: contentItem.mimeType,
|
||||
|
|
|
|||
Loading…
Reference in New Issue