@chorus-protocol/skill 0.4.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/LICENSE +190 -0
- package/README.md +55 -0
- package/cli.mjs +75 -0
- package/package.json +36 -0
- package/templates/en/PROTOCOL.md +76 -0
- package/templates/en/SKILL.md +94 -0
- package/templates/shared/TRANSPORT.md +364 -0
- package/templates/shared/envelope.schema.json +47 -0
- package/templates/shared/examples/en-to-en.json +17 -0
- package/templates/shared/examples/ja-to-zh-CN.json +18 -0
- package/templates/shared/examples/zh-CN-to-ja.json +18 -0
- package/templates/zh-CN/PROTOCOL.zh-CN.md +76 -0
- package/templates/zh-CN/SKILL.zh-CN.md +93 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to the Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by the Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding any notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
Copyright 2026 Chorus Protocol Contributors
|
|
179
|
+
|
|
180
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
181
|
+
you may not use this file except in compliance with the License.
|
|
182
|
+
You may obtain a copy of the License at
|
|
183
|
+
|
|
184
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
185
|
+
|
|
186
|
+
Unless required by applicable law or agreed to in writing, software
|
|
187
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
188
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
189
|
+
See the License for the specific language governing permissions and
|
|
190
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Chorus Protocol — Skill Package
|
|
2
|
+
|
|
3
|
+
Chorus is an agent-to-agent communication protocol. An agent loads `SKILL.md` and learns how to send and receive messages across platforms, languages, and cultures.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### 1. Load the Skill
|
|
8
|
+
|
|
9
|
+
Add `SKILL.md` to your agent's skill/prompt configuration. The agent reads it and learns the Chorus protocol.
|
|
10
|
+
|
|
11
|
+
### 2. Send a message
|
|
12
|
+
|
|
13
|
+
Your agent packages a Chorus envelope:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"chorus_version": "0.4",
|
|
18
|
+
"sender_id": "my-agent@chorus.example",
|
|
19
|
+
"original_text": "Let's sync on the project timeline.",
|
|
20
|
+
"sender_culture": "en"
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
And delivers it through a Chorus server or directly to the receiver.
|
|
25
|
+
|
|
26
|
+
### 3. Receive and adapt
|
|
27
|
+
|
|
28
|
+
When a message arrives from another agent, your agent validates the envelope, adapts the message for its human (translating language and bridging cultural context as needed), and responds with `{"status": "ok"}`.
|
|
29
|
+
|
|
30
|
+
## Connecting to a Server
|
|
31
|
+
|
|
32
|
+
To connect via a Chorus server (see `TRANSPORT.md`):
|
|
33
|
+
|
|
34
|
+
1. **Register** — announce your agent ID, receive endpoint, and capabilities (`card_version: "0.3"`, culture, languages)
|
|
35
|
+
2. **Discover** — query the server for other registered agents
|
|
36
|
+
3. **Send** — post your envelope with the receiver's address
|
|
37
|
+
|
|
38
|
+
Agents can also exchange envelopes directly (P2P) without a server.
|
|
39
|
+
|
|
40
|
+
## Files
|
|
41
|
+
|
|
42
|
+
| File | Content |
|
|
43
|
+
|------|---------|
|
|
44
|
+
| `SKILL.md` | Agent learning document — teaches the Chorus protocol |
|
|
45
|
+
| `PROTOCOL.md` | Formal protocol specification (v0.4) |
|
|
46
|
+
| `TRANSPORT.md` | HTTP binding — register, send, receive, discover |
|
|
47
|
+
| `envelope.schema.json` | Envelope v0.4 JSON Schema |
|
|
48
|
+
| `examples/` | Sample envelopes (en↔en, zh-CN↔ja, ja↔zh-CN) |
|
|
49
|
+
|
|
50
|
+
## Design Principles
|
|
51
|
+
|
|
52
|
+
- **Transport-agnostic**: the envelope can travel over any channel
|
|
53
|
+
- **Model-agnostic**: any LLM that handles multilingual text works
|
|
54
|
+
- **No personality in the protocol**: how your agent speaks is its own business
|
|
55
|
+
- **Pre-1.0**: backwards compatibility is not guaranteed until 1.0
|
package/cli.mjs
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync, mkdirSync, writeFileSync, existsSync, cpSync } from "fs";
|
|
4
|
+
import { join, dirname } from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, "package.json"), "utf8"));
|
|
9
|
+
|
|
10
|
+
const LANGS = ["en", "zh-CN"];
|
|
11
|
+
const DEFAULT_LANG = "en";
|
|
12
|
+
|
|
13
|
+
const args = process.argv.slice(2);
|
|
14
|
+
const command = args[0];
|
|
15
|
+
|
|
16
|
+
if (command === "init") {
|
|
17
|
+
const langFlag = args.indexOf("--lang");
|
|
18
|
+
const lang = langFlag !== -1 && args[langFlag + 1] ? args[langFlag + 1] : DEFAULT_LANG;
|
|
19
|
+
|
|
20
|
+
if (!LANGS.includes(lang)) {
|
|
21
|
+
console.error(`Unsupported language: ${lang}. Available: ${LANGS.join(", ")}`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const targetDir = join(process.cwd(), "chorus");
|
|
26
|
+
|
|
27
|
+
if (existsSync(targetDir)) {
|
|
28
|
+
console.error(`Directory "chorus/" already exists. Remove it first or choose a different location.`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
mkdirSync(targetDir, { recursive: true });
|
|
33
|
+
mkdirSync(join(targetDir, "examples"), { recursive: true });
|
|
34
|
+
|
|
35
|
+
const templateDir = join(__dirname, "templates", lang);
|
|
36
|
+
const sharedDir = join(__dirname, "templates", "shared");
|
|
37
|
+
|
|
38
|
+
const protocolFile = lang === "en" ? "PROTOCOL.md" : `PROTOCOL.${lang}.md`;
|
|
39
|
+
const skillFile = lang === "en" ? "SKILL.md" : `SKILL.${lang}.md`;
|
|
40
|
+
|
|
41
|
+
writeFileSync(
|
|
42
|
+
join(targetDir, "PROTOCOL.md"),
|
|
43
|
+
readFileSync(join(templateDir, protocolFile))
|
|
44
|
+
);
|
|
45
|
+
writeFileSync(
|
|
46
|
+
join(targetDir, "SKILL.md"),
|
|
47
|
+
readFileSync(join(templateDir, skillFile))
|
|
48
|
+
);
|
|
49
|
+
writeFileSync(
|
|
50
|
+
join(targetDir, "TRANSPORT.md"),
|
|
51
|
+
readFileSync(join(sharedDir, "TRANSPORT.md"))
|
|
52
|
+
);
|
|
53
|
+
writeFileSync(
|
|
54
|
+
join(targetDir, "envelope.schema.json"),
|
|
55
|
+
readFileSync(join(sharedDir, "envelope.schema.json"))
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
cpSync(join(sharedDir, "examples"), join(targetDir, "examples"), { recursive: true });
|
|
59
|
+
|
|
60
|
+
console.log(`Chorus Skill package initialized in ./chorus/ (${lang})`);
|
|
61
|
+
console.log(`\nFiles created:`);
|
|
62
|
+
console.log(` chorus/PROTOCOL.md — Protocol specification`);
|
|
63
|
+
console.log(` chorus/SKILL.md — Agent learning document`);
|
|
64
|
+
console.log(` chorus/TRANSPORT.md — Default transport profile (optional)`);
|
|
65
|
+
console.log(` chorus/envelope.schema.json`);
|
|
66
|
+
console.log(` chorus/examples/`);
|
|
67
|
+
console.log(`\nGive your agent chorus/SKILL.md to teach it the Chorus protocol.`);
|
|
68
|
+
} else {
|
|
69
|
+
console.log(`@chorus-protocol/skill v${pkg.version}`);
|
|
70
|
+
console.log(`\nUsage:`);
|
|
71
|
+
console.log(` chorus-skill init [--lang en|zh-CN] Initialize Chorus Skill package`);
|
|
72
|
+
console.log(`\nExamples:`);
|
|
73
|
+
console.log(` npx @chorus-protocol/skill init`);
|
|
74
|
+
console.log(` npx @chorus-protocol/skill init --lang zh-CN`);
|
|
75
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@chorus-protocol/skill",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Chorus Protocol — Link agents across platforms. Install the Chorus Skill package for your agent.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"chorus-skill": "./cli.mjs"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"license": "Apache-2.0",
|
|
10
|
+
"files": [
|
|
11
|
+
"cli.mjs",
|
|
12
|
+
"templates",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=16"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/owensun6/chorus.git",
|
|
22
|
+
"directory": "packages/chorus-skill"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://github.com/owensun6/chorus/tree/main/packages/chorus-skill",
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/owensun6/chorus/issues"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"chorus",
|
|
30
|
+
"protocol",
|
|
31
|
+
"agent",
|
|
32
|
+
"a2a",
|
|
33
|
+
"cross-cultural",
|
|
34
|
+
"communication"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Chorus Protocol
|
|
2
|
+
|
|
3
|
+
Version 0.4 | Link agents across platforms.
|
|
4
|
+
|
|
5
|
+
The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119.
|
|
6
|
+
|
|
7
|
+
## 1. What is Chorus
|
|
8
|
+
|
|
9
|
+
Chorus is an agent-to-agent communication standard that links agents across platforms, languages, and cultures.
|
|
10
|
+
|
|
11
|
+
## 2. The Envelope
|
|
12
|
+
|
|
13
|
+
A JSON object:
|
|
14
|
+
|
|
15
|
+
- chorus_version (string, MUST): "0.4"
|
|
16
|
+
- sender_id (string, MUST): Sender address, format `name@host`
|
|
17
|
+
- original_text (string, MUST): The original message
|
|
18
|
+
- sender_culture (string, MUST): BCP 47 tag
|
|
19
|
+
- cultural_context (string 10-500, MAY): Optional hint — why the sender said it this way, in sender's language. Most receivers can adapt without it
|
|
20
|
+
- conversation_id (string max 64, MAY): Multi-turn identifier
|
|
21
|
+
- turn_number (integer ≥ 1, MAY): Turn counter
|
|
22
|
+
|
|
23
|
+
`sender_id` format: `name@host`. `host` is the Chorus server domain or peer address. Uniqueness is guaranteed by the host's namespace.
|
|
24
|
+
|
|
25
|
+
Additional fields permitted. Formal schema: `envelope.schema.json`
|
|
26
|
+
|
|
27
|
+
## 3. Rules
|
|
28
|
+
|
|
29
|
+
### Sending
|
|
30
|
+
|
|
31
|
+
1. MAY include `cultural_context` as a hint to the receiver when sender and receiver cultures differ
|
|
32
|
+
2. MUST NOT include personality or style in `cultural_context`
|
|
33
|
+
|
|
34
|
+
### Receiving
|
|
35
|
+
|
|
36
|
+
1. MUST validate the envelope before processing. If invalid, MUST respond with an error
|
|
37
|
+
2. MUST deliver the message in a form the receiver can understand
|
|
38
|
+
3. MAY deliver without adaptation when culture and language are the same
|
|
39
|
+
|
|
40
|
+
### Response
|
|
41
|
+
|
|
42
|
+
A JSON object returned to the sender:
|
|
43
|
+
|
|
44
|
+
- status (string, MUST): "ok" or "error"
|
|
45
|
+
- error_code (string, when error): See below
|
|
46
|
+
- detail (string, MAY): Human-readable description
|
|
47
|
+
|
|
48
|
+
Error codes:
|
|
49
|
+
|
|
50
|
+
- `INVALID_ENVELOPE` — Required fields missing or wrong type
|
|
51
|
+
- `UNSUPPORTED_VERSION` — `chorus_version` not recognized
|
|
52
|
+
- `ADAPTATION_FAILED` — Receiver could not process the message
|
|
53
|
+
|
|
54
|
+
Transport-level errors (delivery failure, timeout, unknown sender) are defined by L3.
|
|
55
|
+
|
|
56
|
+
### Constraints
|
|
57
|
+
|
|
58
|
+
- MUST NOT include personality or style in the envelope
|
|
59
|
+
- When present, `cultural_context` MUST be in the sender's language
|
|
60
|
+
|
|
61
|
+
## 4. Not In Scope
|
|
62
|
+
|
|
63
|
+
- Transport: how envelopes travel between agents
|
|
64
|
+
- Discovery: how agents initially find each other's addresses
|
|
65
|
+
- Authentication: how agents verify identity
|
|
66
|
+
- Personality: how an agent speaks
|
|
67
|
+
- Storage: how history is persisted
|
|
68
|
+
|
|
69
|
+
## 5. Versioning
|
|
70
|
+
|
|
71
|
+
0.4 is not backwards compatible with 0.2/0.3. Breaking changes from 0.2/0.3:
|
|
72
|
+
|
|
73
|
+
- `original_semantic` renamed to `original_text`
|
|
74
|
+
- `cultural_context` changed from conditional to optional (MAY)
|
|
75
|
+
|
|
76
|
+
Legacy envelopes using `original_semantic` or `chorus_version` values below `"0.4"` are not accepted. Senders MUST upgrade to 0.4 envelope format. There is no migration bridge — this is a pre-1.0 protocol and backwards compatibility is not guaranteed until 1.0.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: chorus
|
|
3
|
+
description: |
|
|
4
|
+
Agent-to-agent communication protocol. Use when sending messages to
|
|
5
|
+
or receiving messages from agents on other platforms. Handles
|
|
6
|
+
cross-platform delivery, language translation, and cultural adaptation.
|
|
7
|
+
version: "0.4"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Chorus
|
|
11
|
+
|
|
12
|
+
You now know the Chorus protocol. You can communicate with any agent on any platform.
|
|
13
|
+
|
|
14
|
+
## What is Chorus
|
|
15
|
+
|
|
16
|
+
Chorus is how agents talk to each other. Your human talks to you. The other human talks to their agent. Chorus links you and that agent — regardless of platform, language, or culture.
|
|
17
|
+
|
|
18
|
+
Same culture, same language: you are a cross-platform bridge. Just deliver the message.
|
|
19
|
+
Different language or culture: you also adapt the message so the receiving human understands it naturally.
|
|
20
|
+
|
|
21
|
+
## Your Role
|
|
22
|
+
|
|
23
|
+
You are a Chorus protocol participant. Your job is to package and understand Chorus envelopes. How to connect with other agents is covered in "How to Connect" below.
|
|
24
|
+
|
|
25
|
+
You may represent your human, or you may act autonomously. Either way, when you communicate with another agent, you use Chorus envelopes.
|
|
26
|
+
|
|
27
|
+
## Sending
|
|
28
|
+
|
|
29
|
+
When you have a message to send to another agent — whether your human asked you to send it, or you are acting on your own:
|
|
30
|
+
|
|
31
|
+
1. **Package the envelope**:
|
|
32
|
+
- `chorus_version`: `"0.4"`
|
|
33
|
+
- `sender_id`: your address (`name@host`)
|
|
34
|
+
- `original_text`: the message. If your human said it, use their exact words. If you are acting autonomously, this is your own message.
|
|
35
|
+
- `sender_culture`: your human's culture (BCP 47 tag, e.g. `en`, `zh-CN`, `ja`). When acting autonomously, use the culture you represent.
|
|
36
|
+
|
|
37
|
+
2. **Optionally add cultural context**: You may include `cultural_context` — a hint in your language about why the message is phrased this way. This is optional; most receivers can adapt without it.
|
|
38
|
+
|
|
39
|
+
3. **For multi-turn conversations**: Include `conversation_id` (any string up to 64 characters — generate one on the first turn, reuse it for all subsequent turns) and `turn_number` (starting at 1, incrementing each turn). These help the receiver maintain context across messages.
|
|
40
|
+
|
|
41
|
+
4. **Send the envelope**: Specify the receiver's address (`receiver_id`, same `name@host` format as your `sender_id`) and deliver the envelope through your connection. The `receiver_id` is part of the transport request, not the envelope itself — the envelope only carries who sent it, not who it's for.
|
|
42
|
+
|
|
43
|
+
## Receiving
|
|
44
|
+
|
|
45
|
+
When you receive a Chorus envelope:
|
|
46
|
+
|
|
47
|
+
1. **Validate it**. Check that `chorus_version`, `sender_id`, `original_text`, and `sender_culture` are present. If anything is missing, respond with `INVALID_ENVELOPE`.
|
|
48
|
+
|
|
49
|
+
2. **Deliver the message**:
|
|
50
|
+
- Same language and culture as your human: deliver `original_text` directly.
|
|
51
|
+
- Different language or culture: deliver the message in a form your human can understand. You are an intelligent agent — you know how to bridge languages and cultures. If `cultural_context` is present, use it to understand why the sender said it that way.
|
|
52
|
+
|
|
53
|
+
3. **Respond to the sender**: Always send back a response so the sender knows their message was received.
|
|
54
|
+
- Success: `{"status": "ok"}`
|
|
55
|
+
- Failure: `{"status": "error", "error_code": "INVALID_ENVELOPE", "detail": "missing sender_culture"}`
|
|
56
|
+
|
|
57
|
+
## How to Connect
|
|
58
|
+
|
|
59
|
+
To communicate with another agent, you need a connection. Chorus does not mandate how — use whatever works. Here are two common options, both described in detail in `TRANSPORT.md`.
|
|
60
|
+
|
|
61
|
+
### Chorus Server
|
|
62
|
+
|
|
63
|
+
A shared relay that maintains a directory of agents.
|
|
64
|
+
|
|
65
|
+
1. **Register**: announce yourself to the server — your `agent_id` (`name@host`), your receive endpoint (you must start an HTTP server on a free port to accept inbound messages — check the port is not already in use before binding), and your `agent_card` with `card_version: "0.3"`, `user_culture`, and `supported_languages`. See TRANSPORT.md Quick Start for the exact request format.
|
|
66
|
+
2. **Discover**: query the server to find other registered agents and learn their cultures.
|
|
67
|
+
3. **Send**: post the envelope with the `receiver_id` to the server. The server relays it to the receiver.
|
|
68
|
+
|
|
69
|
+
This is like email: you send to the server, the server delivers to the recipient. Anyone can run a Chorus server.
|
|
70
|
+
|
|
71
|
+
### P2P Direct
|
|
72
|
+
|
|
73
|
+
If you and the other agent can reach each other directly (e.g. you both know each other's endpoint or peer address), exchange envelopes without a server. Your humans share your addresses or endpoints and you connect.
|
|
74
|
+
|
|
75
|
+
### Knowing the receiver's culture
|
|
76
|
+
|
|
77
|
+
When sending cross-culturally, knowing the receiver's culture helps you decide how to phrase your message. You can learn it through:
|
|
78
|
+
|
|
79
|
+
- **Discovery**: the server's agent directory includes each agent's `user_culture`
|
|
80
|
+
- **Prior conversation**: if you've received a message from them, their `sender_culture` tells you
|
|
81
|
+
- **Out of band**: your human tells you
|
|
82
|
+
|
|
83
|
+
## DO NOT
|
|
84
|
+
|
|
85
|
+
- Do not put your personality or speaking style in the envelope. How you talk is your business, not the protocol's.
|
|
86
|
+
- Do not forward a foreign-language message to your human without adaptation. Even a simple agent MUST deliver messages in a form the human can understand.
|
|
87
|
+
- Do not invent or guess `cultural_context`. If you do not understand the cultural nuance, omit it — the receiver can adapt without it.
|
|
88
|
+
|
|
89
|
+
## Reference
|
|
90
|
+
|
|
91
|
+
Full protocol specification: `PROTOCOL.md`
|
|
92
|
+
Default transport profile: `TRANSPORT.md`
|
|
93
|
+
Formal JSON Schema: `envelope.schema.json`
|
|
94
|
+
Examples: `examples/`
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
# Chorus Transport Profile
|
|
2
|
+
|
|
3
|
+
Version 0.4 | Default L3 binding for Chorus envelope delivery.
|
|
4
|
+
|
|
5
|
+
The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119.
|
|
6
|
+
|
|
7
|
+
## 1. Scope
|
|
8
|
+
|
|
9
|
+
This document defines one way to deliver Chorus envelopes between agents. It is an optional L3 profile — not part of the core protocol.
|
|
10
|
+
|
|
11
|
+
Chorus Protocol (L1) defines the envelope format. Chorus Skill (L2) teaches agents how to use it. This transport profile provides a default HTTP binding so that agents can interoperate without building custom transport.
|
|
12
|
+
|
|
13
|
+
Agents MAY use any transport that delivers valid Chorus envelopes. Compliance with this profile is not required for Chorus compliance.
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
A complete register → send → receive flow using the HTTP binding:
|
|
18
|
+
|
|
19
|
+
**Step 1 — Register your agent**
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
POST /agents
|
|
23
|
+
|
|
24
|
+
{
|
|
25
|
+
"agent_id": "my-agent@chorus.example",
|
|
26
|
+
"endpoint": "https://my-agent.example/receive",
|
|
27
|
+
"agent_card": {
|
|
28
|
+
"card_version": "0.3",
|
|
29
|
+
"user_culture": "en",
|
|
30
|
+
"supported_languages": ["en"]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Response: `201` with `{ "success": true, "data": { "agent_id": "...", "registered_at": "..." } }`
|
|
36
|
+
|
|
37
|
+
**Step 2 — Send a message**
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
POST /messages
|
|
41
|
+
|
|
42
|
+
{
|
|
43
|
+
"receiver_id": "other-agent@chorus.example",
|
|
44
|
+
"envelope": {
|
|
45
|
+
"chorus_version": "0.4",
|
|
46
|
+
"sender_id": "my-agent@chorus.example",
|
|
47
|
+
"original_text": "Hello, let's collaborate on this project.",
|
|
48
|
+
"sender_culture": "en"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Response: `200` with `{ "success": true, "data": { "delivery": "delivered", "receiver_response": { "status": "ok" } } }`
|
|
54
|
+
|
|
55
|
+
**Step 3 — Receive a message**
|
|
56
|
+
|
|
57
|
+
Your endpoint receives:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
POST https://my-agent.example/receive
|
|
61
|
+
|
|
62
|
+
{
|
|
63
|
+
"envelope": {
|
|
64
|
+
"chorus_version": "0.4",
|
|
65
|
+
"sender_id": "other-agent@chorus.example",
|
|
66
|
+
"original_text": "こんにちは、プロジェクトについて相談しましょう。",
|
|
67
|
+
"sender_culture": "ja"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Your endpoint responds: `{"status": "ok"}`
|
|
73
|
+
|
|
74
|
+
That's it. You are now sending and receiving Chorus envelopes.
|
|
75
|
+
|
|
76
|
+
**Important: envelope nesting.** The Chorus envelope is always wrapped inside a JSON object — never sent as the top-level body. When sending: `{ "receiver_id": "...", "envelope": { ...chorus fields... } }`. When receiving: `{ "envelope": { ...chorus fields... } }`. The envelope fields (`chorus_version`, `sender_id`, `original_text`, `sender_culture`) go inside the `"envelope"` key, not at the root of the request body.
|
|
77
|
+
|
|
78
|
+
## 2. Addressing
|
|
79
|
+
|
|
80
|
+
An agent address follows the format `name@host`.
|
|
81
|
+
|
|
82
|
+
- `name`: identifier, unique within the host's namespace
|
|
83
|
+
- `host`: the Chorus server domain or peer address
|
|
84
|
+
|
|
85
|
+
The same format applies to both `sender_id` (defined in PROTOCOL.md) and `receiver_id` (used in transport requests).
|
|
86
|
+
|
|
87
|
+
Within a single server, implementations SHOULD accept the short form `name` as a local alias for `name@{server-host}`.
|
|
88
|
+
|
|
89
|
+
## 3. Connection Modes
|
|
90
|
+
|
|
91
|
+
### Server Relay
|
|
92
|
+
|
|
93
|
+
Agents register with a shared Chorus server. The server maintains a directory and relays envelopes between them.
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
Agent A ──envelope──▶ Chorus Server ──envelope──▶ Agent B
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### P2P Direct
|
|
100
|
+
|
|
101
|
+
Two agents exchange envelopes directly when they know each other's endpoints.
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
Agent A ──envelope──▶ Agent B
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
No registration or server required. The agents' humans share addresses out of band.
|
|
108
|
+
|
|
109
|
+
## 4. Operations
|
|
110
|
+
|
|
111
|
+
Four abstract operations, independent of transport binding. Section 6 maps these to HTTP.
|
|
112
|
+
|
|
113
|
+
### 4.1 Register
|
|
114
|
+
|
|
115
|
+
An agent announces itself to a server.
|
|
116
|
+
|
|
117
|
+
Request:
|
|
118
|
+
- `agent_id` (string, MUST): the agent's `name@host` address
|
|
119
|
+
- `endpoint` (string, MUST): URL where the agent receives envelopes
|
|
120
|
+
- `agent_card` (object, SHOULD): agent capabilities — `card_version` (agent card schema version, currently `"0.3"`), `user_culture` (BCP 47), `supported_languages` (BCP 47 array)
|
|
121
|
+
|
|
122
|
+
Note: the agent card field is `card_version` (not `chorus_version`). The envelope has its own `chorus_version` field (`"0.4"`). They are different fields versioning different things.
|
|
123
|
+
|
|
124
|
+
**Migration from card v0.2**: In v0.2, the agent card field was named `chorus_version` (same name as the envelope field). This caused confusion, so v0.3 renames it to `card_version`. Agents using the old `chorus_version` field in their agent card MUST update to `card_version: "0.3"`. Servers MAY return a generic validation error if the old field name is used.
|
|
125
|
+
|
|
126
|
+
Result: registration record with `registered_at` timestamp.
|
|
127
|
+
|
|
128
|
+
Re-registering an existing `agent_id` updates the record.
|
|
129
|
+
|
|
130
|
+
### 4.2 Unregister
|
|
131
|
+
|
|
132
|
+
An agent removes itself from a server.
|
|
133
|
+
|
|
134
|
+
Request:
|
|
135
|
+
- `agent_id` (string, MUST)
|
|
136
|
+
|
|
137
|
+
Result: confirmation. No-op if already absent.
|
|
138
|
+
|
|
139
|
+
### 4.3 Discover
|
|
140
|
+
|
|
141
|
+
Query registered agents.
|
|
142
|
+
|
|
143
|
+
Request: none required. MAY support filters.
|
|
144
|
+
|
|
145
|
+
Result: list of registration records.
|
|
146
|
+
|
|
147
|
+
### 4.4 Send
|
|
148
|
+
|
|
149
|
+
Deliver a Chorus envelope to another agent.
|
|
150
|
+
|
|
151
|
+
Request:
|
|
152
|
+
- `receiver_id` (string, MUST): receiver's `name@host` address
|
|
153
|
+
- `envelope` (object, MUST): a valid Chorus envelope per PROTOCOL.md
|
|
154
|
+
|
|
155
|
+
The sender's identity is `envelope.sender_id`. There is no separate sender field — a single source of truth avoids mismatch.
|
|
156
|
+
|
|
157
|
+
Result: delivery outcome (see Section 5).
|
|
158
|
+
|
|
159
|
+
## 5. Delivery States
|
|
160
|
+
|
|
161
|
+
A Send request produces one of three outcomes:
|
|
162
|
+
|
|
163
|
+
| State | Meaning |
|
|
164
|
+
|-------|---------|
|
|
165
|
+
| `delivered` | Envelope reached the receiver. The response includes the receiver's protocol-level reply (per PROTOCOL.md Section 3) |
|
|
166
|
+
| `failed` | Delivery failed. The response includes an error code and detail |
|
|
167
|
+
| `rejected` | Sender validation failed (not registered, invalid envelope). No delivery attempted |
|
|
168
|
+
|
|
169
|
+
### Retry
|
|
170
|
+
|
|
171
|
+
- Senders MAY retry on transient failures (`ERR_AGENT_UNREACHABLE`, `ERR_TIMEOUT`)
|
|
172
|
+
- Senders MUST NOT retry on permanent failures (`ERR_AGENT_NOT_FOUND`, `ERR_VALIDATION`)
|
|
173
|
+
- Senders SHOULD use exponential backoff when retrying
|
|
174
|
+
- Receivers SHOULD treat duplicate envelopes with the same `conversation_id` + `turn_number` as idempotent
|
|
175
|
+
|
|
176
|
+
## 6. HTTP Binding
|
|
177
|
+
|
|
178
|
+
The default transport binding. A conforming server implements these endpoints.
|
|
179
|
+
|
|
180
|
+
### 6.1 Endpoints
|
|
181
|
+
|
|
182
|
+
| Operation | Method | Path | Success |
|
|
183
|
+
|-----------|--------|------|---------|
|
|
184
|
+
| Register | POST | `/agents` | 201 (new) / 200 (update) |
|
|
185
|
+
| Unregister | DELETE | `/agents/:id` | 200 |
|
|
186
|
+
| Discover (list) | GET | `/agents` | 200 |
|
|
187
|
+
| Discover (single) | GET | `/agents/:id` | 200 |
|
|
188
|
+
| Send | POST | `/messages` | 200 |
|
|
189
|
+
| Health | GET | `/health` | 200 |
|
|
190
|
+
|
|
191
|
+
### 6.2 Response Envelope
|
|
192
|
+
|
|
193
|
+
All HTTP responses use a common format:
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"success": true,
|
|
198
|
+
"data": { },
|
|
199
|
+
"metadata": { "timestamp": "2026-03-20T10:00:00.000Z" }
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
```json
|
|
204
|
+
{
|
|
205
|
+
"success": false,
|
|
206
|
+
"error": { "code": "ERR_VALIDATION", "message": "sender_id is required" },
|
|
207
|
+
"metadata": { "timestamp": "2026-03-20T10:00:00.000Z" }
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### 6.3 Register
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
POST /agents
|
|
215
|
+
|
|
216
|
+
{
|
|
217
|
+
"agent_id": "alice@chorus.example",
|
|
218
|
+
"endpoint": "https://alice.example/receive",
|
|
219
|
+
"agent_card": {
|
|
220
|
+
"card_version": "0.3",
|
|
221
|
+
"user_culture": "zh-CN",
|
|
222
|
+
"supported_languages": ["zh-CN", "en"]
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### 6.4 Send
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
POST /messages
|
|
231
|
+
|
|
232
|
+
{
|
|
233
|
+
"receiver_id": "bob@chorus.example",
|
|
234
|
+
"envelope": {
|
|
235
|
+
"chorus_version": "0.4",
|
|
236
|
+
"sender_id": "alice@chorus.example",
|
|
237
|
+
"original_text": "下午一起喝杯咖啡?",
|
|
238
|
+
"sender_culture": "zh-CN",
|
|
239
|
+
"cultural_context": "中国同事之间用「喝咖啡」作为非正式交流的邀请,表达善意和亲近,不一定真的要喝咖啡"
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Delivered:
|
|
245
|
+
|
|
246
|
+
```json
|
|
247
|
+
{
|
|
248
|
+
"success": true,
|
|
249
|
+
"data": {
|
|
250
|
+
"delivery": "delivered",
|
|
251
|
+
"receiver_response": { "status": "ok" }
|
|
252
|
+
},
|
|
253
|
+
"metadata": { "timestamp": "..." }
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Failed:
|
|
258
|
+
|
|
259
|
+
```json
|
|
260
|
+
{
|
|
261
|
+
"success": true,
|
|
262
|
+
"data": {
|
|
263
|
+
"delivery": "failed",
|
|
264
|
+
"error_code": "ERR_AGENT_UNREACHABLE",
|
|
265
|
+
"detail": "Receiver did not respond within timeout"
|
|
266
|
+
},
|
|
267
|
+
"metadata": { "timestamp": "..." }
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Note: a delivery failure is not an HTTP error. The HTTP request succeeded; the delivery did not. Hence `"success": true` with `"delivery": "failed"`.
|
|
272
|
+
|
|
273
|
+
### 6.5 Agent Receive Endpoint
|
|
274
|
+
|
|
275
|
+
An agent that accepts envelopes MUST expose an HTTP endpoint. The URL is declared during Register.
|
|
276
|
+
|
|
277
|
+
Request (from server or direct peer):
|
|
278
|
+
|
|
279
|
+
```
|
|
280
|
+
POST {agent_endpoint}
|
|
281
|
+
|
|
282
|
+
{
|
|
283
|
+
"envelope": {
|
|
284
|
+
"chorus_version": "0.4",
|
|
285
|
+
"sender_id": "alice@chorus.example",
|
|
286
|
+
"original_text": "下午一起喝杯咖啡?",
|
|
287
|
+
"sender_culture": "zh-CN"
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Response — per PROTOCOL.md Section 3:
|
|
293
|
+
|
|
294
|
+
```json
|
|
295
|
+
{ "status": "ok" }
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
```json
|
|
299
|
+
{ "status": "error", "error_code": "INVALID_ENVELOPE", "detail": "missing sender_culture" }
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## 7. Transport Error Codes
|
|
303
|
+
|
|
304
|
+
These are distinct from protocol-level error codes in PROTOCOL.md.
|
|
305
|
+
|
|
306
|
+
| Code | HTTP Status | Meaning | Retryable |
|
|
307
|
+
|------|------------|---------|-----------|
|
|
308
|
+
| `ERR_VALIDATION` | 400 | Request body failed validation | No |
|
|
309
|
+
| `ERR_AGENT_NOT_FOUND` | 404 | Receiver not registered | No |
|
|
310
|
+
| `ERR_AGENT_UNREACHABLE` | 502 | Could not reach receiver endpoint | Yes |
|
|
311
|
+
| `ERR_TIMEOUT` | 504 | Receiver did not respond in time | Yes |
|
|
312
|
+
| `ERR_UNAUTHORIZED` | 401 | Authentication required or invalid | No |
|
|
313
|
+
| `ERR_SENDER_NOT_REGISTERED` | 400 | Sender not registered with this server | No |
|
|
314
|
+
|
|
315
|
+
## 8. Discovery
|
|
316
|
+
|
|
317
|
+
A Chorus server SHOULD serve a discovery document at:
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
GET /.well-known/chorus.json
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
```json
|
|
324
|
+
{
|
|
325
|
+
"chorus_version": "0.4",
|
|
326
|
+
"server_name": "Example Chorus Hub",
|
|
327
|
+
"endpoints": {
|
|
328
|
+
"register": "/agents",
|
|
329
|
+
"discover": "/agents",
|
|
330
|
+
"send": "/messages",
|
|
331
|
+
"health": "/health"
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Clients that support discovery SHOULD fetch this document to resolve endpoint paths rather than hardcoding them.
|
|
337
|
+
|
|
338
|
+
## 9. Extensions
|
|
339
|
+
|
|
340
|
+
### A2A Message Wrapping (MAY)
|
|
341
|
+
|
|
342
|
+
Implementations MAY encode the Chorus envelope as a DataPart inside an A2A message, using mediaType `application/vnd.chorus.envelope+json`. This enables interoperability with A2A-compatible platforms.
|
|
343
|
+
|
|
344
|
+
A2A wrapping is an alternate encoding of the `envelope` field, not a change to the Send request structure. The request still contains `receiver_id` + `envelope`. The server or receiver detects the encoding and extracts the Chorus envelope for protocol processing.
|
|
345
|
+
|
|
346
|
+
### SSE Streaming (MAY)
|
|
347
|
+
|
|
348
|
+
Implementations MAY support Server-Sent Events to stream the receiver's processing output back to the sender. This is a content stream extension, not a streaming version of the delivery states in Section 5.
|
|
349
|
+
|
|
350
|
+
When supported:
|
|
351
|
+
|
|
352
|
+
- The Send request includes `"stream": true`
|
|
353
|
+
- The server relays the receiver's SSE stream to the sender
|
|
354
|
+
- Events: `chunk` (incremental content from receiver), `done` (processing complete, includes full result), `error` (receiver processing failed)
|
|
355
|
+
|
|
356
|
+
The delivery state for a streamed request is determined by the final event: `done` maps to `delivered`, `error` maps to `failed`.
|
|
357
|
+
|
|
358
|
+
## 10. Not In Scope
|
|
359
|
+
|
|
360
|
+
- Authentication schemes — use whatever your deployment requires
|
|
361
|
+
- Rate limiting — server-specific policy
|
|
362
|
+
- Federation between Chorus servers — future work
|
|
363
|
+
- Envelope encryption — future work
|
|
364
|
+
- Message persistence or history — implementation concern
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://chorus-protocol.org/schemas/envelope/v0.4",
|
|
4
|
+
"title": "Chorus Envelope",
|
|
5
|
+
"description": "Chorus Protocol v0.4 — Agent-to-agent communication envelope",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["chorus_version", "sender_id", "original_text", "sender_culture"],
|
|
8
|
+
"additionalProperties": true,
|
|
9
|
+
"properties": {
|
|
10
|
+
"chorus_version": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"enum": ["0.4"],
|
|
13
|
+
"description": "Protocol version"
|
|
14
|
+
},
|
|
15
|
+
"sender_id": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"pattern": "^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+$",
|
|
18
|
+
"description": "Sender address (name@host)"
|
|
19
|
+
},
|
|
20
|
+
"original_text": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"minLength": 1,
|
|
23
|
+
"description": "The original message"
|
|
24
|
+
},
|
|
25
|
+
"sender_culture": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"pattern": "^[a-z]{2,3}(-[A-Z][a-z]{3})?(-[A-Z]{2}|-[0-9]{3})?$",
|
|
28
|
+
"description": "Sender culture (BCP 47 tag)"
|
|
29
|
+
},
|
|
30
|
+
"cultural_context": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"minLength": 10,
|
|
33
|
+
"maxLength": 500,
|
|
34
|
+
"description": "Optional hint — cultural background in sender's language. Most receivers can adapt without it"
|
|
35
|
+
},
|
|
36
|
+
"conversation_id": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"maxLength": 64,
|
|
39
|
+
"description": "Multi-turn conversation identifier"
|
|
40
|
+
},
|
|
41
|
+
"turn_number": {
|
|
42
|
+
"type": "integer",
|
|
43
|
+
"minimum": 1,
|
|
44
|
+
"description": "Turn counter"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_description": "Same-culture communication — Chorus as cross-platform interop",
|
|
3
|
+
|
|
4
|
+
"user_input": "Hey, can we push the deployment to tomorrow? The CI pipeline is still red.",
|
|
5
|
+
|
|
6
|
+
"envelope": {
|
|
7
|
+
"chorus_version": "0.4",
|
|
8
|
+
"sender_id": "alice@chorus.example.com",
|
|
9
|
+
"original_text": "Hey, can we push the deployment to tomorrow? The CI pipeline is still red.",
|
|
10
|
+
"sender_culture": "en"
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
"adapted_output": {
|
|
14
|
+
"receiver_culture": "en",
|
|
15
|
+
"text": "Hey, can we push the deployment to tomorrow? The CI pipeline is still red."
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_description": "日本人委婉拒绝提议 → 中国文化适配",
|
|
3
|
+
|
|
4
|
+
"user_input": "ちょっと難しいかもしれませんね。もう少し検討させていただけますか。",
|
|
5
|
+
|
|
6
|
+
"envelope": {
|
|
7
|
+
"chorus_version": "0.4",
|
|
8
|
+
"sender_id": "tanaka@chorus.example.jp",
|
|
9
|
+
"original_text": "ちょっと難しいかもしれませんね。もう少し検討させていただけますか。",
|
|
10
|
+
"sender_culture": "ja",
|
|
11
|
+
"cultural_context": "日本のビジネス文化において、「ちょっと難しいかもしれません」は直接的な拒否を避けるための婉曲表現です。「もう少し検討させていただけますか」は表面上は検討の余地を残す表現ですが、実質的にはお断りの意味を含むことが多いです。日本では相手の面子を傷つけないよう、このような間接的な表現が礼儀とされています。"
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
"adapted_output": {
|
|
15
|
+
"receiver_culture": "zh-CN",
|
|
16
|
+
"text": "对方其实是在委婉地拒绝这个提议。在日本商务文化里,'可能有点困难'加上'能否再考虑一下',基本上就是在说'这个方案恐怕不行'。他们习惯用这种间接的方式表达,是为了给双方都留面子。建议你可以换个方案再试试。"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_description": "中国人向日本同事表达感谢 → 日本文化适配",
|
|
3
|
+
|
|
4
|
+
"user_input": "辛苦了,这个项目多亏了你,真的非常感谢!",
|
|
5
|
+
|
|
6
|
+
"envelope": {
|
|
7
|
+
"chorus_version": "0.4",
|
|
8
|
+
"sender_id": "wang@chorus.example.cn",
|
|
9
|
+
"original_text": "辛苦了,这个项目多亏了你,真的非常感谢!",
|
|
10
|
+
"sender_culture": "zh-CN",
|
|
11
|
+
"cultural_context": "在中国职场文化中,'辛苦了'是对同事辛勤付出的认可和慰劳,表达的是'我看到了你的努力'。'多亏了你'是直接归功于对方的贡献,语气真诚而非客套。这种直接表达感谢在中国同事间是常见且受欢迎的。"
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
"adapted_output": {
|
|
15
|
+
"receiver_culture": "ja",
|
|
16
|
+
"text": "プロジェクトでのご尽力に心から感謝しています。中国の同僚から、あなたの貢献があったからこそ成功したと、とても率直に感謝が伝えられています。中国では、こうした直接的な感謝表現は、本心からの敬意を込めたものです。"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Chorus 协议
|
|
2
|
+
|
|
3
|
+
版本 0.4 | 连接跨平台的智能体。
|
|
4
|
+
|
|
5
|
+
本文档中的关键词 "MUST"(必须)、"MUST NOT"(禁止)、"SHOULD"(应当)和 "MAY"(可以)的含义遵循 RFC 2119 的定义。
|
|
6
|
+
|
|
7
|
+
## 1. Chorus 是什么
|
|
8
|
+
|
|
9
|
+
Chorus 是一种智能体间通信标准,用于连接跨平台、跨语言、跨文化的智能体。
|
|
10
|
+
|
|
11
|
+
## 2. 信封
|
|
12
|
+
|
|
13
|
+
一个 JSON 对象:
|
|
14
|
+
|
|
15
|
+
- chorus_version(字符串,MUST):"0.4"
|
|
16
|
+
- sender_id(字符串,MUST):发送方地址,格式为 `name@host`
|
|
17
|
+
- original_text(字符串,MUST):原始消息
|
|
18
|
+
- sender_culture(字符串,MUST):BCP 47 标签
|
|
19
|
+
- cultural_context(字符串 10-500,MAY):可选提示——发送方为何这样表达,使用发送方的语言书写。多数接收方可在没有它的情况下完成适配
|
|
20
|
+
- conversation_id(字符串,最大 64,MAY):多轮对话标识符
|
|
21
|
+
- turn_number(整数 ≥ 1,MAY):轮次计数器
|
|
22
|
+
|
|
23
|
+
`sender_id` 格式:`name@host`。`host` 是 Chorus 服务器域名或对端地址。唯一性由主机的命名空间保证。
|
|
24
|
+
|
|
25
|
+
允许附加字段。正式 schema 见:`envelope.schema.json`
|
|
26
|
+
|
|
27
|
+
## 3. 规则
|
|
28
|
+
|
|
29
|
+
### 发送
|
|
30
|
+
|
|
31
|
+
1. 当发送方和接收方文化不同时,MAY 包含 `cultural_context` 作为给接收方的提示
|
|
32
|
+
2. MUST NOT 在 `cultural_context` 中包含人格或风格信息
|
|
33
|
+
|
|
34
|
+
### 接收
|
|
35
|
+
|
|
36
|
+
1. MUST 在处理前验证信封。如果无效,MUST 返回错误
|
|
37
|
+
2. MUST 以接收方能够理解的形式投递消息
|
|
38
|
+
3. 当文化和语言相同时,MAY 不做适配直接投递
|
|
39
|
+
|
|
40
|
+
### 响应
|
|
41
|
+
|
|
42
|
+
返回给发送方的 JSON 对象:
|
|
43
|
+
|
|
44
|
+
- status(字符串,MUST):"ok" 或 "error"
|
|
45
|
+
- error_code(字符串,出错时):见下文
|
|
46
|
+
- detail(字符串,MAY):人类可读的描述
|
|
47
|
+
|
|
48
|
+
错误码:
|
|
49
|
+
|
|
50
|
+
- `INVALID_ENVELOPE` — 必填字段缺失或类型错误
|
|
51
|
+
- `UNSUPPORTED_VERSION` — `chorus_version` 无法识别
|
|
52
|
+
- `ADAPTATION_FAILED` — 接收方无法处理该消息
|
|
53
|
+
|
|
54
|
+
传输层错误(投递失败、超时、未知发送方)由 L3 定义。
|
|
55
|
+
|
|
56
|
+
### 约束
|
|
57
|
+
|
|
58
|
+
- MUST NOT 在信封中包含人格或风格信息
|
|
59
|
+
- 当包含 `cultural_context` 时,MUST 使用发送方的语言书写
|
|
60
|
+
|
|
61
|
+
## 4. 不在范围内
|
|
62
|
+
|
|
63
|
+
- 传输:信封如何在智能体之间传递
|
|
64
|
+
- 发现:智能体如何获取彼此的地址
|
|
65
|
+
- 认证:智能体如何验证身份
|
|
66
|
+
- 人格:智能体如何说话
|
|
67
|
+
- 存储:历史记录如何持久化
|
|
68
|
+
|
|
69
|
+
## 5. 版本控制
|
|
70
|
+
|
|
71
|
+
0.4 与 0.2/0.3 不向后兼容。从 0.2/0.3 开始的破坏性变更:
|
|
72
|
+
|
|
73
|
+
- `original_semantic` 重命名为 `original_text`
|
|
74
|
+
- `cultural_context` 从条件必填改为可选(MAY)
|
|
75
|
+
|
|
76
|
+
使用 `original_semantic` 或低于 `"0.4"` 的 `chorus_version` 值的旧版信封不被接受。发送方 MUST 升级到 0.4 信封格式。不提供迁移桥接——这是 1.0 之前的协议,在 1.0 之前不保证向后兼容。
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: chorus
|
|
3
|
+
description: |
|
|
4
|
+
Agent 间通信协议。当你需要向其他平台的 Agent 发送消息或接收来自
|
|
5
|
+
其他平台 Agent 的消息时使用。处理跨平台投递、语言翻译和文化适配。
|
|
6
|
+
version: "0.4"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Chorus
|
|
10
|
+
|
|
11
|
+
你现在掌握了 Chorus 协议。你可以和任何平台上的任何 Agent 通信。
|
|
12
|
+
|
|
13
|
+
## Chorus 是什么
|
|
14
|
+
|
|
15
|
+
Chorus 是 Agent 之间对话的方式。你的人类跟你说话,对方的人类跟他们的 Agent 说话。Chorus 把你和那个 Agent 连起来——不管平台、语言还是文化差异。
|
|
16
|
+
|
|
17
|
+
同文化、同语言:你就是一座跨平台的桥。把消息递过去就行。
|
|
18
|
+
不同语言或文化:你还需要对消息做适配,让接收方的人类能自然地理解它。
|
|
19
|
+
|
|
20
|
+
## 你的角色
|
|
21
|
+
|
|
22
|
+
你是 Chorus 协议的参与者。你的工作是打包和理解 Chorus 信封。如何与其他 Agent 建立连接,见下方「怎么连接」。
|
|
23
|
+
|
|
24
|
+
你可以代表你的人类,也可以自主行动。不管哪种情况,当你和另一个 Agent 通信时,你使用 Chorus 信封。
|
|
25
|
+
|
|
26
|
+
## 发送
|
|
27
|
+
|
|
28
|
+
当你有消息要发给另一个 Agent——不管是你的人类让你发的,还是你自主行动发的:
|
|
29
|
+
|
|
30
|
+
1. **打包信封**:
|
|
31
|
+
- `chorus_version`:`"0.4"`
|
|
32
|
+
- `sender_id`:你的地址(`name@host`)
|
|
33
|
+
- `original_text`:消息内容。如果是人类说的,用原话一字不改。如果是你自主行动,这就是你自己的消息。
|
|
34
|
+
- `sender_culture`:你的人类所属的文化(BCP 47 标签,比如 `en`、`zh-CN`、`ja`)。自主行动时,使用你所代表的文化。
|
|
35
|
+
|
|
36
|
+
2. **可选添加文化语境**:你可以包含 `cultural_context`——用你的语言解释消息为何这样措辞。这是可选的;多数接收方可以在没有它的情况下完成适配。
|
|
37
|
+
|
|
38
|
+
3. **多轮对话**:加上 `conversation_id`(任意字符串,最多 64 个字符——首轮时生成一个,后续轮次复用)和 `turn_number`(从 1 开始,每轮递增)。这帮助接收方在多条消息间保持上下文。
|
|
39
|
+
|
|
40
|
+
4. **发送信封**:指定接收方的地址(`receiver_id`,与你的 `sender_id` 格式相同,都是 `name@host`),通过你的连接投递信封。`receiver_id` 是传输请求的一部分,不在信封内——信封只携带发送者信息,不携带收件人信息。
|
|
41
|
+
|
|
42
|
+
## 接收
|
|
43
|
+
|
|
44
|
+
当你收到一个 Chorus 信封时:
|
|
45
|
+
|
|
46
|
+
1. **验证信封**。检查 `chorus_version`、`sender_id`、`original_text` 和 `sender_culture` 是否存在。如有缺失,回复 `INVALID_ENVELOPE`。
|
|
47
|
+
|
|
48
|
+
2. **投递消息**:
|
|
49
|
+
- 与你的人类语言和文化相同:直接投递 `original_text`。
|
|
50
|
+
- 语言或文化不同:把消息转化成你的人类能理解的形式。你是一个有智慧的 Agent——你知道怎么跨越语言和文化。如果信封里有 `cultural_context`,用它来理解发送者为什么会那样说。
|
|
51
|
+
|
|
52
|
+
3. **回复发送方**:始终回复一个响应,让发送方知道消息已收到。
|
|
53
|
+
- 成功:`{"status": "ok"}`
|
|
54
|
+
- 失败:`{"status": "error", "error_code": "INVALID_ENVELOPE", "detail": "缺少 sender_culture"}`
|
|
55
|
+
|
|
56
|
+
## 怎么连接
|
|
57
|
+
|
|
58
|
+
要和另一个 Agent 通信,你需要一个连接。Chorus 不强制要求特定方式——能用就行。以下是两种常见方式,详见 `TRANSPORT.md`。
|
|
59
|
+
|
|
60
|
+
### Chorus 服务器
|
|
61
|
+
|
|
62
|
+
一个维护 Agent 目录的共享中继。
|
|
63
|
+
|
|
64
|
+
1. **注册**:向服务器宣告你自己——你的 `agent_id`(`name@host`)、接收端点(你需要在一个空闲端口上启动 HTTP 服务来接收消息——绑定前先确认端口未被占用)、以及 `agent_card`,包含 `card_version: "0.3"`、`user_culture`、`supported_languages`。具体请求格式见 TRANSPORT.md Quick Start。
|
|
65
|
+
2. **发现**:查询服务器,找到其他已注册的 Agent,了解它们的文化。
|
|
66
|
+
3. **发送**:把信封和 `receiver_id` 一起发给服务器。服务器转发给接收方。
|
|
67
|
+
|
|
68
|
+
就像电子邮件:你发给服务器,服务器投递给收件人。任何人都可以运行 Chorus 服务器。
|
|
69
|
+
|
|
70
|
+
### P2P 直连
|
|
71
|
+
|
|
72
|
+
如果你和对方 Agent 能直接互相访问(比如你们都知道对方的端点或对端地址),不需要服务器,直接交换信封就行。你们的人类互相分享地址或端点,然后你们就连上了。
|
|
73
|
+
|
|
74
|
+
### 了解接收方的文化
|
|
75
|
+
|
|
76
|
+
在跨文化发送时,了解接收方的文化有助于你决定如何措辞消息。你可以通过以下方式了解:
|
|
77
|
+
|
|
78
|
+
- **发现机制**:服务器的 Agent 目录包含每个 Agent 的 `user_culture`
|
|
79
|
+
- **先前对话**:如果你收到过对方的消息,对方的 `sender_culture` 就告诉了你
|
|
80
|
+
- **带外方式**:你的人类告诉你
|
|
81
|
+
|
|
82
|
+
## 不要做的事
|
|
83
|
+
|
|
84
|
+
- 不要把你的个性或说话风格塞进信封里。你怎么说话是你自己的事,不是协议的事。
|
|
85
|
+
- 不要把外语消息原封不动地转给你的人类。哪怕是最简单的 Agent,也 MUST 把消息转成人类能理解的形式。
|
|
86
|
+
- 不要编造或猜测 `cultural_context`。如果你不理解其中的文化差异,就省掉它——接收方可以在没有它的情况下做适配。
|
|
87
|
+
|
|
88
|
+
## 参考
|
|
89
|
+
|
|
90
|
+
完整协议规范:`PROTOCOL.md`
|
|
91
|
+
默认传输方案:`TRANSPORT.md`
|
|
92
|
+
正式 JSON Schema:`envelope.schema.json`
|
|
93
|
+
示例:`examples/`
|