@coda-console/protocol 3.3.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  按 semver。协议自己的大版本写在协议名里(如 `coda/run@1`),与 npm 包版本、插件清单的 v2 独立;更早的版本见 git 历史。
4
4
 
5
+ ## 3.5.0 — 2026-11-09
6
+
7
+ - 流程参数的 `agent` 类型:值是一组 Agent 选择,与插件设置的 Agent 组合(`format: coda-agent`)相同:`agent`,以及可选的 `model`、`effort`、`mode`、`options`。不写 `default`;`defaultFrom="session.agent"` 是从会话发起、没给值时取那个会话的 Agent 选择,只用于这种参数(Coda #2303 第 4 步)。
8
+
9
+ ## 3.4.0 — 2026-11-09
10
+
11
+ - `coda/session@1` 的 `read`:都不带游标时读最新的 `limit` 条;写清 `before` 是这个游标之前最新的 `limit` 条、`more` 表示更早还有没有;消息总按先后排;`after` 与 `before` 不能同时带(Coda #2311)。
12
+ - `coda/session@1` 的消息加可选的 `senderName`:发送者当时的显示名,大群不必把每个发送者都写进 `status.participants`。
13
+
5
14
  ## 3.3.0 — 2026-11-09
6
15
 
7
16
  - `coda:choice` 的 `note`:`required` 时选它必须附言(写说明或附上文件),默认 `optional`(Coda #2303 第 3 步:卡片在输入框里填写)。
package/docs/protocol.md CHANGED
@@ -293,12 +293,17 @@ status:
293
293
 
294
294
  观察方 watch 这条记录,`head` 变了就用 `read` 读游标之后的消息。两个操作都是立即结果,不开运行;`read` 是 `safe` 的:
295
295
 
296
- - `read`:输入 `{ after?, before?, limit? }`,`after`、`before` 是游标,`limit` 为 1 到 100;结果 `{ messages, cursor, more }`,没有消息时 `cursor` 为 `null`。
296
+ - `read`:输入 `{ after?, before?, limit? }`,`after`、`before` 是游标,`limit` 为 1 到 100;结果 `{ messages, cursor, more }`,没有消息时 `cursor` 为 `null`。`messages` 总按先后排,旧的在前:
297
+ - 都不带游标:最新的 `limit` 条,`more` 表示更早还有没有;客户端打开会话时先读这一页;
298
+ - 只带 `after`:这个游标之后的,`more` 表示之后还有没有;
299
+ - 只带 `before`:这个游标之前最新的 `limit` 条,`more` 表示更早还有没有;往前翻页就拿这一页第一条的 `cursor` 作下一次的 `before`;
300
+ - `after` 与 `before` 不能同时带。
297
301
  - `post`:输入 `{ text, parts?, replyTo?, mentions? }`;结果 `{ message: { id, cursor } }`。发送者固定是 `self`;Provider 按调用的 `requestId` 只发一次,发送失败就报错。
298
302
 
299
- 消息是 `{ id, cursor, sender, text, parts?, replyTo?, mentions?, about?, createdAt? }`:
303
+ 消息是 `{ id, cursor, sender, senderName?, text, parts?, replyTo?, mentions?, about?, createdAt? }`:
300
304
 
301
305
  - `sender` 与 `mentions` 写参与者 ID,`replyTo` 写消息 ID;
306
+ - `senderName` 是发送者当时的显示名,可选:大群不必把每个发送者都写进 `status.participants`;
302
307
  - 回复一条消息就算 @ 了它的发送者,Provider 把被回复消息的发送者也写进 `mentions`:只有 Provider 知道被回复的那条是谁发的,观察方不用记住 Bot 发过哪些消息;
303
308
  - `text` 是纯文本兜底,看不懂 `parts` 的一方只看它;
304
309
  - 撤回、编辑、表情回应都是一条新消息,`about: { message, change: "edit"|"recall"|"reaction", value? }` 指向旧消息;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coda-console/protocol",
3
- "version": "3.3.0",
3
+ "version": "3.5.0",
4
4
  "description": "Coda 的协议:插件清单的类型(JSON Schema)、通用校验器、协议定义与调用信封、流程方言与 Agent 接入协议",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -58,7 +58,7 @@
58
58
  },
59
59
  "operations": {
60
60
  "read": {
61
- "description": "读消息:after、before 是游标,limit 为 1 到 100;立即结果。",
61
+ "description": "读消息,limit 为 1 到 100,消息总按先后排(旧在前);立即结果。都不带游标时读最新的 limit 条,more 表示更早还有没有;带 after 读这个游标之后的,more 表示之后还有没有;带 before 读这个游标之前最新的 limit 条,more 表示更早还有没有。after 与 before 不能同时带。",
62
62
  "safe": true,
63
63
  "input": {
64
64
  "$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -68,6 +68,7 @@
68
68
  "before": {"type": "string", "minLength": 1, "maxLength": 2048},
69
69
  "limit": {"type": "integer", "minimum": 1, "maximum": 100}
70
70
  },
71
+ "not": {"required": ["after", "before"]},
71
72
  "additionalProperties": false
72
73
  },
73
74
  "result": {
@@ -109,6 +110,7 @@
109
110
  "id": {"$ref": "#/$defs/id"},
110
111
  "cursor": {"$ref": "#/$defs/id"},
111
112
  "sender": {"$ref": "#/$defs/id", "description": "参与者 ID"},
113
+ "senderName": {"type": "string", "maxLength": 200, "description": "发送者当时的显示名,可选;大群不必把每个发送者都写进 status.participants"},
112
114
  "text": {"type": "string", "description": "纯文本兜底"},
113
115
  "parts": {"type": "array", "items": {"$ref": "#/$defs/part"}},
114
116
  "replyTo": {"$ref": "#/$defs/id", "description": "回复的消息 ID"},
@@ -20,7 +20,7 @@
20
20
  "stepFailed": "STEP_FAILED",
21
21
  "variables": ["inputs", "run", "github", "vars"],
22
22
  "inputs": {
23
- "types": ["string", "boolean", "number", "branch"],
24
- "sources": {"session.branch": ["branch", "string"]}
23
+ "types": ["string", "boolean", "number", "branch", "agent"],
24
+ "sources": {"session.branch": ["branch", "string"], "session.agent": ["agent"]}
25
25
  }
26
26
  }
@@ -120,7 +120,7 @@
120
120
  {
121
121
  "name": "Input",
122
122
  "superClass": ["Element"],
123
- "description": "运行的一个输入:label 是表单上的名字,defaultFrom 是从会话发起、没给值时从哪里取(在 default 之前)",
123
+ "description": "运行的一个输入:label 是表单上的名字,defaultFrom 是从会话发起、没给值时从哪里取(在 default 之前);type 为 agent 的值是一组 Agent 选择(agent,以及可选的 model、effort、mode、options)",
124
124
  "properties": [
125
125
  {"name": "name", "isAttr": true, "type": "String"},
126
126
  {"name": "type", "isAttr": true, "type": "String"},
@@ -92,13 +92,15 @@
92
92
  "not": {"enum": ["__defineGetter__", "__defineSetter__", "__lookupGetter__", "__lookupSetter__", "__proto__", "constructor", "hasOwnProperty", "isPrototypeOf",
93
93
  "propertyIsEnumerable", "toLocaleString", "toString", "valueOf"]},
94
94
  "description": "name 不合法:须为字母开头的字母、数字、「_」,且不是 JavaScript 对象自带的名字(如 constructor、toString、__proto__):运行按名字记和取输入"},
95
- "type": {"enum": ["string", "boolean", "number", "branch"], "description": "type 只能是 string、boolean、number、branch"},
95
+ "type": {"enum": ["string", "boolean", "number", "branch", "agent"], "description": "type 只能是 string、boolean、number、branch、agent"},
96
96
  "label": {"type": "string", "pattern": "\\S", "maxLength": 40, "description": "label 须为 1–40 个字"},
97
- "defaultFrom": {"enum": ["session.branch"], "description": "defaultFrom 只能是 session.branch"}
97
+ "defaultFrom": {"enum": ["session.branch", "session.agent"], "description": "defaultFrom 只能是 session.branch 或 session.agent"}
98
98
  },
99
99
  "required": ["name"],
100
100
  "allOf": [
101
- {"if": {"required": ["defaultFrom"]}, "then": {"properties": {"type": {"enum": ["branch", "string"], "description": "defaultFrom=\"session.branch\" 只用于 type 为 branch、string 的参数"}}}},
101
+ {"if": {"required": ["defaultFrom"], "properties": {"defaultFrom": {"const": "session.branch"}}}, "then": {"properties": {"type": {"enum": ["branch", "string"], "description": "defaultFrom=\"session.branch\" 只用于 type 为 branch、string 的参数"}}}},
102
+ {"if": {"required": ["defaultFrom"], "properties": {"defaultFrom": {"const": "session.agent"}}}, "then": {"required": ["type"], "description": "defaultFrom=\"session.agent\" 只用于 type 为 agent 的参数", "properties": {"type": {"enum": ["agent"], "description": "defaultFrom=\"session.agent\" 只用于 type 为 agent 的参数"}}}},
103
+ {"if": {"required": ["type"], "properties": {"type": {"const": "agent"}}}, "then": {"not": {"required": ["default"]}, "description": "type 为 agent 的参数不写 default:值是一组 Agent 选择,从会话取用 defaultFrom=\"session.agent\""}},
102
104
  {"if": {"required": ["type"], "properties": {"type": {"const": "number"}}},
103
105
  "then": {"properties": {"default": {"pattern": "^\\s*[-+]?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][-+]?\\d+)?\\s*$", "x-number": true, "description": "default 须为数字"}}}}
104
106
  ]