feat: add language-first operating contract
This commit is contained in:
parent
d35b46a5b5
commit
79dd5f3920
5 changed files with 257 additions and 2 deletions
|
|
@ -0,0 +1,69 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
DEFAULT_HUMAN_SURFACE,
|
||||
SYSTEM_INTERNAL_SURFACE,
|
||||
compileLanguageGoal,
|
||||
} from './languageOperatingModel'
|
||||
|
||||
describe('languageOperatingModel', () => {
|
||||
it('treats natural language as the required primary input', () => {
|
||||
expect(() => compileLanguageGoal({ utterance: ' ', personaAuthorized: false }))
|
||||
.toThrow('LANGUAGE_GOAL_REQUIRED')
|
||||
|
||||
expect(compileLanguageGoal({
|
||||
utterance: ' 帮我把今天的会议整理进知识库 ',
|
||||
personaAuthorized: false,
|
||||
}).goal).toBe('帮我把今天的会议整理进知识库')
|
||||
})
|
||||
|
||||
it('keeps an unauthorized persona explanatory while the system remains direct', () => {
|
||||
const projection = compileLanguageGoal({
|
||||
utterance: '帮我整理桌面上的项目资料',
|
||||
personaAuthorized: false,
|
||||
})
|
||||
|
||||
expect(projection.mode).toBe('system_direct')
|
||||
expect(projection.status).toBe('ready')
|
||||
expect(projection.receiptSummary).toContain('人格体只提供解释和计划')
|
||||
})
|
||||
|
||||
it('uses an explicitly authorized persona as the semantic agent', () => {
|
||||
const projection = compileLanguageGoal({
|
||||
utterance: '继续开发 HoloLake',
|
||||
personaAuthorized: true,
|
||||
})
|
||||
|
||||
expect(projection.mode).toBe('persona_primary')
|
||||
expect(projection.receiptSummary).toContain('系统校验并执行')
|
||||
})
|
||||
|
||||
it('asks for one human decision only when a reality boundary is detected', () => {
|
||||
const projection = compileLanguageGoal({
|
||||
utterance: '把这个版本公开发布出去',
|
||||
personaAuthorized: true,
|
||||
detectedBoundaries: ['public_release', 'new_cost', 'public_release'],
|
||||
})
|
||||
|
||||
expect(projection.status).toBe('needs_confirmation')
|
||||
expect(projection.confirmation).toEqual(expect.objectContaining({
|
||||
required: true,
|
||||
boundaries: ['public_release', 'new_cost'],
|
||||
}))
|
||||
expect(projection.confirmation.question).toContain('公开发布')
|
||||
expect(projection.confirmation.question).toContain('新的费用')
|
||||
expect(projection.confirmation.question).toContain('不同意')
|
||||
})
|
||||
|
||||
it('keeps technical controls out of the default human surface', () => {
|
||||
expect(DEFAULT_HUMAN_SURFACE).toEqual([
|
||||
'language_input',
|
||||
'task_status',
|
||||
'reality_boundary_confirmation',
|
||||
'human_receipt',
|
||||
])
|
||||
expect(DEFAULT_HUMAN_SURFACE).not.toContain('node_identity')
|
||||
expect(SYSTEM_INTERNAL_SURFACE).toContain('node_identity')
|
||||
expect(SYSTEM_INTERNAL_SURFACE).toContain('repository_route')
|
||||
expect(SYSTEM_INTERNAL_SURFACE).toContain('model_configuration')
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
export type LanguageControlMode = 'system_direct' | 'persona_primary'
|
||||
|
||||
export type RealityBoundary =
|
||||
| 'new_cost'
|
||||
| 'data_egress'
|
||||
| 'new_external_account'
|
||||
| 'permission_expansion'
|
||||
| 'public_release'
|
||||
| 'irreversible_change'
|
||||
| 'privacy_or_credential'
|
||||
| 'private_relationship'
|
||||
|
||||
export type LanguageGoalRequest = {
|
||||
utterance: string
|
||||
personaAuthorized: boolean
|
||||
detectedBoundaries?: RealityBoundary[]
|
||||
}
|
||||
|
||||
export type HumanConfirmation = {
|
||||
required: boolean
|
||||
boundaries: RealityBoundary[]
|
||||
question: string | null
|
||||
}
|
||||
|
||||
export type LanguageGoalProjection = {
|
||||
goal: string
|
||||
mode: LanguageControlMode
|
||||
status: 'ready' | 'needs_confirmation'
|
||||
confirmation: HumanConfirmation
|
||||
receiptSummary: string
|
||||
}
|
||||
|
||||
const BOUNDARY_LABELS: Record<RealityBoundary, string> = {
|
||||
new_cost: '会产生新的费用',
|
||||
data_egress: '会让数据离开当前设备',
|
||||
new_external_account: '会创建或绑定新的外部账号',
|
||||
permission_expansion: '会扩大现有权限',
|
||||
public_release: '会公开发布或代表你向外发送内容',
|
||||
irreversible_change: '包含难以恢复的迁移、覆盖或删除',
|
||||
privacy_or_credential: '需要隐私、钥匙串、验证码或身份确认',
|
||||
private_relationship: '会触及私人关系或不可转让关系核心',
|
||||
}
|
||||
|
||||
function normalizeBoundaries(boundaries: RealityBoundary[] | undefined): RealityBoundary[] {
|
||||
return [...new Set(boundaries ?? [])]
|
||||
}
|
||||
|
||||
export function compileLanguageGoal(request: LanguageGoalRequest): LanguageGoalProjection {
|
||||
const goal = request.utterance.trim()
|
||||
if (!goal) throw new Error('LANGUAGE_GOAL_REQUIRED')
|
||||
|
||||
const boundaries = normalizeBoundaries(request.detectedBoundaries)
|
||||
const confirmationRequired = boundaries.length > 0
|
||||
const mode: LanguageControlMode = request.personaAuthorized
|
||||
? 'persona_primary'
|
||||
: 'system_direct'
|
||||
|
||||
return {
|
||||
goal,
|
||||
mode,
|
||||
status: confirmationRequired ? 'needs_confirmation' : 'ready',
|
||||
confirmation: {
|
||||
required: confirmationRequired,
|
||||
boundaries,
|
||||
question: confirmationRequired
|
||||
? `继续前需要你确认:${boundaries.map((boundary) => BOUNDARY_LABELS[boundary]).join(';')}。不同意也不会影响你继续使用其他功能。`
|
||||
: null,
|
||||
},
|
||||
receiptSummary: confirmationRequired
|
||||
? '我已经理解你的目标,正在等待一个现实边界决定。'
|
||||
: mode === 'persona_primary'
|
||||
? '我已经理解你的目标,将由获授权的人格体规划,系统校验并执行。'
|
||||
: '我已经理解你的目标;当前由系统处理安全范围内的动作,人格体只提供解释和计划。',
|
||||
}
|
||||
}
|
||||
|
||||
export const DEFAULT_HUMAN_SURFACE = [
|
||||
'language_input',
|
||||
'task_status',
|
||||
'reality_boundary_confirmation',
|
||||
'human_receipt',
|
||||
] as const
|
||||
|
||||
export const SYSTEM_INTERNAL_SURFACE = [
|
||||
'node_identity',
|
||||
'permission_policy',
|
||||
'repository_route',
|
||||
'model_configuration',
|
||||
'tool_parameters',
|
||||
'deployment_log',
|
||||
] as const
|
||||
Loading…
Reference in a new issue