@coda-console/protocol 2.6.0 → 3.1.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 +41 -0
- package/README.md +39 -11
- package/docs/agent-protocol.md +26 -21
- package/docs/protocol.md +363 -0
- package/package.json +5 -4
- package/protocol.mjs +140 -0
- package/schemas/agent/wait.json +4 -0
- package/schemas/plugin/extension-points.json +2 -0
- package/schemas/plugin/plugin.json +2 -0
- package/schemas/plugin/protocol-implementations.json +10 -0
- package/schemas/plugin/protocols.json +11 -0
- package/schemas/plugin/setting.json +1 -1
- package/schemas/protocol/v1/agent.json +69 -0
- package/schemas/protocol/v1/definition.json +57 -0
- package/schemas/protocol/v1/environment.json +105 -0
- package/schemas/protocol/v1/executor.json +279 -0
- package/schemas/protocol/v1/request.json +29 -0
- package/schemas/protocol/v1/response.json +25 -0
- package/schemas/protocol/v1/run.json +75 -0
- package/schemas/protocol/v1/session.json +206 -0
- package/validate.mjs +4 -1
- package/workflow/actions.json +0 -2
- package/workflow/dialect.json +2 -1
- package/workflow/moddle.json +1 -2
- package/workflow/values.json +3 -3
- package/docs/executor-protocol.md +0 -261
- package/executor.mjs +0 -21
- package/schemas/executor/v1/common.json +0 -89
- package/schemas/executor/v1/execution.json +0 -246
- package/schemas/executor/v1/executor.json +0 -98
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "coda/agent@1",
|
|
3
|
+
"title": "Agent",
|
|
4
|
+
"description": "一台机器上装着的 Agent 程序及其模型与审批模式,照 Coda 的 Agent 资源 spec。插件不再写在 spec 里,由记录的 provider 表达;本版本不定义操作。",
|
|
5
|
+
"spec": {
|
|
6
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"$defs": {
|
|
9
|
+
"level": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"id": {"type": "string", "minLength": 1, "maxLength": 200},
|
|
13
|
+
"name": {"type": "string", "maxLength": 200},
|
|
14
|
+
"shortName": {"type": "string", "maxLength": 40}
|
|
15
|
+
},
|
|
16
|
+
"required": ["id"],
|
|
17
|
+
"additionalProperties": false
|
|
18
|
+
},
|
|
19
|
+
"option": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"properties": {
|
|
22
|
+
"id": {"type": "string", "minLength": 1, "maxLength": 200},
|
|
23
|
+
"name": {"type": "string", "maxLength": 200},
|
|
24
|
+
"shortName": {"type": "string", "maxLength": 40},
|
|
25
|
+
"type": {"enum": ["boolean", "select"], "description": "开关,或几个选项里选一个"},
|
|
26
|
+
"choices": {"type": "array", "items": {"$ref": "#/$defs/level"}, "description": "能选的选项"}
|
|
27
|
+
},
|
|
28
|
+
"required": ["id", "type"],
|
|
29
|
+
"additionalProperties": false,
|
|
30
|
+
"if": {"properties": {"type": {"const": "select"}}, "required": ["type"]},
|
|
31
|
+
"then": {"required": ["choices"]},
|
|
32
|
+
"else": {"not": {"required": ["choices"]}}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"properties": {
|
|
36
|
+
"agent": {"type": "string", "minLength": 1, "maxLength": 200, "description": "Agent 的 ID:spawn 的 agent 写它"},
|
|
37
|
+
"title": {"type": "string", "maxLength": 200, "description": "给人看的名字"},
|
|
38
|
+
"defaultModel": {"type": "string", "maxLength": 200, "description": "不指定模型时用的模型 ID;读到目录前为空"},
|
|
39
|
+
"models": {
|
|
40
|
+
"type": "array",
|
|
41
|
+
"description": "它在那台能用的模型,最近读到的目录",
|
|
42
|
+
"items": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"properties": {
|
|
45
|
+
"id": {"type": "string", "minLength": 1, "maxLength": 200},
|
|
46
|
+
"name": {"type": "string", "maxLength": 200},
|
|
47
|
+
"shortName": {"type": "string", "maxLength": 40},
|
|
48
|
+
"group": {"type": "string", "maxLength": 200, "description": "来源:Agent 自带的没有,模型服务的是服务的标题"},
|
|
49
|
+
"efforts": {"type": "array", "items": {"$ref": "#/$defs/level"}},
|
|
50
|
+
"options": {"type": "array", "items": {"$ref": "#/$defs/option"}}
|
|
51
|
+
},
|
|
52
|
+
"required": ["id", "efforts", "options"],
|
|
53
|
+
"additionalProperties": false
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"modes": {"type": "array", "description": "它的审批模式", "items": {"$ref": "#/$defs/level"}}
|
|
57
|
+
},
|
|
58
|
+
"required": ["agent", "title", "defaultModel", "models", "modes"],
|
|
59
|
+
"additionalProperties": false
|
|
60
|
+
},
|
|
61
|
+
"status": {
|
|
62
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
63
|
+
"type": "object",
|
|
64
|
+
"maxProperties": 0,
|
|
65
|
+
"additionalProperties": false,
|
|
66
|
+
"description": "Agent 记录没有 status 字段"
|
|
67
|
+
},
|
|
68
|
+
"operations": {}
|
|
69
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://coda.pub/schemas/protocol/v1/definition.json",
|
|
4
|
+
"title": "协议定义",
|
|
5
|
+
"description": "一个协议的名字、记录格式与操作。名字是「命名空间/名字@大版本」;spec、status 与每个操作的输入、结果都是 JSON Schema(draft 2020-12),只引用定义自身的 $defs。操作要么立刻返回结果(result),要么返回运行引用(run: true);只读的立即结果可标 safe: true。",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"name": {"$ref": "#/$defs/name"},
|
|
9
|
+
"title": {"$ref": "#/$defs/title"},
|
|
10
|
+
"description": {"$ref": "#/$defs/description"},
|
|
11
|
+
"spec": {"$ref": "#/$defs/schema"},
|
|
12
|
+
"status": {"$ref": "#/$defs/schema"},
|
|
13
|
+
"operations": {
|
|
14
|
+
"description": "操作名 → 输入与输出;不定义操作的协议写空对象",
|
|
15
|
+
"type": "object",
|
|
16
|
+
"maxProperties": 50,
|
|
17
|
+
"propertyNames": {"$ref": "#/$defs/operationName"},
|
|
18
|
+
"additionalProperties": {"$ref": "#/$defs/operation"}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"required": ["name", "spec", "status", "operations"],
|
|
22
|
+
"additionalProperties": false,
|
|
23
|
+
"$defs": {
|
|
24
|
+
"name": {
|
|
25
|
+
"description": "命名空间以小写字母开头,名字以小写字母或数字开头,两者只用小写字母、数字和「-」,各不超过 40 个字符;大版本是正整数。短名(见文档)至多 63 个字符;每个「-」在短名里占两个字符,所以协议名本身至多 61 个字符,parseProtocolName 还会按实际短名再核一次。命名空间为 coda 的由 Coda 保留。",
|
|
26
|
+
"type": "string",
|
|
27
|
+
"maxLength": 61,
|
|
28
|
+
"pattern": "^[a-z][a-z0-9-]{0,39}/[a-z0-9][a-z0-9-]{0,39}@[1-9][0-9]*$"
|
|
29
|
+
},
|
|
30
|
+
"operationName": {
|
|
31
|
+
"description": "操作名:小写字母开头,只用小写字母、数字和「-」,不超过 64 个字符",
|
|
32
|
+
"type": "string",
|
|
33
|
+
"pattern": "^[a-z][a-z0-9-]{0,63}$"
|
|
34
|
+
},
|
|
35
|
+
"schema": {
|
|
36
|
+
"description": "JSON Schema(draft 2020-12)",
|
|
37
|
+
"type": ["object", "boolean"]
|
|
38
|
+
},
|
|
39
|
+
"title": {"description": "给人看的名字", "type": "string", "maxLength": 100, "pattern": "^(?=.*\\S)[^\\u0000\\r\\n]*$"},
|
|
40
|
+
"description": {"description": "一句话说明", "type": "string", "maxLength": 1000, "pattern": "^(?=.*\\S)[^\\u0000\\r\\n]*$"},
|
|
41
|
+
"operation": {
|
|
42
|
+
"description": "操作:input 必有;result 是立即结果的 schema,或写 run: true 表示返回运行引用。两者恰写一个。safe: true 只能与 result 一起写。",
|
|
43
|
+
"type": "object",
|
|
44
|
+
"properties": {
|
|
45
|
+
"description": {"$ref": "#/$defs/description"},
|
|
46
|
+
"input": {"$ref": "#/$defs/schema"},
|
|
47
|
+
"result": {"$ref": "#/$defs/schema"},
|
|
48
|
+
"run": {"const": true, "description": "返回运行引用,而不是立即结果"},
|
|
49
|
+
"safe": {"const": true, "description": "只读、没有副作用:调用双方都不按 requestId 留请求和回答,重发就再做一次"}
|
|
50
|
+
},
|
|
51
|
+
"required": ["input"],
|
|
52
|
+
"additionalProperties": false,
|
|
53
|
+
"oneOf": [{"required": ["result"]}, {"required": ["run"]}],
|
|
54
|
+
"dependentRequired": {"safe": ["result"]}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "coda/environment@1",
|
|
3
|
+
"title": "环境",
|
|
4
|
+
"description": "插件提供的外部环境,例如别家 Agent 自带的云主机。本版本只读:list 列目录,read 读文件;路径是 Provider 自己的命名空间。",
|
|
5
|
+
"spec": {
|
|
6
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"title": {"type": "string", "maxLength": 200, "description": "给人看的名字"},
|
|
10
|
+
"container": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"description": "Provider 给的容器",
|
|
13
|
+
"properties": {
|
|
14
|
+
"id": {"type": "string", "minLength": 1, "maxLength": 2048},
|
|
15
|
+
"title": {"type": "string", "maxLength": 200}
|
|
16
|
+
},
|
|
17
|
+
"required": ["id", "title"],
|
|
18
|
+
"additionalProperties": false
|
|
19
|
+
},
|
|
20
|
+
"actions": {
|
|
21
|
+
"type": "array",
|
|
22
|
+
"uniqueItems": true,
|
|
23
|
+
"items": {"enum": ["read", "checkout", "delete", "exec"]},
|
|
24
|
+
"description": "能做什么;本版本只认 read"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"required": ["title", "actions"],
|
|
28
|
+
"additionalProperties": false
|
|
29
|
+
},
|
|
30
|
+
"status": {
|
|
31
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
32
|
+
"type": "object",
|
|
33
|
+
"properties": {
|
|
34
|
+
"state": {"enum": ["available", "unreachable"]},
|
|
35
|
+
"reason": {"type": "string", "maxLength": 4096, "description": "状态说明,可选"}
|
|
36
|
+
},
|
|
37
|
+
"required": ["state"],
|
|
38
|
+
"additionalProperties": false
|
|
39
|
+
},
|
|
40
|
+
"operations": {
|
|
41
|
+
"list": {
|
|
42
|
+
"description": "列目录:path 为空字符串表示根,after 是上一页的 next;立即结果。",
|
|
43
|
+
"safe": true,
|
|
44
|
+
"input": {
|
|
45
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
46
|
+
"type": "object",
|
|
47
|
+
"properties": {
|
|
48
|
+
"path": {"type": "string", "maxLength": 4096},
|
|
49
|
+
"after": {"type": "string", "minLength": 1, "maxLength": 2048}
|
|
50
|
+
},
|
|
51
|
+
"required": ["path"],
|
|
52
|
+
"additionalProperties": false
|
|
53
|
+
},
|
|
54
|
+
"result": {
|
|
55
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
56
|
+
"type": "object",
|
|
57
|
+
"properties": {
|
|
58
|
+
"entries": {
|
|
59
|
+
"type": "array",
|
|
60
|
+
"items": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"properties": {
|
|
63
|
+
"name": {"type": "string", "minLength": 1, "maxLength": 1024},
|
|
64
|
+
"type": {"enum": ["file", "dir", "link"]},
|
|
65
|
+
"size": {"type": "integer", "minimum": 0}
|
|
66
|
+
},
|
|
67
|
+
"required": ["name", "type"],
|
|
68
|
+
"additionalProperties": false
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"next": {"oneOf": [{"type": "string", "minLength": 1, "maxLength": 2048}, {"type": "null"}], "description": "下一页从哪里接着列;没有了为 null"}
|
|
72
|
+
},
|
|
73
|
+
"required": ["entries", "next"],
|
|
74
|
+
"additionalProperties": false
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"read": {
|
|
78
|
+
"description": "读文件的一段:offset 默认 0,length 至多 1 MiB;立即结果。",
|
|
79
|
+
"safe": true,
|
|
80
|
+
"input": {
|
|
81
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
82
|
+
"type": "object",
|
|
83
|
+
"properties": {
|
|
84
|
+
"path": {"type": "string", "minLength": 1, "maxLength": 4096},
|
|
85
|
+
"offset": {"type": "integer", "minimum": 0},
|
|
86
|
+
"length": {"type": "integer", "minimum": 0, "maximum": 1048576}
|
|
87
|
+
},
|
|
88
|
+
"required": ["path"],
|
|
89
|
+
"additionalProperties": false
|
|
90
|
+
},
|
|
91
|
+
"result": {
|
|
92
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
93
|
+
"type": "object",
|
|
94
|
+
"properties": {
|
|
95
|
+
"path": {"type": "string", "minLength": 1, "maxLength": 4096},
|
|
96
|
+
"size": {"type": "integer", "minimum": 0, "description": "文件总字节数"},
|
|
97
|
+
"base64": {"type": "string", "pattern": "^[A-Za-z0-9+/]*={0,2}$", "description": "这一段的内容"},
|
|
98
|
+
"more": {"type": "boolean", "description": "这一段之后还有没有"}
|
|
99
|
+
},
|
|
100
|
+
"required": ["path", "size", "base64", "more"],
|
|
101
|
+
"additionalProperties": false
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "coda/executor@1",
|
|
3
|
+
"title": "执行器",
|
|
4
|
+
"description": "一台机器上执行脚本步骤的环境。execute 接下一份工作,返回执行器自己开出的 coda/run@1 运行引用;执行器不写调用方的记录,也没有 target 绑定。",
|
|
5
|
+
"spec": {
|
|
6
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"$defs": {
|
|
9
|
+
"resourceName": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"pattern": "^(?:slots|group:(?!host$(?![\\s\\S]))[^\\s\\u0000-\\u001f\\u007f]{1,100})$(?![\\s\\S])",
|
|
12
|
+
"description": "slots 对应 host;其他本机命名组用 group:<原名>,不将不同组折叠为 slots"
|
|
13
|
+
},
|
|
14
|
+
"resourceAmounts": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"propertyNames": {"$ref": "#/$defs/resourceName"},
|
|
17
|
+
"maxProperties": 128,
|
|
18
|
+
"additionalProperties": {"type": "integer", "minimum": 0, "maximum": 9007199254740991},
|
|
19
|
+
"description": "可报告多个独立资源的容量"
|
|
20
|
+
},
|
|
21
|
+
"userLabels": {
|
|
22
|
+
"type": "array",
|
|
23
|
+
"items": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"minLength": 1,
|
|
26
|
+
"maxLength": 40,
|
|
27
|
+
"pattern": "^[a-z0-9][a-z0-9._-]*$(?![\\s\\S])",
|
|
28
|
+
"not": {
|
|
29
|
+
"pattern": "^(darwin|linux|win32|aix|android|freebsd|openbsd|sunos|cygwin|netbsd|haiku|arm|arm64|ia32|x64|loong64|mips|mipsel|ppc|ppc64|riscv64|s390|s390x|gui)$|^(xcode|ios|node)-"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"maxItems": 64,
|
|
33
|
+
"uniqueItems": true,
|
|
34
|
+
"description": "用户自定义标签,不占用 OS、架构、gui 与 xcode-/ios-/node- 探测命名空间"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"properties": {
|
|
38
|
+
"enabled": {"type": "boolean"},
|
|
39
|
+
"capacity": {"$ref": "#/$defs/resourceAmounts"},
|
|
40
|
+
"labels": {"$ref": "#/$defs/userLabels"},
|
|
41
|
+
"title": {"type": "string", "minLength": 1, "maxLength": 200}
|
|
42
|
+
},
|
|
43
|
+
"required": ["enabled", "capacity", "labels"],
|
|
44
|
+
"additionalProperties": false,
|
|
45
|
+
"description": "执行器配置意图,由持有端维护"
|
|
46
|
+
},
|
|
47
|
+
"status": {
|
|
48
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
49
|
+
"type": "object",
|
|
50
|
+
"$defs": {
|
|
51
|
+
"resourceName": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"pattern": "^(?:slots|group:(?!host$(?![\\s\\S]))[^\\s\\u0000-\\u001f\\u007f]{1,100})$(?![\\s\\S])"
|
|
54
|
+
},
|
|
55
|
+
"resourceAmounts": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"propertyNames": {"$ref": "#/$defs/resourceName"},
|
|
58
|
+
"maxProperties": 128,
|
|
59
|
+
"additionalProperties": {"type": "integer", "minimum": 0, "maximum": 9007199254740991}
|
|
60
|
+
},
|
|
61
|
+
"labels": {
|
|
62
|
+
"type": "array",
|
|
63
|
+
"items": {"type": "string", "minLength": 1, "maxLength": 40, "pattern": "^[a-z0-9][a-z0-9._-]*$(?![\\s\\S])"},
|
|
64
|
+
"maxItems": 64,
|
|
65
|
+
"uniqueItems": true
|
|
66
|
+
},
|
|
67
|
+
"reason": {
|
|
68
|
+
"type": "object",
|
|
69
|
+
"properties": {
|
|
70
|
+
"code": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
71
|
+
"message": {"type": "string", "minLength": 1, "maxLength": 4096}
|
|
72
|
+
},
|
|
73
|
+
"required": ["code", "message"],
|
|
74
|
+
"additionalProperties": false
|
|
75
|
+
},
|
|
76
|
+
"timestamp": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"minLength": 1,
|
|
79
|
+
"maxLength": 40,
|
|
80
|
+
"pattern": "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])T([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d{1,9})?Z$(?![\\s\\S])"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"properties": {
|
|
84
|
+
"detectedLabels": {"$ref": "#/$defs/labels"},
|
|
85
|
+
"capabilities": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"properties": {
|
|
88
|
+
"os": {"type": "string", "minLength": 1, "maxLength": 40},
|
|
89
|
+
"arch": {"type": "string", "minLength": 1, "maxLength": 40},
|
|
90
|
+
"nodeVersion": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
91
|
+
"xcode": {
|
|
92
|
+
"type": "object",
|
|
93
|
+
"properties": {"version": {"type": "string", "minLength": 1, "maxLength": 128}, "build": {"type": "string", "minLength": 1, "maxLength": 128}},
|
|
94
|
+
"required": ["version", "build"],
|
|
95
|
+
"additionalProperties": false
|
|
96
|
+
},
|
|
97
|
+
"simulatorRuntimes": {
|
|
98
|
+
"type": "array",
|
|
99
|
+
"items": {
|
|
100
|
+
"type": "object",
|
|
101
|
+
"properties": {"id": {"type": "string", "minLength": 1, "maxLength": 256}, "version": {"type": "string", "minLength": 1, "maxLength": 128}, "available": {"type": "boolean"}},
|
|
102
|
+
"required": ["id", "version", "available"],
|
|
103
|
+
"additionalProperties": false
|
|
104
|
+
},
|
|
105
|
+
"maxItems": 256
|
|
106
|
+
},
|
|
107
|
+
"graphicalSession": {"type": ["boolean", "null"]}
|
|
108
|
+
},
|
|
109
|
+
"required": ["os", "arch", "nodeVersion", "graphicalSession"],
|
|
110
|
+
"additionalProperties": false
|
|
111
|
+
},
|
|
112
|
+
"capacity": {"$ref": "#/$defs/resourceAmounts"},
|
|
113
|
+
"occupied": {"$ref": "#/$defs/resourceAmounts"},
|
|
114
|
+
"available": {"$ref": "#/$defs/resourceAmounts"},
|
|
115
|
+
"accepting": {"type": "boolean"},
|
|
116
|
+
"reason": {"$ref": "#/$defs/reason"},
|
|
117
|
+
"observedAt": {"$ref": "#/$defs/timestamp"},
|
|
118
|
+
"observedRevision": {"type": "string", "minLength": 1, "maxLength": 2048},
|
|
119
|
+
"executionFeatures": {
|
|
120
|
+
"type": "object",
|
|
121
|
+
"properties": {
|
|
122
|
+
"multiResource": {"const": false},
|
|
123
|
+
"multiUnit": {"const": false},
|
|
124
|
+
"exclusive": {"type": "boolean"},
|
|
125
|
+
"noResources": {"type": "boolean"},
|
|
126
|
+
"namedResources": {"type": "boolean"},
|
|
127
|
+
"context": {"type": "boolean"}
|
|
128
|
+
},
|
|
129
|
+
"required": ["multiResource", "multiUnit", "exclusive"],
|
|
130
|
+
"additionalProperties": false
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
"required": [],
|
|
134
|
+
"additionalProperties": false,
|
|
135
|
+
"anyOf": [
|
|
136
|
+
{"maxProperties": 0},
|
|
137
|
+
{
|
|
138
|
+
"required": ["detectedLabels", "capabilities", "capacity", "occupied", "available", "accepting", "observedAt", "observedRevision", "executionFeatures"]
|
|
139
|
+
}
|
|
140
|
+
],
|
|
141
|
+
"description": "空对象表示未知;非空为持有端最近观察到的事实,不是在线或预留保证"
|
|
142
|
+
},
|
|
143
|
+
"operations": {
|
|
144
|
+
"execute": {
|
|
145
|
+
"description": "接下一份执行工作,返回执行器自己开出的运行引用。",
|
|
146
|
+
"input": {
|
|
147
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
148
|
+
"type": "object",
|
|
149
|
+
"$defs": {
|
|
150
|
+
"opaqueId": {"type": "string", "minLength": 1, "maxLength": 2048},
|
|
151
|
+
"resourceRef": {
|
|
152
|
+
"type": "object",
|
|
153
|
+
"properties": {"kind": {"type": "string", "minLength": 1, "maxLength": 128}, "id": {"$ref": "#/$defs/opaqueId"}},
|
|
154
|
+
"required": ["kind", "id"],
|
|
155
|
+
"additionalProperties": false
|
|
156
|
+
},
|
|
157
|
+
"snapshotRef": {
|
|
158
|
+
"type": "object",
|
|
159
|
+
"properties": {"kind": {"const": "git/snapshot@1"}, "id": {"$ref": "#/$defs/opaqueId"}},
|
|
160
|
+
"required": ["kind", "id"],
|
|
161
|
+
"additionalProperties": false
|
|
162
|
+
},
|
|
163
|
+
"repositoryRef": {
|
|
164
|
+
"type": "object",
|
|
165
|
+
"properties": {"kind": {"const": "git/source@1"}, "id": {"$ref": "#/$defs/opaqueId"}},
|
|
166
|
+
"required": ["kind", "id"],
|
|
167
|
+
"additionalProperties": false
|
|
168
|
+
},
|
|
169
|
+
"labels": {
|
|
170
|
+
"type": "array",
|
|
171
|
+
"items": {"type": "string", "minLength": 1, "maxLength": 40, "pattern": "^[a-z0-9][a-z0-9._-]*$(?![\\s\\S])"},
|
|
172
|
+
"maxItems": 64,
|
|
173
|
+
"uniqueItems": true
|
|
174
|
+
},
|
|
175
|
+
"resourceName": {
|
|
176
|
+
"type": "string",
|
|
177
|
+
"pattern": "^(?:slots|group:(?!host$(?![\\s\\S]))[^\\s\\u0000-\\u001f\\u007f]{1,100})$(?![\\s\\S])"
|
|
178
|
+
},
|
|
179
|
+
"workingDirectory": {
|
|
180
|
+
"type": "string",
|
|
181
|
+
"minLength": 1,
|
|
182
|
+
"maxLength": 4096,
|
|
183
|
+
"pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*[\\u0000-\\u001f\\u007f])(?!.*(?:^|/)\\.\\.(?:/|$)).+$",
|
|
184
|
+
"description": "工作根下的相对路径;拒绝绝对路径、反斜线和 .. 段,真实落点与符号链接仍须执行方检查"
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
"properties": {
|
|
188
|
+
"source": {
|
|
189
|
+
"oneOf": [
|
|
190
|
+
{"type": "null"},
|
|
191
|
+
{"type": "object", "properties": {"snapshot": {"$ref": "#/$defs/snapshotRef"}}, "required": ["snapshot"], "additionalProperties": false},
|
|
192
|
+
{
|
|
193
|
+
"type": "object",
|
|
194
|
+
"properties": {
|
|
195
|
+
"repository": {"$ref": "#/$defs/repositoryRef"},
|
|
196
|
+
"commit": {"type": "string", "minLength": 1, "maxLength": 64, "pattern": "^(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})$(?![\\s\\S])"}
|
|
197
|
+
},
|
|
198
|
+
"required": ["repository", "commit"],
|
|
199
|
+
"additionalProperties": false
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
"requirements": {
|
|
204
|
+
"type": "object",
|
|
205
|
+
"properties": {"labels": {"$ref": "#/$defs/labels"}},
|
|
206
|
+
"required": ["labels"],
|
|
207
|
+
"additionalProperties": false
|
|
208
|
+
},
|
|
209
|
+
"resources": {
|
|
210
|
+
"type": "object",
|
|
211
|
+
"propertyNames": {"$ref": "#/$defs/resourceName"},
|
|
212
|
+
"maxProperties": 1,
|
|
213
|
+
"additionalProperties": {"const": 1},
|
|
214
|
+
"description": "空对象表示不占资源;否则只申请一个资源的一单位"
|
|
215
|
+
},
|
|
216
|
+
"exclusiveResources": {
|
|
217
|
+
"type": "array",
|
|
218
|
+
"items": {"$ref": "#/$defs/resourceName"},
|
|
219
|
+
"maxItems": 1,
|
|
220
|
+
"uniqueItems": true,
|
|
221
|
+
"default": [],
|
|
222
|
+
"description": "空数组或独占申请的那一个资源,须与 resources 的键一致"
|
|
223
|
+
},
|
|
224
|
+
"context": {
|
|
225
|
+
"type": "object",
|
|
226
|
+
"properties": {
|
|
227
|
+
"workflow": {
|
|
228
|
+
"type": "object",
|
|
229
|
+
"properties": {
|
|
230
|
+
"name": {"type": "string", "minLength": 1, "maxLength": 256},
|
|
231
|
+
"job": {"type": "string", "minLength": 1, "maxLength": 256},
|
|
232
|
+
"runId": {"$ref": "#/$defs/opaqueId"},
|
|
233
|
+
"runAttempt": {"type": "integer", "minimum": 1, "maximum": 9007199254740991},
|
|
234
|
+
"sha": {"type": "string", "pattern": "^(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})?$(?![\\s\\S])"},
|
|
235
|
+
"ref": {"type": "string", "maxLength": 1024},
|
|
236
|
+
"repository": {"type": "string", "maxLength": 2048}
|
|
237
|
+
},
|
|
238
|
+
"required": ["name", "job", "runId", "runAttempt", "sha", "ref", "repository"],
|
|
239
|
+
"additionalProperties": false
|
|
240
|
+
},
|
|
241
|
+
"plugin": {
|
|
242
|
+
"type": "object",
|
|
243
|
+
"properties": {"id": {"type": "string", "pattern": "^[a-z][a-z0-9-]{0,39}$(?![\\s\\S])"}, "version": {"type": "string", "minLength": 1, "maxLength": 128}},
|
|
244
|
+
"required": ["id", "version"],
|
|
245
|
+
"additionalProperties": false
|
|
246
|
+
},
|
|
247
|
+
"audience": {"const": "user"},
|
|
248
|
+
"outputNames": {"type": "array", "maxItems": 64, "uniqueItems": true, "items": {"type": "string", "minLength": 1, "maxLength": 128}}
|
|
249
|
+
},
|
|
250
|
+
"additionalProperties": false,
|
|
251
|
+
"description": "可信生产者给出的运行上下文与输出声明;不是环境快照或授权凭证"
|
|
252
|
+
},
|
|
253
|
+
"task": {
|
|
254
|
+
"oneOf": [
|
|
255
|
+
{"type": "object", "properties": {"script": {"type": "string", "minLength": 1, "maxLength": 65536}, "shell": {"type": "string", "minLength": 1, "maxLength": 4096}}, "required": ["script", "shell"], "additionalProperties": false},
|
|
256
|
+
{"type": "object", "properties": {"command": {"type": "string", "minLength": 1, "maxLength": 4096}, "args": {"type": "array", "items": {"type": "string", "minLength": 0, "maxLength": 16384}, "maxItems": 256}}, "required": ["command", "args"], "additionalProperties": false}
|
|
257
|
+
]
|
|
258
|
+
},
|
|
259
|
+
"workingDirectory": {"$ref": "#/$defs/workingDirectory", "default": "."},
|
|
260
|
+
"env": {
|
|
261
|
+
"type": "object",
|
|
262
|
+
"propertyNames": {"pattern": "^[A-Za-z_][A-Za-z0-9_]{0,127}$(?![\\s\\S])"},
|
|
263
|
+
"maxProperties": 128,
|
|
264
|
+
"additionalProperties": {"type": "string", "minLength": 0, "maxLength": 16384}
|
|
265
|
+
},
|
|
266
|
+
"timeoutMs": {"type": "integer", "minimum": 1, "maximum": 9007199254740991},
|
|
267
|
+
"cancelGraceMs": {"type": "integer", "minimum": 0, "maximum": 9007199254740991}
|
|
268
|
+
},
|
|
269
|
+
"required": ["source", "requirements", "resources", "task", "env"],
|
|
270
|
+
"additionalProperties": false,
|
|
271
|
+
"allOf": [
|
|
272
|
+
{"if": {"properties": {"resources": {"maxProperties": 0}}}, "then": {"properties": {"exclusiveResources": {"maxItems": 0}}}}
|
|
273
|
+
],
|
|
274
|
+
"description": "一次执行工作的输入;取消走 coda/run@1 的 cancel 操作,不写在输入里"
|
|
275
|
+
},
|
|
276
|
+
"run": true
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://coda.pub/schemas/protocol/v1/request.json",
|
|
4
|
+
"title": "统一调用请求",
|
|
5
|
+
"description": "对一条记录的一次操作:记录引用、操作名、输入、请求 ID、发起方引用和是否被等待。同一个请求 ID 重发只做一次;被调用方建运行时照抄 parent 与 awaited。",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"$defs": {
|
|
8
|
+
"reference": {
|
|
9
|
+
"description": "记录引用:协议名(尚未定义成协议的资源暂用资源种类名)与不透明 ID",
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"kind": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
13
|
+
"id": {"type": "string", "minLength": 1, "maxLength": 2048}
|
|
14
|
+
},
|
|
15
|
+
"required": ["kind", "id"],
|
|
16
|
+
"additionalProperties": false
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"properties": {
|
|
20
|
+
"record": {"$ref": "#/$defs/reference"},
|
|
21
|
+
"operation": {"type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z][a-z0-9-]{0,63}$"},
|
|
22
|
+
"input": true,
|
|
23
|
+
"requestId": {"type": "string", "minLength": 1, "maxLength": 2048},
|
|
24
|
+
"parent": {"$ref": "#/$defs/reference", "description": "发起这次调用的一方:调用方的运行、会话或其他记录"},
|
|
25
|
+
"awaited": {"type": "boolean", "description": "调用方是否在等它"}
|
|
26
|
+
},
|
|
27
|
+
"required": ["record", "operation", "input", "requestId", "parent", "awaited"],
|
|
28
|
+
"additionalProperties": false
|
|
29
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://coda.pub/schemas/protocol/v1/response.json",
|
|
4
|
+
"title": "统一调用回答",
|
|
5
|
+
"description": "一次调用要么立刻返回结果,要么返回一个运行引用;两者恰有一个。运行引用指向被调用方自己的 coda/run@1 记录,调用方 watch 它取结果。",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"$defs": {
|
|
8
|
+
"reference": {
|
|
9
|
+
"description": "运行记录引用:类型名与不透明 ID",
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"kind": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
13
|
+
"id": {"type": "string", "minLength": 1, "maxLength": 2048}
|
|
14
|
+
},
|
|
15
|
+
"required": ["kind", "id"],
|
|
16
|
+
"additionalProperties": false
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"properties": {
|
|
20
|
+
"result": true,
|
|
21
|
+
"run": {"$ref": "#/$defs/reference"}
|
|
22
|
+
},
|
|
23
|
+
"additionalProperties": false,
|
|
24
|
+
"oneOf": [{"required": ["result"]}, {"required": ["run"]}]
|
|
25
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "coda/run@1",
|
|
3
|
+
"title": "运行",
|
|
4
|
+
"description": "被调用方为一次调用开出的运行记录,由被调用方持有和写入。调用方 watch 这条记录取结果;状态到 completed、failed、canceled 后不再改变。",
|
|
5
|
+
"spec": {
|
|
6
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"$defs": {
|
|
9
|
+
"reference": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"kind": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
13
|
+
"id": {"type": "string", "minLength": 1, "maxLength": 2048}
|
|
14
|
+
},
|
|
15
|
+
"required": ["kind", "id"],
|
|
16
|
+
"additionalProperties": false
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"properties": {
|
|
20
|
+
"record": {"$ref": "#/$defs/reference", "description": "调用的是哪条记录"},
|
|
21
|
+
"operation": {"type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z][a-z0-9-]{0,63}$", "description": "调用的操作名"},
|
|
22
|
+
"input": {"description": "原样保存的调用输入"},
|
|
23
|
+
"requestId": {"type": "string", "minLength": 1, "maxLength": 2048, "description": "调用方的请求 ID;重发只对应这条运行"},
|
|
24
|
+
"parent": {"$ref": "#/$defs/reference", "description": "谁让它存在:发起它的记录引用,必填"},
|
|
25
|
+
"awaited": {"type": "boolean", "description": "父是否在等它;不等时完成只追加消息,不叫醒父"}
|
|
26
|
+
},
|
|
27
|
+
"required": ["record", "operation", "input", "requestId", "parent", "awaited"],
|
|
28
|
+
"additionalProperties": false
|
|
29
|
+
},
|
|
30
|
+
"status": {
|
|
31
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
32
|
+
"type": "object",
|
|
33
|
+
"$defs": {
|
|
34
|
+
"reference": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"properties": {
|
|
37
|
+
"kind": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
38
|
+
"id": {"type": "string", "minLength": 1, "maxLength": 2048}
|
|
39
|
+
},
|
|
40
|
+
"required": ["kind", "id"],
|
|
41
|
+
"additionalProperties": false
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"properties": {
|
|
45
|
+
"state": {"enum": ["working", "input-required", "completed", "failed", "canceled"], "description": "后三个是终态"},
|
|
46
|
+
"result": {"description": "完成、失败或取消时的结果;失败时约定为 { code, message },code 为 unknown 表示结局不明"},
|
|
47
|
+
"progress": {"type": "string", "maxLength": 4096, "description": "进展说明,可选"},
|
|
48
|
+
"awaiting": {"$ref": "#/$defs/reference", "description": "等输入时那张卡片的引用"}
|
|
49
|
+
},
|
|
50
|
+
"required": ["state"],
|
|
51
|
+
"additionalProperties": false,
|
|
52
|
+
"allOf": [
|
|
53
|
+
{
|
|
54
|
+
"if": {"properties": {"state": {"enum": ["completed", "failed"]}}, "required": ["state"]},
|
|
55
|
+
"then": {"required": ["result"]}
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"if": {"properties": {"state": {"enum": ["working", "input-required"]}}, "required": ["state"]},
|
|
59
|
+
"then": {"not": {"required": ["result"]}}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"if": {"properties": {"state": {"const": "input-required"}}, "required": ["state"]},
|
|
63
|
+
"then": {"required": ["awaiting"]},
|
|
64
|
+
"else": {"not": {"required": ["awaiting"]}}
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"operations": {
|
|
69
|
+
"cancel": {
|
|
70
|
+
"description": "请求取消;立即回答空结果,实际是否停止看状态。",
|
|
71
|
+
"input": {"$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "maxProperties": 0, "additionalProperties": false},
|
|
72
|
+
"result": {"$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "maxProperties": 0, "additionalProperties": false}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|