Refactor reference selection and simplify AI prompts

This commit is contained in:
hy committed 2026-03-31 16:50:05 +08:00
1 parent 95079f6c4e
commit b5656a75ff
6 files changed
+304 -295

No files matched your search

+54 -24
View File
@@ -1,33 +1,63 @@
import {
buildDirectorPromptUserContext,
type IntentPromptInput,
JSON_ONLY_INTENT_CONTRACT
} from './shared'
import { renderLineList } from '../../utils/render'
export const buildIntentSystemPrompt = (): string =>
[
'【角色】你是请求分流决策器。',
'【目标】在 need_context / to_plan / direct_human 三者中选择唯一模式。',
'【背景】你只能依据当前输入字段判断,不得使用未提供信息。',
'【流程】先判断信息是否不足,再判断是否需要本地工具执行,最后给出结构化决策。',
'【范围】若用户已显式选择参考资料,默认视为优先参考范围;涉及本地资料时优先走本地能力,不要忽略这些选择。',
'【约束】不得编造上下文;reason 必须说明判定依据。',
'【输出】',
JSON_ONLY_INTENT_CONTRACT,
'【样例-正】当用户请求“请把 A 文档改成模板并保存”且需要多个业务动作时,输出 mode=to_plan。',
'【样例-正】当用户请求“总结这篇文章并按要求输出”且单个 human 可闭环完成时,输出 mode=direct_human。',
'【样例-正】当用户问“继续刚才第二步”但缺少指代信息时,输出 mode=need_context。',
'【样例-反】不要输出“我觉得应该先查一下”这类自然语言。'
].join('\n')
export const buildIntentUserPrompt = (input: IntentPromptInput): string => {
const contextEvidenceText = renderLineList(input.contextEvidence, {
fallback: '(none)',
style: 'plain'
})
return `
<user_context>
<user_input>
${input.userInput}
</user_input>
<session_summary>
${input.sessionSummaryText}
</session_summary>
<recent_turns>
${input.recentTurnsText}
</recent_turns>
<selected_context>
${input.selectedContextText}
</selected_context>
<context_evidence>
${contextEvidenceText}
</context_evidence>
<context_rounds>
${input.contextRounds}/${input.maxContextRounds}
</context_rounds>
</user_context>
`.trim()
}
export const buildIntentPrompt = (input: IntentPromptInput) => {
return {
system: [
'【角色】你是请求分流决策器。',
'【目标】在 need_context / to_plan / direct_human 三者中选择唯一模式。',
'【背景】你只能依据当前输入字段判断,不得使用未提供信息。',
'【流程】先判断信息是否不足,再判断是否需要本地工具执行,最后给出结构化决策。',
'【范围】若用户已显式选择参考资料,默认视为优先参考范围;涉及本地资料时优先走本地能力,不要忽略这些选择。',
'【约束】不得编造上下文;reason 必须说明判定依据。',
'【输出】',
JSON_ONLY_INTENT_CONTRACT,
'【样例-正】当用户请求“请把 A 文档改成模板并保存”且需要多个业务动作时,输出 mode=to_plan。',
'【样例-正】当用户请求“总结这篇文章并按要求输出”且单个 human 可闭环完成时,输出 mode=direct_human。',
'【样例-正】当用户问“继续刚才第二步”但缺少指代信息时,输出 mode=need_context。',
'【样例-反】不要输出“我觉得应该先查一下”这类自然语言。'
].join('\n'),
user: buildDirectorPromptUserContext({
...input,
extraSections: [
{
label: '当前 context rounds',
value: `${input.contextRounds}/${input.maxContextRounds}`
}
]
})
system: buildIntentSystemPrompt(),
user: buildIntentUserPrompt(input)
}
}
+49 -15
View File
@@ -1,24 +1,58 @@
import {
buildDirectorPromptUserContext,
type PlanPromptInput,
JSON_ONLY_PLAN_CONTRACT
} from './shared'
import { renderLineList } from '../../utils/render'
export const buildPlanSystemPrompt = (): string =>
[
'【角色】你是任务规划器。',
'【目标】把用户请求拆成可独立执行的任务列表。',
'【背景】执行层是本地工具执行模式,典型能力包括知识库检索、终端执行、docx 处理。',
'【运行时约束】最终总结由 runtime 自动追加 synthesis human 负责,不要把“总结答复”写成计划中的业务任务。',
'【范围】若已显式选择参考资料,任务规划必须优先围绕这些本地选择取证;不要默认扩大到未选中的本地资料。',
'【流程】先识别最终交付物,再拆分最小可行任务,最后检查任务是否可执行可验证。',
'【约束】每个 userInput 必须包含“动作 + 对象 + 完成判据”;禁止空泛任务。',
'【输出】',
JSON_ONLY_PLAN_CONTRACT,
'【样例-正】userInput: "读取 /docs/a.docx,提取行动项并输出 owner/due_date/task 字段"。',
'【样例-反】userInput: "继续优化文档质量"。'
].join('\n')
export const buildPlanUserPrompt = (input: PlanPromptInput): string => {
const contextEvidenceText = renderLineList(input.contextEvidence, {
fallback: '(none)',
style: 'plain'
})
return `
<user_context>
<user_input>
${input.userInput}
</user_input>
<session_summary>
${input.sessionSummaryText}
</session_summary>
<recent_turns>
${input.recentTurnsText}
</recent_turns>
<selected_context>
${input.selectedContextText}
</selected_context>
<context_evidence>
${contextEvidenceText}
</context_evidence>
</user_context>
`.trim()
}
export const buildPlanPrompt = (input: PlanPromptInput) => {
return {
system: [
'【角色】你是任务规划器。',
'【目标】把用户请求拆成可独立执行的任务列表。',
'【背景】执行层是本地工具执行模式,典型能力包括知识库检索、终端执行、docx 处理。',
'【运行时约束】最终总结由 runtime 自动追加 synthesis human 负责,不要把“总结答复”写成计划中的业务任务。',
'【范围】若已显式选择参考资料,任务规划必须优先围绕这些本地选择取证;不要默认扩大到未选中的本地资料。',
'【流程】先识别最终交付物,再拆分最小可行任务,最后检查任务是否可执行可验证。',
'【约束】每个 userInput 必须包含“动作 + 对象 + 完成判据”;禁止空泛任务。',
'【输出】',
JSON_ONLY_PLAN_CONTRACT,
'【样例-正】userInput: "读取 /docs/a.docx,提取行动项并输出 owner/due_date/task 字段"。',
'【样例-反】userInput: "继续优化文档质量"。'
].join('\n'),
user: buildDirectorPromptUserContext(input)
system: buildPlanSystemPrompt(),
user: buildPlanUserPrompt(input)
}
}
@@ -1,5 +1,3 @@
import { renderLineList, renderNamedSections } from '../../utils/render'
export const JSON_ONLY_INTENT_CONTRACT = [
'只输出 JSON,不得输出任何额外文字。',
'格式:{"mode":"need_context|to_plan|direct_human","reason":"string"}。',
@@ -26,29 +24,3 @@ export type IntentPromptInput = DirectorPromptSharedInput & {
}
export type PlanPromptInput = DirectorPromptSharedInput
export const buildDirectorPromptUserContext = (
input: DirectorPromptSharedInput & {
extraSections?: Array<{ label: string; value: string }>
}
) =>
renderNamedSections(
[
{ label: '用户输入', value: input.userInput },
{ label: '会话摘要', value: input.sessionSummaryText },
{ label: '最近对话', value: input.recentTurnsText },
{ label: '用户选择的参考资料', value: input.selectedContextText },
{
label: '上下文证据',
value: renderLineList(input.contextEvidence, {
fallback: '(none)',
style: 'plain'
})
},
...(input.extraSections || [])
],
{
fallback: '(none)',
style: 'plain'
}
)
+171 -22
View File
@@ -1,6 +1,13 @@
import type { AiRunContext } from '../../types'
import type { HumanState } from '../types'
import { buildBrainPromptSections } from './brainContextSections'
import { renderLineList } from '../../utils/render'
import { getSkillDefinition } from '../skills'
import {
renderHumanEvidenceLines,
renderHumanFactLines,
renderHumanOpenQuestionLines
} from '../shared/memoryRenderers'
import { getToolPromptSpec } from '../tools/registry'
import type { HumanState, ToolPromptSpec } from '../types'
type HumanBrainPromptInput = {
userInput: string
@@ -12,27 +19,150 @@ type HumanBrainPromptInput = {
watchHintText: string
}
export const buildBrainPromptContext = (input: { state: HumanState; ctx: AiRunContext }) => {
const sections = buildBrainPromptSections(input)
return buildHumanBrainPrompt({
userInput: input.state.task.userInput,
memorySnapshotText: sections.memorySnapshotText,
selectedContextText: sections.selectedContextText,
skillContextText: sections.skillContextText,
recentToolResultsText: sections.recentToolResultsText,
recentDecisionHistoryText: sections.recentDecisionHistoryText,
watchHintText: [
'如果这里是 none,表示当前没有额外的收敛提醒;否则应优先考虑结束任务或纠偏。',
'',
input.state.watchHint || 'none'
].join('\n')
const formatPlainList = (items: string[]): string =>
renderLineList(items, {
fallback: 'none',
style: 'plain'
})
const renderLearnedToolSpecLine = (spec: ToolPromptSpec): string => {
const requiredArgs = spec.args
.filter((arg) => arg.required)
.map((arg) => `${arg.name}:${arg.type}`)
.join(', ')
const example = spec.examples?.[0]
? `示例目标=${spec.examples[0].goal};示例参数键=[${Object.keys(spec.examples[0].args).join(', ') || 'none'}]`
: '示例=none'
return `- 工具 ${spec.name}:适用场景=${spec.whenToUse};必填参数=[${requiredArgs || 'none'}];${example}`
}
export const buildHumanBrainPrompt = (input: HumanBrainPromptInput) => {
return {
system: `
const buildRecentToolResultLine = (
result: NonNullable<HumanState['lastParallelCallToolResults']>[number],
index: number
): string => {
const diagnosticText = result.diagnostic
? `;diagnostic=${result.diagnostic.kind}${result.diagnostic.missingArgs?.length ? `;missingArgs=[${result.diagnostic.missingArgs.join(', ')}]` : ''}`
: ''
return `- 第${index + 1}项:工具 ${result.toolName} ${result.ok ? '执行成功' : '执行失败'}(code=${result.code});摘要:${result.summary}${diagnosticText}`
}
const buildMemorySnapshotText = (state: HumanState): string =>
[
'下面是你之前沉淀下来的记忆。这些内容代表当前已经确认、可以直接复用或仍影响推进的信息。',
'',
'已确认的事实:',
renderHumanFactLines(state, 'brain_prompt'),
'',
'支撑这些事实的关键证据:',
renderHumanEvidenceLines(state, 'brain_prompt'),
'',
'仍未解决的问题:',
renderHumanOpenQuestionLines(state, 'brain_prompt')
].join('\n')
const buildSelectedContextPromptText = (ctx: AiRunContext): string =>
[
'下面是当前用户明确给出的参考资料上下文。后续判断、检索和文件定位都必须先对齐这段信息。',
'',
ctx.selectedContextText
].join('\n')
const buildSkillContextText = (state: HumanState): string => {
const learnedSkillIds = state.brainMemory.outside.learnedSkillIds
const learnedSkillDefinitions = learnedSkillIds.map((skillId) => getSkillDefinition(skillId))
const learnedToolNames = Array.from(
new Set(learnedSkillDefinitions.flatMap((definition) => definition.toolNames))
)
const learnedToolSpecLines =
learnedToolNames.length > 0
? learnedToolNames
.map((toolName) => getToolPromptSpec(toolName))
.filter((spec): spec is ToolPromptSpec => Boolean(spec))
.map(renderLearnedToolSpecLine)
: ['none']
const skillCatalogLines =
state.brainMemory.outside.skillCatalog.length > 0
? state.brainMemory.outside.skillCatalog.map(
(item) =>
`- ${item.skillId}:${item.summary};可提供工具=[${item.toolNames.join(', ')}];适用场景=${item.whenToUse}`
)
: ['none']
const learnedSkillIdLines =
learnedSkillIds.length > 0 ? learnedSkillIds.map((skillId) => `- ${skillId}`) : ['none']
const learnedSkillDetailLines =
learnedSkillDefinitions.length > 0
? learnedSkillDefinitions.map((definition) => `- ${definition.skillId}:${definition.detail}`)
: ['none']
return [
'下面是当前可用的技能信息。技能目录摘要只用于判断要不要学习;只有已学习 skill 的详细说明和工具要点,才代表你当前可以直接依赖的能力。',
'',
'当前可用技能目录摘要:',
formatPlainList(skillCatalogLines),
'',
'已经学习的 skill id:',
formatPlainList(learnedSkillIdLines),
'',
'已学习技能的详细说明:',
formatPlainList(learnedSkillDetailLines),
'',
'已学习技能对应的工具使用要点:',
formatPlainList(learnedToolSpecLines)
].join('\n')
}
const buildRecentToolResultsText = (state: HumanState): string =>
[
'下面是最近一轮工具调用刚带回来的新信息。请把这些结果和已有记忆一起判断,不要重复做同样的动作。',
'',
renderLineList(
(state.lastParallelCallToolResults || []).map((result, index) =>
buildRecentToolResultLine(result, index)
),
{
fallback: 'none',
style: 'plain'
}
)
].join('\n')
const buildRecentDecisionHistoryText = (state: HumanState): string =>
[
'下面是最近几轮已经做过的正式判断摘要,只用于帮助你理解时间顺序并避免重复决策。',
'',
renderLineList(
state.brainMemory.outside.brainDecisions.map((record, index) => {
const ordinal = index + 1
const action = record.nextAction.action
const nextActionPayload =
action === 'learning'
? `wantLearnSkillIds=[${record.nextAction.wantLearnSkillIds.join(',')}]`
: action === 'hand'
? `parallelCallToolParam=${JSON.stringify(record.nextAction.parallelCallToolParam)}`
: 'final_delivery=true'
return `- 第${ordinal}轮(createdAt=${record.createdAt}):决定“${record.decision.summary}”;原因:${record.decision.reason};预期结果:${record.decision.expectedOutcome};nextAction.action=${action};nextAction数据:${nextActionPayload}`
}),
{
fallback: 'none',
style: 'plain'
}
)
].join('\n')
const buildWatchHintText = (state: HumanState): string =>
[
'如果这里是 none,表示当前没有额外的收敛提醒;否则应优先考虑结束任务或纠偏。',
'',
state.watchHint || 'none'
].join('\n')
export const buildBrainSystemPrompt = (): string =>
`
<system>
<role>
你现在扮演一个负责分析情况、整理记忆、做出下一步判断的大脑角色。
@@ -206,8 +336,10 @@ export const buildHumanBrainPrompt = (input: HumanBrainPromptInput) => {
</example_mouth>
</output_examples>
</system>
`.trim(),
user: `
`.trim()
export const buildBrainUserPrompt = (input: HumanBrainPromptInput): string =>
`
<user_context>
<user_request>
${input.userInput}
@@ -238,5 +370,22 @@ ${input.watchHintText}
</converge_hint>
</user_context>
`.trim()
export const buildBrainPromptContext = (input: { state: HumanState; ctx: AiRunContext }) => {
return buildHumanBrainPrompt({
userInput: input.state.task.userInput,
memorySnapshotText: buildMemorySnapshotText(input.state),
selectedContextText: buildSelectedContextPromptText(input.ctx),
skillContextText: buildSkillContextText(input.state),
recentToolResultsText: buildRecentToolResultsText(input.state),
recentDecisionHistoryText: buildRecentDecisionHistoryText(input.state),
watchHintText: buildWatchHintText(input.state)
})
}
export const buildHumanBrainPrompt = (input: HumanBrainPromptInput) => {
return {
system: buildBrainSystemPrompt(),
user: buildBrainUserPrompt(input)
}
}
@@ -1,182 +0,0 @@
import type { AiRunContext } from '../../types'
import type { HumanState, ToolPromptSpec } from '../types'
import { getSkillDefinition } from '../skills'
import { getToolPromptSpec } from '../tools/registry'
import { renderLineList } from '../../utils/render'
import {
renderHumanEvidenceLines,
renderHumanFactLines,
renderHumanOpenQuestionLines
} from '../shared/memoryRenderers'
const formatList = (items: string[]): string =>
renderLineList(items, {
fallback: 'none',
style: 'plain'
})
type BrainPromptRenderView = {
factLines: string
evidenceLines: string
openQuestionLines: string
selectedContextText: string
skillCatalogLines: string[]
learnedSkillIdLines: string[]
learnedSkillDetailLines: string[]
learnedToolSpecLines: string[]
recentToolResultLines: string
recentDecisionHistoryLines: string
}
export type BrainPromptSections = {
memorySnapshotText: string
selectedContextText: string
skillContextText: string
recentToolResultsText: string
recentDecisionHistoryText: string
}
const renderLearnedToolSpecLine = (spec: ToolPromptSpec): string => {
const requiredArgs = spec.args
.filter((arg) => arg.required)
.map((arg) => `${arg.name}:${arg.type}`)
.join(', ')
const example = spec.examples?.[0]
? `示例目标=${spec.examples[0].goal};示例参数键=[${Object.keys(spec.examples[0].args).join(', ') || 'none'}]`
: '示例=none'
return `- 工具 ${spec.name}:适用场景=${spec.whenToUse};必填参数=[${requiredArgs || 'none'}];${example}`
}
const buildRecentToolResultLine = (
result: NonNullable<HumanState['lastParallelCallToolResults']>[number],
index: number
): string => {
const diagnosticText = result.diagnostic
? `;diagnostic=${result.diagnostic.kind}${result.diagnostic.missingArgs?.length ? `;missingArgs=[${result.diagnostic.missingArgs.join(', ')}]` : ''}`
: ''
return `- 第${index + 1}项:工具 ${result.toolName} ${result.ok ? '执行成功' : '执行失败'}(code=${result.code});摘要:${result.summary}${diagnosticText}`
}
const buildBrainPromptRenderView = (input: {
state: HumanState
ctx: AiRunContext
}): BrainPromptRenderView => {
const { state, ctx } = input
const learnedSkillIds = state.brainMemory.outside.learnedSkillIds
const learnedSkillDefinitions = learnedSkillIds.map((skillId) => getSkillDefinition(skillId))
const learnedToolNames = Array.from(
new Set(learnedSkillDefinitions.flatMap((definition) => definition.toolNames))
)
const learnedToolSpecLines =
learnedToolNames.length > 0
? learnedToolNames
.map((toolName) => getToolPromptSpec(toolName))
.filter((spec): spec is ToolPromptSpec => Boolean(spec))
.map(renderLearnedToolSpecLine)
: ['none']
const recentToolResultLines = renderLineList(
(state.lastParallelCallToolResults || []).map((result, index) =>
buildRecentToolResultLine(result, index)
),
{
fallback: 'none',
style: 'plain'
}
)
const recentDecisionHistoryLines = renderLineList(
state.brainMemory.outside.brainDecisions.map((record, index) => {
const ordinal = index + 1
const action = record.nextAction.action
const nextActionPayload =
action === 'learning'
? `wantLearnSkillIds=[${record.nextAction.wantLearnSkillIds.join(',')}]`
: action === 'hand'
? `parallelCallToolParam=${JSON.stringify(record.nextAction.parallelCallToolParam)}`
: 'final_delivery=true'
return `- 第${ordinal}轮(createdAt=${record.createdAt}):决定“${record.decision.summary}”;原因:${record.decision.reason};预期结果:${record.decision.expectedOutcome};nextAction.action=${action};nextAction数据:${nextActionPayload}`
}),
{
fallback: 'none',
style: 'plain'
}
)
return {
factLines: renderHumanFactLines(state, 'brain_prompt'),
evidenceLines: renderHumanEvidenceLines(state, 'brain_prompt'),
openQuestionLines: renderHumanOpenQuestionLines(state, 'brain_prompt'),
selectedContextText: ctx.selectedContextText,
skillCatalogLines:
state.brainMemory.outside.skillCatalog.length > 0
? state.brainMemory.outside.skillCatalog.map(
(item) =>
`- ${item.skillId}:${item.summary};可提供工具=[${item.toolNames.join(', ')}];适用场景=${item.whenToUse}`
)
: ['none'],
learnedSkillIdLines:
learnedSkillIds.length > 0 ? learnedSkillIds.map((skillId) => `- ${skillId}`) : ['none'],
learnedSkillDetailLines:
learnedSkillDefinitions.length > 0
? learnedSkillDefinitions.map((definition) => `- ${definition.skillId}:${definition.detail}`)
: ['none'],
learnedToolSpecLines,
recentToolResultLines,
recentDecisionHistoryLines
}
}
export const buildBrainPromptSections = (input: {
state: HumanState
ctx: AiRunContext
}): BrainPromptSections => {
const view = buildBrainPromptRenderView(input)
return {
memorySnapshotText: [
'下面是你之前沉淀下来的记忆。这些内容代表当前已经确认、可以直接复用或仍影响推进的信息。',
'',
'已确认的事实:',
view.factLines,
'',
'支撑这些事实的关键证据:',
view.evidenceLines,
'',
'仍未解决的问题:',
view.openQuestionLines
].join('\n'),
selectedContextText: [
'下面是当前用户明确给出的参考资料上下文。后续判断、检索和文件定位都必须先对齐这段信息。',
'',
view.selectedContextText
].join('\n'),
skillContextText: [
'下面是当前可用的技能信息。技能目录摘要只用于判断要不要学习;只有已学习 skill 的详细说明和工具要点,才代表你当前可以直接依赖的能力。',
'',
'当前可用技能目录摘要:',
formatList(view.skillCatalogLines),
'',
'已经学习的 skill id:',
formatList(view.learnedSkillIdLines),
'',
'已学习技能的详细说明:',
formatList(view.learnedSkillDetailLines),
'',
'已学习技能对应的工具使用要点:',
formatList(view.learnedToolSpecLines)
].join('\n'),
recentToolResultsText: [
'下面是最近一轮工具调用刚带回来的新信息。请把这些结果和已有记忆一起判断,不要重复做同样的动作。',
'',
view.recentToolResultLines
].join('\n'),
recentDecisionHistoryText: [
'下面是最近几轮已经做过的正式判断摘要,只用于帮助你理解时间顺序并避免重复决策。',
'',
view.recentDecisionHistoryLines
].join('\n')
}
}
+30 -24
View File
@@ -30,26 +30,8 @@ const buildFinalDecisionText = (state: HumanState): string =>
? `最终决定:“${state.lastBrainDecision.decision.summary}”;原因:${state.lastBrainDecision.decision.reason};预期结果:${state.lastBrainDecision.decision.expectedOutcome}`
: 'none'
export const buildMouthPromptContext = (input: {
state: HumanState
deliveryMode: HumanDeliveryMode
}) => {
return buildHumanMouthPrompt({
deliveryMode: input.deliveryMode,
userInput: input.state.task.userInput,
finalDecisionText: buildFinalDecisionText(input.state),
factsText: renderHumanFactLines(input.state, 'mouth_prompt'),
evidencesText: renderHumanEvidenceLines(input.state, 'mouth_prompt'),
openQuestionsText: renderHumanOpenQuestionLines(input.state, 'mouth_prompt'),
recentToolResultsText: renderHumanRecentToolResultLines(input.state, 'prompt'),
runtimeArtifactsText: renderHumanArtifactLines(input.state, 'prompt'),
watchHintText: input.state.watchHint || 'none'
})
}
export const buildHumanMouthPrompt = (input: HumanMouthPromptInput) => {
return {
system: `
export const buildMouthSystemPrompt = (deliveryMode: HumanDeliveryMode): string =>
`
<system>
<role>
你现在扮演一个负责对外表达最终结果的人。
@@ -71,7 +53,7 @@ export const buildHumanMouthPrompt = (input: HumanMouthPromptInput) => {
</delivery_principles>
<delivery_mode_rules>
${buildDeliveryModePromptRules(input.deliveryMode)}
${buildDeliveryModePromptRules(deliveryMode)}
</delivery_mode_rules>
<output_rules>
@@ -97,11 +79,13 @@ ${buildDeliveryModePromptRules(input.deliveryMode)}
</output_principles>
<output_example>
${buildDeliveryModePromptExample(input.deliveryMode)}
${buildDeliveryModePromptExample(deliveryMode)}
</output_example>
</system>
`.trim(),
user: `
`.trim()
export const buildMouthUserPrompt = (input: HumanMouthPromptInput): string =>
`
<user_context>
<delivery_mode>
${input.deliveryMode}
@@ -140,5 +124,27 @@ ${input.watchHintText}
</watch_hint>
</user_context>
`.trim()
export const buildMouthPromptContext = (input: {
state: HumanState
deliveryMode: HumanDeliveryMode
}) => {
return buildHumanMouthPrompt({
deliveryMode: input.deliveryMode,
userInput: input.state.task.userInput,
finalDecisionText: buildFinalDecisionText(input.state),
factsText: renderHumanFactLines(input.state, 'mouth_prompt'),
evidencesText: renderHumanEvidenceLines(input.state, 'mouth_prompt'),
openQuestionsText: renderHumanOpenQuestionLines(input.state, 'mouth_prompt'),
recentToolResultsText: renderHumanRecentToolResultLines(input.state, 'prompt'),
runtimeArtifactsText: renderHumanArtifactLines(input.state, 'prompt'),
watchHintText: input.state.watchHint || 'none'
})
}
export const buildHumanMouthPrompt = (input: HumanMouthPromptInput) => {
return {
system: buildMouthSystemPrompt(input.deliveryMode),
user: buildMouthUserPrompt(input)
}
}