From cf7df54874c20f8ae9cb4e48b2c75f9ef6968f14 Mon Sep 17 00:00:00 2001 From: weichen Date: Sat, 3 Oct 2026 16:56:14 +0000 Subject: [PATCH] Add session permission mode and confirmation detail Why: The product needs a session mode and a place to show tool arguments on a confirmation card without inventing a second card type. Evidence: GOWORK=off go test . passed. New fields use omitempty, so existing golden JSON stays the same. Impact: Empty permission mode still means the profile policy. Clients that ignore unknown fields keep working. Refs: feature/permission-hooks Co-authored-by: Cursor --- hitl.go | 2 ++ model.go | 20 +++++++++++--------- tools.go | 26 +++++++++++++++----------- ts/types.ts | 2 ++ 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/hitl.go b/hitl.go index 9d589d6..14e203f 100644 --- a/hitl.go +++ b/hitl.go @@ -23,6 +23,8 @@ type HITLCard struct { // Blocked:阻断态(门禁不通过等)——确认入口禁用并给出出路;阻断本身进审计。 Blocked bool `json:"blocked,omitempty"` BlockReason string `json:"blockReason,omitempty"` + // Detail 是确认卡上的参数预览或其他补充说明。 + Detail string `json:"detail,omitempty"` } type HITLKind string diff --git a/model.go b/model.go index 132fd40..b67a6fc 100644 --- a/model.go +++ b/model.go @@ -26,15 +26,17 @@ type Project struct { } type Conversation struct { - ID ID `json:"id"` - ProjectID ID `json:"projectId"` - Owner ID `json:"owner,omitempty"` // 冗余自项目,查询过滤用 - Title string `json:"title"` - ProfileID ID `json:"profileId,omitempty"` // 空为默认画像 - Pinned bool `json:"pinned,omitempty"` // 侧栏置顶(方案 A P6/P8:本端组织偏好,服务端权威) - Archived bool `json:"archived,omitempty"` // 归档:列表默认隐藏,数据保留 - AllowCrossRead bool `json:"allowCrossRead,omitempty"` // 跨会话出站:本会话读取同项目其他会话记录(需项目开关 crossSession.read) - CrossPrivate bool `json:"crossPrivate,omitempty"` // 跨会话入站:私有会话,不被他读、不出现在他方列表 + ID ID `json:"id"` + ProjectID ID `json:"projectId"` + Owner ID `json:"owner,omitempty"` // 冗余自项目,查询过滤用 + Title string `json:"title"` + ProfileID ID `json:"profileId,omitempty"` // 空为默认画像 + Pinned bool `json:"pinned,omitempty"` // 侧栏置顶(方案 A P6/P8:本端组织偏好,服务端权威) + Archived bool `json:"archived,omitempty"` // 归档:列表默认隐藏,数据保留 + AllowCrossRead bool `json:"allowCrossRead,omitempty"` // 跨会话出站:本会话读取同项目其他会话记录(需项目开关 crossSession.read) + CrossPrivate bool `json:"crossPrivate,omitempty"` // 跨会话入站:私有会话,不被他读、不出现在他方列表 + // PermissionMode 是会话权限:空或 default 沿用画像;plan 只读加计划工具;auto_edit 放行工作区写文件。 + PermissionMode string `json:"permissionMode,omitempty"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } diff --git a/tools.go b/tools.go index 2ed1d17..b1855ef 100644 --- a/tools.go +++ b/tools.go @@ -23,16 +23,20 @@ type ToolDesc struct { // Hidden 预留能力形态:默认不对模型与 /api/tools 列表可见,须运行时开关 // (如 runtime.fsTools)或管理动作开启后可用(提案 2026-09-30-file-preview-and-reserved-capabilities)。 Hidden bool `json:"hidden,omitempty"` + // ReadOnly、Edits、Risk 是工具注册时的权限声明。Risk 取 low、medium、high。 + ReadOnly bool `json:"readOnly,omitempty"` + Edits bool `json:"edits,omitempty"` + Risk string `json:"risk,omitempty"` } // HTTPToolSpec:无代码自定义工具(4.8)。模板变量 {{param.x}} 从调用参数注入。 type HTTPToolSpec struct { - Method string `json:"method"` - URL string `json:"url"` - Headers map[string]string `json:"headers,omitempty"` - BodyTemplate string `json:"bodyTemplate,omitempty"` // JSON 模板 - AuthRef string `json:"authRef,omitempty"` // 设置中的密钥引用(settings key) - TimeoutMs int `json:"timeoutMs,omitempty"` + Method string `json:"method"` + URL string `json:"url"` + Headers map[string]string `json:"headers,omitempty"` + BodyTemplate string `json:"bodyTemplate,omitempty"` // JSON 模板 + AuthRef string `json:"authRef,omitempty"` // 设置中的密钥引用(settings key) + TimeoutMs int `json:"timeoutMs,omitempty"` // ResultPath 从响应 JSON 中裁剪(jq 点路径);空取整个响应。 ResultPath string `json:"resultPath,omitempty"` } @@ -44,9 +48,9 @@ type ToolCallRequest struct { } type ToolCallResult struct { - CallID string `json:"callId"` - Status string `json:"status"` // ok | error - Output string `json:"output,omitempty"` - Truncated bool `json:"truncated,omitempty"` - Artifact *Artifact `json:"artifact,omitempty"` // 超长转工件 + CallID string `json:"callId"` + Status string `json:"status"` // ok | error + Output string `json:"output,omitempty"` + Truncated bool `json:"truncated,omitempty"` + Artifact *Artifact `json:"artifact,omitempty"` // 超长转工件 } diff --git a/ts/types.ts b/ts/types.ts index 067b6f1..165c1f4 100644 --- a/ts/types.ts +++ b/ts/types.ts @@ -15,6 +15,7 @@ export interface Conversation { id: ID; projectId: ID; owner?: ID; title: string; profileId?: ID; pinned?: boolean; archived?: boolean; allowCrossRead?: boolean; crossPrivate?: boolean; + permissionMode?: 'default' | 'plan' | 'auto_edit' | ''; createdAt: string; updatedAt: string; } @@ -150,6 +151,7 @@ export interface HITLCard { choices?: HITLChoice[]; allowFreeInput: boolean; freeInputHint?: string; timeoutSec?: number | null; form?: UINode[]; createdAt: string; resolved: boolean; anchorMessageId?: ID; blocked?: boolean; blockReason?: string; + detail?: string; } export interface HITLResponse {