feat: let agents read supervisor story graphs

Expose saved decisions, timelines and source evidence through read-only Story Graph tools across Model, Harness and local/remote OpenCode and Continue. Supervisor enablement and runtime assignments govern discovery and calls; reads do not invoke models or modify stored evidence. Remote use requires matching Desktop and Agent changes.

Make Continue discussion show the complete editable message with a separated destination and shared action layout. Sending uses the visible draft without reattaching removed context.

Validation: existing focused MCP, runtime, controlled Linux Host, discussion component and Electron layout checks plus typechecks; staged diff check passed. Cross-scope fact reuse, historical reconstruction and full package acceptance remain deferred.

Release note: Agents can consult saved supervisor decisions and their sources when continuing work. Continue discussion now lets you review and edit the complete message before sending.
This commit is contained in:
mesalogo
2026-09-28 12:38:00 +08:00
parent 83a3ea261e
commit 66f77b83c2
61 changed files with 1527 additions and 150 deletions
+14 -5
View File
@@ -350,6 +350,14 @@ function proxyToolInputSchema(
ReturnType<ModelToolProviderLike['listTools']>
>[number]
): Record<string, unknown> {
if (isStoryGraphTool(tool.name)) {
const schema = structuredClone(tool.inputSchema)
const scope = (schema.properties as Record<string, Record<string, unknown>>).scope!
// Scope is a discriminated union: Global and projects are mutually exclusive.
scope.oneOf = scope.anyOf
delete scope.anyOf
return dshCompatibleMainInputSchema(schema)
}
return isMainWebTool(tool) || tool.name === 'generate_image'
? dshCompatibleMainInputSchema(tool.inputSchema)
: tool.inputSchema
@@ -367,7 +375,7 @@ function boundedProxyToolCatalog(
}> {
const catalog = tools.filter(
(tool) =>
isMainWebTool(tool) ||
isMainWebTool(tool) || isStoryGraphTool(tool.name) ||
(workMode === 'execute' && (tool.source === 'mcp' || tool.name === 'generate_image'))
)
if (catalog.length > MAX_MCP_PROXY_TOOLS) {
@@ -856,7 +864,7 @@ export class DeepSeekHarnessRuntime implements AgentRuntime {
)
const catalog = boundedProxyToolCatalog(tools, context.workMode)
this.proxyToolCatalogs.set(params.sessionId, tools.filter(
(tool) => tool.source === 'mcp' || isMainWebTool(tool) || tool.name === 'generate_image'
(tool) => tool.source === 'mcp' || isMainWebTool(tool) || isStoryGraphTool(tool.name) || tool.name === 'generate_image'
))
return { tools: catalog }
}
@@ -897,7 +905,7 @@ export class DeepSeekHarnessRuntime implements AgentRuntime {
const tool = tools.find(
(candidate) =>
candidate.name === name &&
(candidate.source === 'mcp' || candidate.name === 'generate_image' ||
(candidate.source === 'mcp' || candidate.name === 'generate_image' || isStoryGraphTool(candidate.name) ||
isMainWebTool(candidate))
)
if (!tool) {
@@ -907,7 +915,7 @@ export class DeepSeekHarnessRuntime implements AgentRuntime {
}
const isWebTool = isMainWebTool(tool)
if (
!isWebTool &&
!isWebTool && !isStoryGraphTool(name) &&
(context.workMode !== 'execute' || !run.authorize)
) {
throw new Error(
@@ -937,7 +945,7 @@ export class DeepSeekHarnessRuntime implements AgentRuntime {
.slice(0, 1_000)}`
)
}
if (!isWebTool) {
if (!isWebTool && !isStoryGraphTool(name)) {
const approval =
run.toolProvider.getApproval(
tool,
@@ -1758,3 +1766,4 @@ export class DeepSeekHarnessRuntime implements AgentRuntime {
}
}
import { imageToolDescriptionLimit } from '../../shared/image-generation-contracts'
import { isStoryGraphTool } from '../../shared/story-graph-tools'