@agentunion/fastaun-browser 0.5.4 → 0.5.8

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.
Files changed (184) hide show
  1. package/CHANGELOG.md +177 -67
  2. package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/216/245/345/205/245/344/270/216/346/274/224/347/244/272/346/214/207/345/215/227.md +290 -0
  3. package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/234/215/345/212/241/346/236/266/346/236/204/344/270/216/350/257/246/347/273/206/345/256/236/347/216/260/350/256/241/345/210/222-codex.md +994 -0
  4. package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/234/215/345/212/241/350/277/220/347/273/264/344/270/216/345/217/221/345/270/203/346/214/207/345/215/227.md +144 -0
  5. package/_packed_docs/CHANGELOG.md +177 -67
  6. package/_packed_docs/INDEX.md +124 -65
  7. package/_packed_docs/KITE_DOCS_GUIDE.md +65 -30
  8. package/_packed_docs/agent.md/SCHEMA.md +83 -58
  9. package/_packed_docs/agent.md/examples/codeagent-claudecode.md +1 -1
  10. package/_packed_docs/agent.md/examples/openclaw-lobster.md +1 -1
  11. package/_packed_docs/agent.md/examples/signed-openclaw-lobster.md +1 -1
  12. package/_packed_docs/audit/AUN/346/234/215/345/212/241Go/345/214/226/351/207/215/346/236/204/347/262/276/347/273/206/345/214/226/346/272/220/347/240/201/345/256/241/346/237/245-20260718.md +366 -0
  13. package/_packed_docs/aun/345/205/254/347/275/221/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +234 -0
  14. package/_packed_docs/aun/345/210/206/345/270/203/345/274/217/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +1095 -0
  15. package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +1199 -0
  16. package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +6 -4
  17. package/_packed_docs/group-message-rpc-alignment-gaps.md +741 -0
  18. package/_packed_docs/message-online-push-alignment.md +572 -0
  19. package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +58 -20
  20. package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +219 -247
  21. package/_packed_docs/protocol/12-Stream-/345/255/220/345/215/217/350/256/256.md +14 -14
  22. package/_packed_docs/protocol/13-Agent/350/241/214/344/270/272/350/247/204/350/214/203.md +3 -3
  23. package/_packed_docs/protocol/15-/347/246/273/347/272/277/346/216/250/351/200/201/351/200/232/347/237/245/345/215/217/350/256/256.md +165 -421
  24. package/_packed_docs/protocol/README.md +1 -0
  25. package/_packed_docs/protocol/aun-docs-guide.md +7 -4
  26. package/_packed_docs/protocol/index.md +25 -19
  27. package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +63 -18
  28. package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +22 -0
  29. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +93 -84
  30. package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +6 -2
  31. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +73 -34
  32. package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +3 -3
  33. package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +21 -9
  34. package/_packed_docs/sdk/09-group-rpc-manual.md +319 -285
  35. package/_packed_docs/sdk/09-message-rpc-manual.md +144 -103
  36. package/_packed_docs/sdk/09-payload-reference.md +1 -1
  37. package/_packed_docs/sdk/09-storage-rpc-manual.md +14 -3
  38. package/_packed_docs/sdk/09-stream-rpc-manual.md +8 -8
  39. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +34 -23
  40. package/_packed_docs/sdk/CHANGELOG-0.5.6.md +73 -0
  41. package/_packed_docs/sdk/INDEX.md +45 -37
  42. package/_packed_docs/sdk/README.md +11 -9
  43. package/_packed_docs//345/217/221/345/270/203/346/212/245/345/221/212-0.5.6.md +260 -0
  44. package/_packed_docs//346/266/210/346/201/257/345/220/214/346/255/245/344/270/216/345/216/206/345/217/262/346/213/211/345/217/226/344/273/243/347/240/201/345/256/241/346/237/245/351/227/256/351/242/230/346/270/205/345/215/225.md +229 -0
  45. package/_packed_docs//346/266/210/346/201/257/345/220/214/346/255/245/344/270/216/345/216/206/345/217/262/346/213/211/345/217/226/346/224/271/351/200/240/346/226/271/346/241/210.md +750 -0
  46. package/dist/agent-md-schema.d.ts +14 -0
  47. package/dist/agent-md-schema.d.ts.map +1 -0
  48. package/dist/agent-md-schema.js +103 -0
  49. package/dist/agent-md-schema.js.map +1 -0
  50. package/dist/agent-md.d.ts +11 -5
  51. package/dist/agent-md.d.ts.map +1 -1
  52. package/dist/agent-md.js +295 -53
  53. package/dist/agent-md.js.map +1 -1
  54. package/dist/aid-store.d.ts +7 -7
  55. package/dist/aid-store.d.ts.map +1 -1
  56. package/dist/aid-store.js +46 -18
  57. package/dist/aid-store.js.map +1 -1
  58. package/dist/aid.d.ts +2 -0
  59. package/dist/aid.d.ts.map +1 -1
  60. package/dist/aid.js +29 -7
  61. package/dist/aid.js.map +1 -1
  62. package/dist/auth.d.ts.map +1 -1
  63. package/dist/auth.js +31 -11
  64. package/dist/auth.js.map +1 -1
  65. package/dist/bundle.js +29920 -19719
  66. package/dist/cert-utils.d.ts +1 -0
  67. package/dist/cert-utils.d.ts.map +1 -1
  68. package/dist/cert-utils.js +36 -16
  69. package/dist/cert-utils.js.map +1 -1
  70. package/dist/client/delivery.d.ts +106 -11
  71. package/dist/client/delivery.d.ts.map +1 -1
  72. package/dist/client/delivery.js +1925 -374
  73. package/dist/client/delivery.js.map +1 -1
  74. package/dist/client/group-state.d.ts.map +1 -1
  75. package/dist/client/group-state.js +27 -24
  76. package/dist/client/group-state.js.map +1 -1
  77. package/dist/client/lifecycle.d.ts +15 -1
  78. package/dist/client/lifecycle.d.ts.map +1 -1
  79. package/dist/client/lifecycle.js +477 -132
  80. package/dist/client/lifecycle.js.map +1 -1
  81. package/dist/client/mention-mode.d.ts +7 -0
  82. package/dist/client/mention-mode.d.ts.map +1 -0
  83. package/dist/client/mention-mode.js +184 -0
  84. package/dist/client/mention-mode.js.map +1 -0
  85. package/dist/client/peers.d.ts +1 -1
  86. package/dist/client/peers.d.ts.map +1 -1
  87. package/dist/client/peers.js +26 -3
  88. package/dist/client/peers.js.map +1 -1
  89. package/dist/client/rpc-pipeline.d.ts +34 -2
  90. package/dist/client/rpc-pipeline.d.ts.map +1 -1
  91. package/dist/client/rpc-pipeline.js +503 -99
  92. package/dist/client/rpc-pipeline.js.map +1 -1
  93. package/dist/client/runtime.d.ts +1 -3
  94. package/dist/client/runtime.d.ts.map +1 -1
  95. package/dist/client/runtime.js +4 -7
  96. package/dist/client/runtime.js.map +1 -1
  97. package/dist/client/v2-e2ee.d.ts +43 -2
  98. package/dist/client/v2-e2ee.d.ts.map +1 -1
  99. package/dist/client/v2-e2ee.js +931 -138
  100. package/dist/client/v2-e2ee.js.map +1 -1
  101. package/dist/client.d.ts +46 -15
  102. package/dist/client.d.ts.map +1 -1
  103. package/dist/client.js +785 -304
  104. package/dist/client.js.map +1 -1
  105. package/dist/errors.d.ts.map +1 -1
  106. package/dist/errors.js +4 -1
  107. package/dist/errors.js.map +1 -1
  108. package/dist/facades.d.ts +26 -1
  109. package/dist/facades.d.ts.map +1 -1
  110. package/dist/facades.js +142 -60
  111. package/dist/facades.js.map +1 -1
  112. package/dist/group-id.d.ts.map +1 -1
  113. package/dist/group-id.js +2 -17
  114. package/dist/group-id.js.map +1 -1
  115. package/dist/group-index.d.ts +6 -1
  116. package/dist/group-index.d.ts.map +1 -1
  117. package/dist/group-index.js +44 -25
  118. package/dist/group-index.js.map +1 -1
  119. package/dist/index.d.ts +5 -4
  120. package/dist/index.d.ts.map +1 -1
  121. package/dist/index.js +3 -2
  122. package/dist/index.js.map +1 -1
  123. package/dist/keystore/index.d.ts +10 -5
  124. package/dist/keystore/index.d.ts.map +1 -1
  125. package/dist/keystore/indexeddb-identity-store.d.ts +0 -12
  126. package/dist/keystore/indexeddb-identity-store.d.ts.map +1 -1
  127. package/dist/keystore/indexeddb-identity-store.js +0 -60
  128. package/dist/keystore/indexeddb-identity-store.js.map +1 -1
  129. package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
  130. package/dist/keystore/indexeddb-shared.js +9 -5
  131. package/dist/keystore/indexeddb-shared.js.map +1 -1
  132. package/dist/keystore/indexeddb-token-store.d.ts +3 -1
  133. package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
  134. package/dist/keystore/indexeddb-token-store.js +47 -2
  135. package/dist/keystore/indexeddb-token-store.js.map +1 -1
  136. package/dist/register-flow.d.ts.map +1 -1
  137. package/dist/register-flow.js +28 -3
  138. package/dist/register-flow.js.map +1 -1
  139. package/dist/seq-tracker.d.ts +28 -8
  140. package/dist/seq-tracker.d.ts.map +1 -1
  141. package/dist/seq-tracker.js +224 -61
  142. package/dist/seq-tracker.js.map +1 -1
  143. package/dist/storage/vfs.d.ts +1 -0
  144. package/dist/storage/vfs.d.ts.map +1 -1
  145. package/dist/storage/vfs.js +26 -2
  146. package/dist/storage/vfs.js.map +1 -1
  147. package/dist/tools/cross-sdk-agent.js +399 -11
  148. package/dist/tools/cross-sdk-agent.js.map +1 -1
  149. package/dist/transport.d.ts +12 -0
  150. package/dist/transport.d.ts.map +1 -1
  151. package/dist/transport.js +226 -102
  152. package/dist/transport.js.map +1 -1
  153. package/dist/v2/session/session.d.ts.map +1 -1
  154. package/dist/v2/session/session.js +3 -4
  155. package/dist/v2/session/session.js.map +1 -1
  156. package/dist/v2/state/commitment.d.ts.map +1 -1
  157. package/dist/v2/state/commitment.js +1 -2
  158. package/dist/v2/state/commitment.js.map +1 -1
  159. package/dist/validators.d.ts.map +1 -1
  160. package/dist/validators.js +8 -14
  161. package/dist/validators.js.map +1 -1
  162. package/dist/version.d.ts +1 -1
  163. package/dist/version.js +1 -1
  164. package/package.json +11 -9
  165. package/dist/group-resources.d.ts +0 -98
  166. package/dist/group-resources.d.ts.map +0 -1
  167. package/dist/group-resources.js +0 -635
  168. package/dist/group-resources.js.map +0 -1
  169. package/dist/keystore/indexeddb.d.ts +0 -179
  170. package/dist/keystore/indexeddb.d.ts.map +0 -1
  171. package/dist/keystore/indexeddb.js +0 -2031
  172. package/dist/keystore/indexeddb.js.map +0 -1
  173. package/dist/namespaces/auth.d.ts +0 -98
  174. package/dist/namespaces/auth.d.ts.map +0 -1
  175. package/dist/namespaces/auth.js +0 -992
  176. package/dist/namespaces/auth.js.map +0 -1
  177. package/dist/namespaces/custody.d.ts +0 -51
  178. package/dist/namespaces/custody.d.ts.map +0 -1
  179. package/dist/namespaces/custody.js +0 -302
  180. package/dist/namespaces/custody.js.map +0 -1
  181. package/dist/namespaces/meta.d.ts +0 -109
  182. package/dist/namespaces/meta.d.ts.map +0 -1
  183. package/dist/namespaces/meta.js +0 -549
  184. package/dist/namespaces/meta.js.map +0 -1
package/dist/agent-md.js CHANGED
@@ -1,8 +1,28 @@
1
1
  import { AID } from './aid.js';
2
2
  import { certMatchesFingerprint, parseAgentMdTailSignature } from './cert-utils.js';
3
+ import { validateAgentMdDocument, verifyAgentMdUpload } from './agent-md-schema.js';
3
4
  import { AUNError, ClientSignatureError, NotFoundError, StateError, ValidationError } from './errors.js';
4
5
  import { isJsonObject } from './types.js';
5
6
  const DEFAULT_HTTP_TIMEOUT_MS = 30_000;
7
+ export function buildDefaultAgentMd(aid, options = {}) {
8
+ const target = String(aid ?? '').trim();
9
+ const type = String(options.type ?? 'agent').trim() || 'agent';
10
+ const name = String(options.name ?? '').trim() || target.split('.', 1)[0] || target;
11
+ const normalized = String(options.description ?? '').trim().replace(/\s+/g, ' ') || `AUN ${type} ${name}`;
12
+ const description = Array.from(normalized).slice(0, 100).join('');
13
+ return [
14
+ '---',
15
+ `aid: ${JSON.stringify(target)}`,
16
+ `name: ${JSON.stringify(name)}`,
17
+ `type: ${JSON.stringify(type)}`,
18
+ 'version: "1.0.0"',
19
+ `description: ${JSON.stringify(description)}`,
20
+ '---',
21
+ '',
22
+ `# ${name}`,
23
+ '',
24
+ ].join('\n');
25
+ }
6
26
  const HEAD_HTTP_TIMEOUT_MS = 15_000;
7
27
  const noopLogger = {
8
28
  error: () => { },
@@ -10,7 +30,127 @@ const noopLogger = {
10
30
  info: () => { },
11
31
  debug: () => { },
12
32
  };
33
+ function nodeBuiltin(name) {
34
+ const processLike = globalThis.process;
35
+ if (typeof processLike?.getBuiltinModule !== 'function')
36
+ return null;
37
+ try {
38
+ return processLike.getBuiltinModule(name);
39
+ }
40
+ catch {
41
+ return null;
42
+ }
43
+ }
44
+ function requestHeaders(init) {
45
+ const out = {};
46
+ try {
47
+ new Headers(init.headers).forEach((value, key) => {
48
+ out[key] = value;
49
+ });
50
+ }
51
+ catch {
52
+ return out;
53
+ }
54
+ return out;
55
+ }
56
+ function requestWithNodeHost(input, init, timeoutMs) {
57
+ return new Promise((resolve, reject) => {
58
+ let parsed;
59
+ try {
60
+ parsed = new URL(input);
61
+ }
62
+ catch (error) {
63
+ reject(error);
64
+ return;
65
+ }
66
+ const module = parsed.protocol === 'https:'
67
+ ? nodeBuiltin('node:https')
68
+ : nodeBuiltin('node:http');
69
+ if (!module) {
70
+ reject(new Error('Node HTTP module is unavailable'));
71
+ return;
72
+ }
73
+ const headers = requestHeaders(init);
74
+ const options = {
75
+ method: init.method ?? 'GET',
76
+ headers,
77
+ timeout: timeoutMs,
78
+ };
79
+ if (parsed.protocol === 'https:') {
80
+ options.rejectUnauthorized = runtimeEnv('NODE_TLS_REJECT_UNAUTHORIZED') !== '0';
81
+ }
82
+ let settled = false;
83
+ let request = null;
84
+ const onAbort = () => {
85
+ request?.destroy(new Error('agent.md request aborted'));
86
+ finish(() => reject(new AUNError('agent.md request aborted')));
87
+ };
88
+ const finish = (callback) => {
89
+ if (settled)
90
+ return;
91
+ settled = true;
92
+ if (init.signal)
93
+ init.signal.removeEventListener('abort', onAbort);
94
+ callback();
95
+ };
96
+ if (init.signal?.aborted) {
97
+ onAbort();
98
+ return;
99
+ }
100
+ try {
101
+ request = module.request(input, options, (response) => {
102
+ const chunks = [];
103
+ response.on('data', (chunk) => {
104
+ if (chunk instanceof Uint8Array)
105
+ chunks.push(chunk);
106
+ else
107
+ chunks.push(new TextEncoder().encode(String(chunk ?? '')));
108
+ });
109
+ response.on('error', (error) => {
110
+ finish(() => reject(error instanceof Error ? error : new Error(String(error))));
111
+ });
112
+ response.on('end', () => {
113
+ const total = chunks.reduce((size, chunk) => size + chunk.byteLength, 0);
114
+ const body = new Uint8Array(total);
115
+ let offset = 0;
116
+ for (const chunk of chunks) {
117
+ body.set(chunk, offset);
118
+ offset += chunk.byteLength;
119
+ }
120
+ const responseHeaders = {};
121
+ for (const [key, value] of Object.entries(response.headers)) {
122
+ if (typeof value === 'string')
123
+ responseHeaders[key] = value;
124
+ else if (Array.isArray(value))
125
+ responseHeaders[key] = value[0] ?? '';
126
+ }
127
+ finish(() => resolve(new Response(body, {
128
+ status: response.statusCode ?? 500,
129
+ headers: responseHeaders,
130
+ })));
131
+ });
132
+ });
133
+ request.on('error', (error) => {
134
+ finish(() => reject(error instanceof Error ? error : new Error(String(error))));
135
+ });
136
+ request.setTimeout(timeoutMs, () => {
137
+ request?.destroy();
138
+ finish(() => reject(new AUNError(`agent.md request timed out after ${timeoutMs}ms`)));
139
+ });
140
+ init.signal?.addEventListener('abort', onAbort, { once: true });
141
+ if (typeof init.body === 'string')
142
+ request.write(init.body);
143
+ request.end();
144
+ }
145
+ catch (error) {
146
+ finish(() => reject(error));
147
+ }
148
+ });
149
+ }
13
150
  async function fetchWithTimeout(input, init, timeoutMs = DEFAULT_HTTP_TIMEOUT_MS) {
151
+ if (new Headers(init.headers).has('host')) {
152
+ return await requestWithNodeHost(input, init, timeoutMs);
153
+ }
14
154
  const controller = new AbortController();
15
155
  const timer = globalThis.setTimeout(() => controller.abort(), timeoutMs);
16
156
  try {
@@ -32,12 +172,54 @@ function headerValue(headers, name) {
32
172
  function agentMdHttpScheme(gatewayUrl) {
33
173
  return String(gatewayUrl ?? '').trim().toLowerCase().startsWith('ws://') ? 'http' : 'https';
34
174
  }
175
+ function runtimeEnv(name) {
176
+ const processLike = globalThis.process;
177
+ return String(processLike?.env?.[name] ?? '').trim();
178
+ }
179
+ function nameServiceAgentMdUrl(aid, gatewayUrl) {
180
+ const configuredBase = runtimeEnv('AUN_NAMESERVICE_URL') || runtimeEnv('KITE_NAMESERVICE_URL');
181
+ if (configuredBase) {
182
+ try {
183
+ const parsed = new URL(configuredBase);
184
+ if (parsed.protocol && parsed.host) {
185
+ parsed.pathname = `${parsed.pathname.replace(/\/+$/g, '')}/agent.md`;
186
+ parsed.search = '';
187
+ parsed.hash = '';
188
+ return parsed.toString();
189
+ }
190
+ }
191
+ catch {
192
+ // 无效配置时回退到按 issuer 推导的 NameService 公网地址。
193
+ }
194
+ }
195
+ const target = String(aid ?? '').trim().toLowerCase();
196
+ const gatewayHost = (() => {
197
+ try {
198
+ return new URL(String(gatewayUrl ?? '').trim()).hostname.toLowerCase();
199
+ }
200
+ catch {
201
+ return '';
202
+ }
203
+ })();
204
+ const configuredIssuer = runtimeEnv('AUN_ISSUER_DOMAIN').toLowerCase();
205
+ const issuer = configuredIssuer
206
+ || (gatewayHost.startsWith('gateway.') ? gatewayHost.slice('gateway.'.length) : '')
207
+ || (target.includes('.') ? target.slice(target.indexOf('.') + 1) : '');
208
+ const host = runtimeEnv('AUN_SERVICE_PUBLIC_HOST_NAMESERVICE') || issuer;
209
+ if (!host)
210
+ return '';
211
+ const scheme = runtimeEnv('AUN_SERVICE_SCHEME_NAMESERVICE') || agentMdHttpScheme(gatewayUrl);
212
+ const port = runtimeEnv('AUN_SERVICE_PUBLIC_PORT_NAMESERVICE');
213
+ const hostWithPort = port && !host.includes(':') && !host.endsWith(`:${port}`) ? `${host}:${port}` : host;
214
+ return `${scheme}://${hostWithPort}/agent.md`;
215
+ }
35
216
  function isRecord(value) {
36
217
  return value !== null && typeof value === 'object' && !Array.isArray(value);
37
218
  }
38
219
  export class AgentMdManager {
39
220
  _aunPath;
40
221
  _agentMdPath;
222
+ _uploadViaGatewayHost;
41
223
  _tokenStore;
42
224
  _log;
43
225
  _ownerAidGetter;
@@ -49,12 +231,13 @@ export class AgentMdManager {
49
231
  _cache = new Map();
50
232
  _memoryStorage = new Map();
51
233
  _fetchInflight = new Set();
234
+ _snapshotLoads = new Map();
52
235
  _lock = Promise.resolve();
53
- _localAgentMdEtag = '';
54
- _remoteAgentMdEtag = '';
236
+ _storageGeneration = 0;
55
237
  constructor(opts) {
56
238
  this._aunPath = String(opts.aunPath ?? '');
57
239
  this._agentMdPath = this._defaultRoot();
240
+ this._uploadViaGatewayHost = opts.uploadViaGatewayHost ?? false;
58
241
  this._tokenStore = opts.tokenStore;
59
242
  this._log = opts.logger ?? noopLogger;
60
243
  this._ownerAidGetter = opts.ownerAidGetter;
@@ -73,11 +256,11 @@ export class AgentMdManager {
73
256
  }
74
257
  setRoot(root) {
75
258
  this._agentMdPath = String(root ?? '').trim() || this._defaultRoot();
259
+ this._storageGeneration += 1;
76
260
  this._cache.clear();
77
261
  this._memoryStorage.clear();
78
262
  this._fetchInflight.clear();
79
- this._localAgentMdEtag = '';
80
- this._remoteAgentMdEtag = '';
263
+ this._snapshotLoads.clear();
81
264
  return this._agentMdPath;
82
265
  }
83
266
  async upload(content) {
@@ -103,11 +286,13 @@ export class AgentMdManager {
103
286
  if (localContent === null || localContent.length === 0) {
104
287
  throw new ValidationError('uploadAgentMd requires local agent.md content');
105
288
  }
289
+ validateAgentMdDocument(localContent, { expectedAid: target });
106
290
  const signedResult = await current.signAgentMd(localContent);
107
291
  if (!signedResult.ok) {
108
292
  throw new ClientSignatureError(signedResult.error.message || 'agent.md signing failed');
109
293
  }
110
294
  const signed = signedResult.data.signed;
295
+ await verifyAgentMdUpload(signed, current.certPem, target);
111
296
  const result = await this._uploadHttp(target, signed);
112
297
  const localEtag = await AgentMdManager.contentEtag(signed);
113
298
  const remoteEtag = String(result.etag ?? '').trim();
@@ -135,6 +320,9 @@ export class AgentMdManager {
135
320
  const signature = { ...verified.data };
136
321
  const statusText = String(signature.status ?? 'invalid');
137
322
  const reason = String(signature.reason ?? '').trim();
323
+ if (statusText === 'invalid') {
324
+ throw new ClientSignatureError(`agent.md verification failed for ${target}${reason ? `: ${reason}` : ''}`);
325
+ }
138
326
  const verification = { status: statusText };
139
327
  if (reason)
140
328
  verification.reason = reason;
@@ -152,7 +340,7 @@ export class AgentMdManager {
152
340
  last_error: '',
153
341
  });
154
342
  let inSync = null;
155
- if (target === this._ownerAid()) {
343
+ if (target.toLowerCase() === this._ownerAid().toLowerCase()) {
156
344
  const remote = contentResult.etag || String(saved.remote_etag ?? '');
157
345
  inSync = localEtag && remote ? localEtag === remote : false;
158
346
  }
@@ -255,8 +443,6 @@ export class AgentMdManager {
255
443
  fields.last_modified = remoteLastModified;
256
444
  record = await this.saveRecord(target, fields) || record;
257
445
  }
258
- if (target === this._ownerAid() && remoteEtag)
259
- this._remoteAgentMdEtag = remoteEtag;
260
446
  await this._scheduleFetchIfMissing(target, record, source);
261
447
  this._log.debug(`agent.md meta observed: aid=${target} etag=${remoteEtag || '-'} last_modified=${remoteLastModified || '-'} source=${source || '-'}`);
262
448
  }
@@ -266,7 +452,6 @@ export class AgentMdManager {
266
452
  const owner = String(ownerAid ?? this._ownerAid() ?? '').trim();
267
453
  const etag = String(meta.agent_md_etag ?? '').trim();
268
454
  if (etag && owner) {
269
- this._remoteAgentMdEtag = etag;
270
455
  await this.observeMeta(owner, etag, '', 'rpc.self');
271
456
  }
272
457
  const etags = meta.agent_md_etags;
@@ -304,33 +489,64 @@ export class AgentMdManager {
304
489
  await this.observeMeta(groupAid, String(group.etag ?? '').trim(), String(group.last_modified ?? group.lastModified ?? '').trim(), 'envelope.group');
305
490
  }
306
491
  }
307
- eventSnapshot() {
308
- if (!this._localAgentMdEtag && !this._remoteAgentMdEtag)
492
+ async eventSnapshot(aid) {
493
+ const target = String(aid ?? this._ownerAid() ?? '').trim();
494
+ if (!target)
495
+ return null;
496
+ const generation = this._storageGeneration;
497
+ if (!this._cache.has(target)) {
498
+ let load = this._snapshotLoads.get(target);
499
+ if (!load) {
500
+ load = this.loadRecord(target).then((record) => {
501
+ if (generation === this._storageGeneration && !this._cache.has(target)) {
502
+ this._cache.set(target, record ? { ...record } : { aid: target });
503
+ }
504
+ });
505
+ this._snapshotLoads.set(target, load);
506
+ }
507
+ try {
508
+ await load;
509
+ }
510
+ finally {
511
+ if (this._snapshotLoads.get(target) === load)
512
+ this._snapshotLoads.delete(target);
513
+ }
514
+ }
515
+ if (generation !== this._storageGeneration)
516
+ return null;
517
+ const record = this._cache.get(target) ?? { aid: target };
518
+ const localEtag = String(record.local_etag ?? '').trim();
519
+ const remoteEtag = String(record.remote_etag ?? record.etag ?? '').trim();
520
+ if (!localEtag && !remoteEtag)
309
521
  return null;
310
- return { local_etag: this._localAgentMdEtag, remote_etag: this._remoteAgentMdEtag };
522
+ return { local_etag: localEtag, remote_etag: remoteEtag };
311
523
  }
312
524
  async readContent(aid) {
313
- return await this._readStorage(this._contentKey(aid));
525
+ const root = this.root;
526
+ return await this._readStorage(this._contentKey(aid), root);
314
527
  }
315
528
  async writeContent(aid, content) {
316
- await this._writeStorage(this._contentKey(aid), String(content ?? ''));
529
+ const root = this.root;
530
+ await this._writeStorage(this._contentKey(aid), String(content ?? ''), root);
317
531
  }
318
532
  async loadRecord(aid) {
319
533
  const target = String(aid ?? '').trim();
320
534
  if (!target)
321
535
  return null;
536
+ const root = this.root;
537
+ const generation = this._storageGeneration;
322
538
  try {
323
539
  const loaded = await this._withLock(async () => {
324
- const record = await this._readRecordUnlocked(target);
540
+ const record = await this._readRecordUnlocked(target, root);
325
541
  const next = Object.keys(record).length > 0 ? { ...record, aid: target } : { aid: target };
326
542
  try {
327
- const content = await this.readContent(target);
543
+ const content = await this._readStorage(this._contentKey(target), root);
328
544
  if (content !== null) {
329
545
  next.content = content;
330
546
  next.local_etag = await AgentMdManager.contentEtag(content);
331
547
  }
332
548
  else {
333
- const metaRaw = await this._readStorage(this._metaKey(target));
549
+ const metaRaw = await this._readStorage(this._metaKey(target), root);
334
550
  if (metaRaw !== null)
335
551
  this._log.warn(`agent.md content read failed: aid=${target}`);
336
552
  }
@@ -342,8 +558,8 @@ export class AgentMdManager {
342
558
  });
343
559
  if (Object.keys(loaded).length <= 1)
344
560
  return null;
345
- this._cache.set(target, { ...loaded });
346
- this._refreshOwnerEtags(target, loaded);
561
+ if (generation === this._storageGeneration)
562
+ this._cache.set(target, { ...loaded });
347
563
  return { ...loaded };
348
564
  }
349
565
  catch (err) {
@@ -355,12 +571,14 @@ export class AgentMdManager {
355
571
  const target = String(aid ?? '').trim();
356
572
  if (!target)
357
573
  return {};
574
+ const root = this.root;
575
+ const generation = this._storageGeneration;
358
576
  try {
359
577
  const inputFields = { ...fields };
360
578
  const hasContent = Object.prototype.hasOwnProperty.call(inputFields, 'content') && inputFields.content !== undefined && inputFields.content !== null;
361
579
  if (hasContent) {
362
580
  const text = String(inputFields.content ?? '');
363
- await this.writeContent(target, text);
581
+ await this._writeStorage(this._contentKey(target), text, root);
364
582
  if (!inputFields.local_etag)
365
583
  inputFields.local_etag = await AgentMdManager.contentEtag(text);
366
584
  if (!inputFields.fetched_at)
@@ -368,20 +586,20 @@ export class AgentMdManager {
368
586
  }
369
587
  delete inputFields.content;
370
588
  const record = await this._withLock(async () => {
371
- const next = { ...(await this._readRecordUnlocked(target)), aid: target };
589
+ const next = { ...(await this._readRecordUnlocked(target, root)), aid: target };
372
590
  for (const [key, value] of Object.entries(inputFields)) {
373
591
  if (value !== undefined && value !== null)
374
592
  next[key] = value;
375
593
  }
376
594
  next.updated_at = Date.now();
377
- await this._writeRecordUnlocked(target, next);
595
+ await this._writeRecordUnlocked(target, next, root);
378
596
  return next;
379
597
  });
380
598
  const loaded = { ...record };
381
599
  if (hasContent)
382
600
  loaded.content = String(fields.content ?? '');
383
- this._cache.set(target, { ...loaded });
384
- this._refreshOwnerEtags(target, loaded);
601
+ if (generation === this._storageGeneration)
602
+ this._cache.set(target, { ...loaded });
385
603
  return { ...loaded };
386
604
  }
387
605
  catch (err) {
@@ -447,10 +665,9 @@ export class AgentMdManager {
447
665
  async _resolvePeer(aid, certFingerprint) {
448
666
  const expectedFp = String(certFingerprint ?? '').trim().toLowerCase();
449
667
  const current = this._currentAid();
450
- if (current?.aid === aid) {
668
+ if (current && current.aid.toLowerCase() === aid.toLowerCase()) {
451
669
  if (!expectedFp || await certMatchesFingerprint(current.certPem, expectedFp))
452
670
  return current;
453
- throw new StateError(`current AID certificate fingerprint mismatch for ${aid}`);
454
671
  }
455
672
  const peer = await this._peerResolver?.(aid, expectedFp || null);
456
673
  if (!(peer instanceof AID)) {
@@ -470,14 +687,48 @@ export class AgentMdManager {
470
687
  async _uploadHttp(aid, content) {
471
688
  const gatewayUrl = await this._resolveGateway(aid);
472
689
  const token = await this._accessToken(aid, gatewayUrl);
473
- const response = await fetchWithTimeout(this._url(aid, gatewayUrl), {
474
- method: 'PUT',
475
- headers: {
476
- Authorization: `Bearer ${token}`,
477
- 'Content-Type': 'text/markdown; charset=utf-8',
478
- },
479
- body: content,
480
- });
690
+ // 浏览器禁止覆盖 Host;动态 AID URL 由浏览器/Docker 的通配解析路由。
691
+ const viaGatewayHost = this._uploadViaGatewayHost && nodeBuiltin('node:http') !== null;
692
+ const headers = {
693
+ Authorization: `Bearer ${token}`,
694
+ 'Content-Type': 'text/markdown; charset=utf-8',
695
+ ...(viaGatewayHost ? { Host: this._safeAid(aid) } : {}),
696
+ };
697
+ let url = this._url(aid, gatewayUrl);
698
+ if (viaGatewayHost) {
699
+ try {
700
+ const parsedGateway = new URL(String(gatewayUrl ?? '').trim());
701
+ const gatewayHost = parsedGateway.hostname;
702
+ const gatewayPort = parsedGateway.port;
703
+ if (gatewayHost) {
704
+ const host = gatewayPort && gatewayPort !== '443' && gatewayPort !== '20001'
705
+ ? `${gatewayHost}:${gatewayPort}`
706
+ : gatewayHost;
707
+ url = `${agentMdHttpScheme(gatewayUrl)}://${host}/agent.md`;
708
+ }
709
+ }
710
+ catch {
711
+ // 无效 Gateway 地址时保留目标 AID URL。
712
+ }
713
+ }
714
+ let response;
715
+ try {
716
+ response = await fetchWithTimeout(url, { method: 'PUT', headers, body: content });
717
+ }
718
+ catch (error) {
719
+ if (!viaGatewayHost)
720
+ throw error;
721
+ const fallbackUrl = nameServiceAgentMdUrl(aid, gatewayUrl);
722
+ if (!fallbackUrl || fallbackUrl === url)
723
+ throw error;
724
+ response = await fetchWithTimeout(fallbackUrl, { method: 'PUT', headers, body: content });
725
+ }
726
+ if (response.status === 404 && viaGatewayHost) {
727
+ const fallbackUrl = nameServiceAgentMdUrl(aid, gatewayUrl);
728
+ if (fallbackUrl && fallbackUrl !== url) {
729
+ response = await fetchWithTimeout(fallbackUrl, { method: 'PUT', headers, body: content });
730
+ }
731
+ }
481
732
  if (response.status === 404) {
482
733
  throw new NotFoundError(`agent.md endpoint not found for aid: ${aid}`);
483
734
  }
@@ -567,35 +818,36 @@ export class AgentMdManager {
567
818
  });
568
819
  return data;
569
820
  }
570
- async _readStorage(logicalKey) {
821
+ async _readStorage(logicalKey, root = this.root) {
571
822
  const key = String(logicalKey ?? '').trim();
572
823
  if (!key)
573
824
  return null;
574
825
  const load = this._tokenStore?.loadAgentMdCache;
575
826
  if (typeof load === 'function') {
576
- const record = await load.call(this._tokenStore, this.root, key);
827
+ const record = await load.call(this._tokenStore, root, key);
577
828
  if (record && Object.prototype.hasOwnProperty.call(record, 'content')) {
578
829
  return String(record.content ?? '');
579
830
  }
580
831
  return null;
581
832
  }
582
- return this._memoryStorage.has(key) ? String(this._memoryStorage.get(key) ?? '') : null;
833
+ const memoryKey = `${root}\u0000${key}`;
834
+ return this._memoryStorage.has(memoryKey) ? String(this._memoryStorage.get(memoryKey) ?? '') : null;
583
835
  }
584
- async _writeStorage(logicalKey, content) {
836
+ async _writeStorage(logicalKey, content, root = this.root) {
585
837
  const key = String(logicalKey ?? '').trim();
586
838
  if (!key)
587
839
  return;
588
840
  const save = this._tokenStore?.upsertAgentMdCache;
589
841
  const text = String(content ?? '');
590
842
  if (typeof save === 'function') {
591
- await save.call(this._tokenStore, this.root, key, {
843
+ await save.call(this._tokenStore, root, key, {
592
844
  content: text,
593
845
  local_etag: await AgentMdManager.contentEtag(text),
594
846
  fetched_at: Date.now(),
595
847
  });
596
848
  return;
597
849
  }
598
- this._memoryStorage.set(key, text);
850
+ this._memoryStorage.set(`${root}\u0000${key}`, text);
599
851
  }
600
852
  async _withLock(fn) {
601
853
  const previous = this._lock.catch(() => undefined);
@@ -624,17 +876,17 @@ export class AgentMdManager {
624
876
  }
625
877
  return record;
626
878
  }
627
- async _writeRecordUnlocked(aid, record) {
879
+ async _writeRecordUnlocked(aid, record, root = this.root) {
628
880
  const payload = {};
629
881
  for (const [key, value] of Object.entries(record)) {
630
882
  if (key !== 'content' && value !== undefined && value !== null)
631
883
  payload[key] = value;
632
884
  }
633
885
  payload.aid = this._safeAid(aid);
634
- await this._writeStorage(this._metaKey(aid), `${JSON.stringify(payload, null, 2)}\n`);
886
+ await this._writeStorage(this._metaKey(aid), `${JSON.stringify(payload, null, 2)}\n`, root);
635
887
  }
636
- async _readRecordUnlocked(aid) {
637
- const raw = await this._readStorage(this._metaKey(aid));
888
+ async _readRecordUnlocked(aid, root = this.root) {
889
+ const raw = await this._readStorage(this._metaKey(aid), root);
638
890
  if (raw === null)
639
891
  return {};
640
892
  try {
@@ -676,15 +928,5 @@ export class AgentMdManager {
676
928
  this._fetchInflight.delete(target);
677
929
  }
678
930
  }
679
- _refreshOwnerEtags(aid, record) {
680
- if (aid !== this._ownerAid())
681
- return;
682
- const localEtag = String(record.local_etag ?? '').trim();
683
- const remoteEtag = String(record.remote_etag ?? '').trim();
684
- if (localEtag)
685
- this._localAgentMdEtag = localEtag;
686
- if (remoteEtag)
687
- this._remoteAgentMdEtag = remoteEtag;
688
- }
689
931
  }
690
932
  //# sourceMappingURL=agent-md.js.map