@agentunion/fastaun 0.5.28 → 0.5.30
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/_packed_docs/CHANGELOG.md +41 -0
- package/_packed_docs/INDEX.md +20 -6
- package/_packed_docs/KITE_DOCS_GUIDE.md +14 -11
- package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +18 -1
- package/_packed_docs/cli//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241CLI/345/274/200/345/217/221/344/270/216/344/275/277/347/224/250/346/214/207/345/215/227.md +869 -0
- package/_packed_docs/sdk/0.5.27-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +408 -0
- package/_packed_docs/sdk/0.5.27-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +410 -0
- package/_packed_docs/sdk/0.5.28-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +228 -0
- package/_packed_docs/sdk/0.5.28-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +146 -0
- package/_packed_docs/sdk/0.5.29-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +180 -0
- package/_packed_docs/sdk/0.5.29-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +164 -0
- package/_packed_docs/sdk/0.5.30-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +61 -0
- package/_packed_docs/sdk/0.5.30-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +68 -0
- package/_packed_docs/sdk/09-/347/273/204/347/273/207/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +90 -90
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +7 -3
- package/_packed_docs/sdk/INDEX.md +20 -4
- package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +1 -1
- package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +1 -1
- package/_packed_docs//346/216/247/345/210/266/346/266/210/346/201/257/344/270/216/350/256/276/345/244/207/350/203/275/345/212/233/345/215/217/345/225/206/346/226/271/346/241/210.md +426 -0
- 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 +279 -229
- package/_packed_docs//351/231/214/347/224/237/344/272/272/346/213/222/347/273/235/345/215/217/350/256/256TDD/345/210/206/351/230/266/346/256/265/345/256/236/346/226/275/350/256/241/345/210/222.md +138 -0
- package/_packed_docs//351/231/214/347/224/237/344/272/272/346/213/222/347/273/235/345/215/217/350/256/256/350/257/246/347/273/206/350/256/276/350/256/241.md +231 -0
- package/_packed_docs//351/243/216/346/216/247/345/223/215/345/272/224/344/270/216SDK/345/215/217/345/220/214/346/226/271/346/241/210.md +381 -0
- package/dist/agent-md-changes.d.ts +2 -14
- package/dist/agent-md-changes.js +41 -212
- package/dist/agent-md-changes.js.map +1 -1
- package/dist/agent-md-schema.js +2 -2
- package/dist/agent-md-schema.js.map +1 -1
- package/dist/agent-md.d.ts +4 -6
- package/dist/agent-md.js +66 -57
- package/dist/agent-md.js.map +1 -1
- package/dist/aid-store.d.ts +3 -1
- package/dist/aid-store.js +65 -42
- package/dist/aid-store.js.map +1 -1
- package/dist/client/control-messages.d.ts +0 -1
- package/dist/client/control-messages.js +90 -70
- package/dist/client/control-messages.js.map +1 -1
- package/dist/client/delivery.js +2 -1
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.js +2 -3
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/lifecycle.js +0 -2
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-pipeline.js +8 -0
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.js +15 -11
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +2 -2
- package/dist/client.js +101 -51
- package/dist/client.js.map +1 -1
- package/dist/config.js +23 -18
- package/dist/config.js.map +1 -1
- package/dist/discovery.js +2 -1
- package/dist/discovery.js.map +1 -1
- package/dist/facades.d.ts +20 -0
- package/dist/facades.js +9 -0
- package/dist/facades.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/keystore/aid-db.js +14 -2
- package/dist/keystore/aid-db.js.map +1 -1
- package/dist/keystore/index.d.ts +3 -0
- package/dist/keystore/index.js +61 -1
- package/dist/keystore/index.js.map +1 -1
- package/dist/keystore/local-identity-store.js +112 -76
- package/dist/keystore/local-identity-store.js.map +1 -1
- package/dist/keystore/local-token-store.js +15 -26
- package/dist/keystore/local-token-store.js.map +1 -1
- package/dist/ownership-v21.d.ts +2 -1
- package/dist/ownership-v21.js +17 -3
- package/dist/ownership-v21.js.map +1 -1
- package/dist/ownership-workflow.js +13 -8
- package/dist/ownership-workflow.js.map +1 -1
- package/dist/register-flow.js +3 -2
- package/dist/register-flow.js.map +1 -1
- package/dist/risk-control.js +2 -2
- package/dist/risk-control.js.map +1 -1
- package/dist/secret-store/file-store.js +68 -56
- package/dist/secret-store/file-store.js.map +1 -1
- package/dist/semantic-facade.js +4 -2
- package/dist/semantic-facade.js.map +1 -1
- package/dist/semantic-protocol.d.ts +2 -12
- package/dist/semantic-protocol.js +33 -48
- package/dist/semantic-protocol.js.map +1 -1
- package/dist/storage/lowlevel.d.ts +4 -0
- package/dist/storage/lowlevel.js +58 -1
- package/dist/storage/lowlevel.js.map +1 -1
- package/dist/storage/vfs.d.ts +4 -0
- package/dist/storage/vfs.js +57 -12
- package/dist/storage/vfs.js.map +1 -1
- package/dist/tools/cross-sdk-agent.d.ts +1 -1
- package/dist/tools/cross-sdk-agent.js +26 -35
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.js +1 -1
- package/dist/transport.js.map +1 -1
- package/dist/validators.js +9 -8
- package/dist/validators.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +8 -8
package/dist/agent-md.js
CHANGED
|
@@ -13,6 +13,7 @@ import { AUNError, ClientSignatureError, NotFoundError, StateError, ValidationEr
|
|
|
13
13
|
import { isJsonObject } from './types.js';
|
|
14
14
|
import { ownershipAid, ownershipFailure, parseOwnershipFile } from './ownership-v21.js';
|
|
15
15
|
import { resultOk } from './result.js';
|
|
16
|
+
import { INVALID_AID_FORMAT } from './error-codes.js';
|
|
16
17
|
const DEFAULT_HTTP_TIMEOUT_MS = 30_000;
|
|
17
18
|
function relationshipFields(meta) {
|
|
18
19
|
return Object.fromEntries(['owner', 'ownership', 'ownership_proof', 'ownership_release'].filter((key) => Object.hasOwn(meta, key)).map((key) => [key, meta[key]]));
|
|
@@ -48,7 +49,7 @@ export function updateOwnershipAgentMd(content, fields) {
|
|
|
48
49
|
document.delete('ownership_release');
|
|
49
50
|
for (const [name, value] of Object.entries(fields))
|
|
50
51
|
document.set(name, value);
|
|
51
|
-
const yamlText = document.toString().replace(/\r\n/g, '\n');
|
|
52
|
+
const yamlText = document.toString({ lineWidth: 0, blockQuote: 'literal' }).replace(/\r\n/g, '\n');
|
|
52
53
|
const updated = `${payload.startsWith('\ufeff') ? '\ufeff' : ''}---\n${yamlText.endsWith('\n') ? yamlText : `${yamlText}\n`}---${match[2]}`;
|
|
53
54
|
validateAgentMdDocument(updated, { expectedAid: String(frontmatter.aid ?? '') });
|
|
54
55
|
return updated;
|
|
@@ -193,21 +194,6 @@ function requestText(url, opts) {
|
|
|
193
194
|
});
|
|
194
195
|
}
|
|
195
196
|
export class AgentMdManager {
|
|
196
|
-
static _commitListeners = new Map();
|
|
197
|
-
static _commitRoot(aunPath) {
|
|
198
|
-
const root = path.resolve(aunPath, 'AIDs');
|
|
199
|
-
return process.platform === 'win32' ? root.toLowerCase() : root;
|
|
200
|
-
}
|
|
201
|
-
static subscribeCommits(aunPath, callback) {
|
|
202
|
-
const root = this._commitRoot(aunPath), listeners = this._commitListeners.get(root) ?? new Set();
|
|
203
|
-
listeners.add(callback);
|
|
204
|
-
this._commitListeners.set(root, listeners);
|
|
205
|
-
return () => {
|
|
206
|
-
listeners.delete(callback);
|
|
207
|
-
if (!listeners.size && this._commitListeners.get(root) === listeners)
|
|
208
|
-
this._commitListeners.delete(root);
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
197
|
_aunPath;
|
|
212
198
|
_verifySsl;
|
|
213
199
|
_log;
|
|
@@ -278,7 +264,7 @@ export class AgentMdManager {
|
|
|
278
264
|
safeAid(aid) {
|
|
279
265
|
const target = String(aid ?? '').trim();
|
|
280
266
|
if (!target || target.includes('/') || target.includes('\\') || target.includes('\0')) {
|
|
281
|
-
throw new ValidationError('agent.md aid is empty or contains path separators');
|
|
267
|
+
throw new ValidationError('agent.md aid is empty or contains path separators', { stringCode: INVALID_AID_FORMAT });
|
|
282
268
|
}
|
|
283
269
|
this._aidValidator?.(target);
|
|
284
270
|
return target;
|
|
@@ -310,7 +296,9 @@ export class AgentMdManager {
|
|
|
310
296
|
loaded.local_etag = AgentMdManager.contentEtag(content);
|
|
311
297
|
}
|
|
312
298
|
catch (err) {
|
|
313
|
-
|
|
299
|
+
delete loaded.content;
|
|
300
|
+
delete loaded.local_etag;
|
|
301
|
+
if (err?.code !== 'ENOENT' && fs.existsSync(this.metaPath(target))) {
|
|
314
302
|
this._log.warn(`agent.md content read failed: aid=${target} err=${err instanceof Error ? err.message : String(err)}`);
|
|
315
303
|
}
|
|
316
304
|
}
|
|
@@ -336,9 +324,6 @@ export class AgentMdManager {
|
|
|
336
324
|
loadRecord(aid) {
|
|
337
325
|
return this._loadRecord(aid);
|
|
338
326
|
}
|
|
339
|
-
listRecordedAids() {
|
|
340
|
-
return fs.readdirSync(this.root, { withFileTypes: true }).filter((entry) => entry.isDirectory() && fs.existsSync(path.join(this.root, entry.name, 'agentmd.json'))).map((entry) => this.safeAid(entry.name));
|
|
341
|
-
}
|
|
342
327
|
updateRecord(aid, change) {
|
|
343
328
|
const target = this.safeAid(aid);
|
|
344
329
|
this._withRecordLock(target, () => {
|
|
@@ -350,11 +335,24 @@ export class AgentMdManager {
|
|
|
350
335
|
this._cache.delete(target);
|
|
351
336
|
}
|
|
352
337
|
setOnCommitted(callback) { this._onCommitted = callback; }
|
|
338
|
+
async _saveCommittedRecord(aid, fields, strict = false) {
|
|
339
|
+
const pending = this._loadRecord(aid, true)?.pending_agent_md_notice;
|
|
340
|
+
const saved = this._saveRecord(aid, fields, strict);
|
|
341
|
+
if (saved.aid && pending?.message_id && this._onCommitted) {
|
|
342
|
+
const notice = (Array.isArray(saved.agent_md_change_outbox) ? saved.agent_md_change_outbox : []).find((item) => item.message_id === pending.message_id);
|
|
343
|
+
if (notice) {
|
|
344
|
+
try {
|
|
345
|
+
await this._onCommitted(aid, notice);
|
|
346
|
+
}
|
|
347
|
+
catch { }
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return saved;
|
|
351
|
+
}
|
|
353
352
|
_saveRecord(aid, fields, strict = false, observation) {
|
|
354
353
|
const target = String(aid ?? '').trim();
|
|
355
354
|
if (!target)
|
|
356
355
|
return {};
|
|
357
|
-
let completedNotice = false;
|
|
358
356
|
try {
|
|
359
357
|
const inputFields = { ...fields };
|
|
360
358
|
const hasContent = Object.prototype.hasOwnProperty.call(inputFields, 'content') && inputFields.content !== undefined && inputFields.content !== null;
|
|
@@ -369,7 +367,6 @@ export class AgentMdManager {
|
|
|
369
367
|
outbox.push(notice);
|
|
370
368
|
inputFields.agent_md_change_outbox = outbox;
|
|
371
369
|
inputFields.pending_agent_md_notice = {};
|
|
372
|
-
completedNotice = true;
|
|
373
370
|
}
|
|
374
371
|
if (observation && (this.root !== observation.root || String(next.remote_etag ?? '') !== observation.etag || Number(next.observation_version ?? 0) !== observation.version))
|
|
375
372
|
throw ownershipFailure('unavailable', 'agent.md observation changed during download', true);
|
|
@@ -398,21 +395,16 @@ export class AgentMdManager {
|
|
|
398
395
|
}
|
|
399
396
|
else {
|
|
400
397
|
const current = this._loadRecord(target, strict);
|
|
401
|
-
if (current && typeof current.content === 'string')
|
|
398
|
+
if (current && typeof current.content === 'string') {
|
|
402
399
|
loaded.content = current.content;
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
listeners.add(this._onCommitted);
|
|
409
|
-
for (const callback of listeners) {
|
|
410
|
-
try {
|
|
411
|
-
callback(target);
|
|
412
|
-
}
|
|
413
|
-
catch { }
|
|
400
|
+
loaded.local_etag = current.local_etag;
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
delete loaded.content;
|
|
404
|
+
delete loaded.local_etag;
|
|
414
405
|
}
|
|
415
406
|
}
|
|
407
|
+
this._cache.set(target, { ...loaded });
|
|
416
408
|
return { ...loaded };
|
|
417
409
|
}
|
|
418
410
|
catch (err) {
|
|
@@ -658,15 +650,15 @@ export class AgentMdManager {
|
|
|
658
650
|
if (!identity || identity.aid !== aid || this._currentAid()?.aid !== aid || this._ownerAid() !== aid)
|
|
659
651
|
throw ownershipFailure('forbidden', 'body recovery requires its current subject identity');
|
|
660
652
|
await this._verifyDocument(pending.content, aid, identity, true, true);
|
|
661
|
-
const remote = await this.
|
|
662
|
-
if (!remote.exists || !isDeepStrictEqual(legacyRelationship(meta), legacyRelationship(validateAgentMdReadDocument(remote.content, { expectedAid: aid }).frontmatter)))
|
|
663
|
-
throw ownershipFailure('conflict', '
|
|
653
|
+
const remote = await this.readOwnershipFresh(aid);
|
|
654
|
+
if (remote.lock === 'locked' && (!remote.exists || !isDeepStrictEqual(legacyRelationship(meta), legacyRelationship(validateAgentMdReadDocument(remote.content, { expectedAid: aid }).frontmatter))))
|
|
655
|
+
throw ownershipFailure('conflict', 'locked agent.md relationship material must remain unchanged');
|
|
664
656
|
if (remote.etag === pending.content_etag && remote.content === pending.content) {
|
|
665
|
-
this.
|
|
657
|
+
await this._saveCommittedRecord(aid, { content: pending.content, remote_etag: remote.etag, pending_operation: '', pending_content: '', pending_content_etag: '', pending_error: '', pending_condition: {}, pending_relation: {}, pending_authorization: '' });
|
|
666
658
|
this._clearConfirmedDraft(aid, pending.content);
|
|
667
659
|
return true;
|
|
668
660
|
}
|
|
669
|
-
if (
|
|
661
|
+
if (condition.if_match && (!remote.exists || remote.etag !== condition.if_match) || condition.if_none_match === '*' && remote.exists)
|
|
670
662
|
throw ownershipFailure('conflict', 'pending agent.md original document condition changed');
|
|
671
663
|
await this._uploadPrepared(aid, pending.content, identity, condition);
|
|
672
664
|
return true;
|
|
@@ -689,7 +681,7 @@ export class AgentMdManager {
|
|
|
689
681
|
await this._verifyDocument(pending.content, aid, identity, true);
|
|
690
682
|
const remote = await this._readEntityFresh(aid);
|
|
691
683
|
if (remote.exists && remote.content === pending.content && remote.etag === pending.content_etag) {
|
|
692
|
-
const saved = this.
|
|
684
|
+
const saved = await this._saveCommittedRecord(aid, { content: pending.content, remote_etag: remote.etag, pending_operation: '', pending_content: '', pending_content_etag: '', pending_error: '', pending_condition: {}, pending_relation: {}, pending_authorization: '' });
|
|
693
685
|
if (!saved.aid)
|
|
694
686
|
throw new StateError('agent.md pending completion persistence failed');
|
|
695
687
|
this._clearConfirmedDraft(aid, pending.content);
|
|
@@ -713,9 +705,9 @@ export class AgentMdManager {
|
|
|
713
705
|
throw new StateError('pending agent.md requires a signer identity');
|
|
714
706
|
if (!multipleSignatures)
|
|
715
707
|
verifyAgentMdBodyUpdate(pending.content, identity.certPem, aid);
|
|
716
|
-
const remote = await this.
|
|
708
|
+
const remote = await this.readOwnershipFresh(aid);
|
|
717
709
|
if (remote.exists && remote.etag === pending.content_etag && remote.content === pending.content) {
|
|
718
|
-
const saved = this.
|
|
710
|
+
const saved = await this._saveCommittedRecord(aid, { content: pending.content, remote_etag: remote.etag, pending_operation: '', pending_content: '', pending_content_etag: '', pending_error: '', pending_condition: {}, pending_relation: {}, pending_authorization: '' });
|
|
719
711
|
if (!saved.aid)
|
|
720
712
|
throw new StateError('agent.md pending completion persistence failed');
|
|
721
713
|
this._clearConfirmedDraft(aid, pending.content);
|
|
@@ -723,8 +715,8 @@ export class AgentMdManager {
|
|
|
723
715
|
}
|
|
724
716
|
if (condition.if_match && (!remote.exists || remote.etag !== condition.if_match) || condition.if_none_match === '*' && remote.exists)
|
|
725
717
|
throw ownershipFailure('conflict', 'pending agent.md original document condition changed');
|
|
726
|
-
if (remote.exists && legacyRelationship(validateAgentMdReadDocument(remote.content, { expectedAid: aid }).frontmatter))
|
|
727
|
-
throw ownershipFailure('conflict', '
|
|
718
|
+
if (remote.lock === 'locked' && remote.exists && legacyRelationship(validateAgentMdReadDocument(remote.content, { expectedAid: aid }).frontmatter))
|
|
719
|
+
throw ownershipFailure('conflict', 'locked agent.md relationship material must remain unchanged');
|
|
728
720
|
await this._uploadPrepared(aid, pending.content, identity, condition);
|
|
729
721
|
return true;
|
|
730
722
|
}
|
|
@@ -746,19 +738,24 @@ export class AgentMdManager {
|
|
|
746
738
|
let condition = originalCondition;
|
|
747
739
|
let relation = entityContext ?? (this._pendingUpload(target, draftStrict))?.relation;
|
|
748
740
|
if (!condition) {
|
|
749
|
-
const fresh = entity ? await this._readEntityFresh(target) :
|
|
741
|
+
const fresh = entity ? await this._readEntityFresh(target) : await this._readBodyOriginalFresh(target);
|
|
750
742
|
condition = fresh.exists ? { if_match: fresh.etag } : { if_none_match: '*' };
|
|
751
743
|
if (!entity) {
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
744
|
+
// 锁未知时按 locked 处理:关系字段必须与原件完全一致
|
|
745
|
+
const locked = 'lock' in fresh && fresh.lock !== 'unlocked';
|
|
746
|
+
const original = fresh.exists ? legacyRelationship(validateAgentMdReadDocument(fresh.content, { expectedAid: target }).frontmatter) : undefined;
|
|
747
|
+
if (locked && !isDeepStrictEqual(legacy, original))
|
|
748
|
+
throw ownershipFailure('conflict', 'locked agent.md relationship material must remain unchanged');
|
|
749
|
+
if (original)
|
|
750
|
+
await this._verifyLegacyBodyContent(target, fresh.content);
|
|
751
|
+
if (legacy && locked)
|
|
755
752
|
relation = { legacy: true, base_content: fresh.content, base_content_etag: AgentMdManager.contentEtag(fresh.content), base_etag: fresh.etag, fields: legacy };
|
|
753
|
+
else if (legacy) {
|
|
754
|
+
const statement = parseOwnershipFile(signedContent, 'agent', { expectedSubAid: target }).statement;
|
|
755
|
+
relation = { relation_version: statement.relation_version, lock: 'unlocked', owner_aid: statement.owner_aid, statement };
|
|
756
756
|
}
|
|
757
|
-
else
|
|
758
|
-
if (fresh.exists && legacyRelationship(validateAgentMdReadDocument(fresh.content, { expectedAid: target }).frontmatter))
|
|
759
|
-
throw ownershipFailure('conflict', 'legacy relationship material cannot be removed or replaced');
|
|
757
|
+
else
|
|
760
758
|
relation = undefined;
|
|
761
|
-
}
|
|
762
759
|
}
|
|
763
760
|
}
|
|
764
761
|
const uploader = this._currentAid();
|
|
@@ -767,7 +764,8 @@ export class AgentMdManager {
|
|
|
767
764
|
const ownership = isJsonObject(meta.ownership) ? meta.ownership : {};
|
|
768
765
|
const statement = isJsonObject(ownership.statement) ? ownership.statement : {};
|
|
769
766
|
const noticeOwner = String(statement.owner_aid ?? ownership.owner_aid ?? meta.owner ?? '').trim();
|
|
770
|
-
const previousNotice = existing?.pending_content === signedContent && isJsonObject(existing.pending_agent_md_notice) ? existing.pending_agent_md_notice
|
|
767
|
+
const previousNotice = existing?.pending_content === signedContent && isJsonObject(existing.pending_agent_md_notice) ? existing.pending_agent_md_notice
|
|
768
|
+
: (Array.isArray(existing?.agent_md_change_outbox) ? existing.agent_md_change_outbox : []).find((item) => item.aid === target && item.owner_aid === noticeOwner && item.sender_aid === (uploader?.aid ?? this._ownerAid()) && item.etag === AgentMdManager.contentEtag(signedContent));
|
|
771
769
|
const notice = previousNotice ?? { sender_aid: uploader?.aid ?? this._ownerAid(), owner_aid: noticeOwner, aid: target, document_type: String(meta.type ?? 'agent'), message_id: crypto.randomUUID() };
|
|
772
770
|
const pending = this._saveRecord(target, { pending_operation: 'replace', pending_target_aid: target, pending_content: signedContent, pending_content_etag: AgentMdManager.contentEtag(signedContent), pending_error: '', pending_condition: condition, pending_relation: relation, pending_authorization: entityAuthorization, pending_agent_md_notice: notice }, draftStrict);
|
|
773
771
|
const savedCondition = pending.pending_condition;
|
|
@@ -781,7 +779,7 @@ export class AgentMdManager {
|
|
|
781
779
|
const authorization = entity ? entityAuthorization : delegated ? this._ownerUploadAuthorization(target, signedContent, owner) : '';
|
|
782
780
|
const result = await this._uploadHttp(target, signedContent, authorization, condition);
|
|
783
781
|
const remoteEtag = String(result.etag ?? '').trim();
|
|
784
|
-
const saved = this.
|
|
782
|
+
const saved = await this._saveCommittedRecord(target, {
|
|
785
783
|
content: signedContent, local_etag: AgentMdManager.contentEtag(signedContent), remote_etag: remoteEtag || undefined,
|
|
786
784
|
last_modified: String(result.last_modified ?? result.lastModified ?? '').trim(), fetched_at: Date.now(), checked_at: Date.now(),
|
|
787
785
|
remote_status: remoteEtag ? 'found' : 'unknown', last_error: '',
|
|
@@ -808,8 +806,19 @@ export class AgentMdManager {
|
|
|
808
806
|
throw ownershipFailure('invalid', 'stored legacy agent.md signature is invalid');
|
|
809
807
|
return parsed;
|
|
810
808
|
}
|
|
809
|
+
// 普通正文更新先严格读取以取得 NS 锁;关系 invalid/unavailable 时不阻断,回落普通原件读取,锁未知
|
|
810
|
+
async _readBodyOriginalFresh(target) {
|
|
811
|
+
try {
|
|
812
|
+
return await this.readOwnershipFresh(target);
|
|
813
|
+
}
|
|
814
|
+
catch (error) {
|
|
815
|
+
if (!(error instanceof AUNError) || !['invalid', 'unavailable'].includes(error.stringCode))
|
|
816
|
+
throw error;
|
|
817
|
+
return { ...await this.readAgentMdFresh(target), lock: 'unknown' };
|
|
818
|
+
}
|
|
819
|
+
}
|
|
811
820
|
async _readLegacyBodyBase(target) {
|
|
812
|
-
const response = await this.
|
|
821
|
+
const response = await this._readBodyOriginalFresh(target);
|
|
813
822
|
if (response.exists)
|
|
814
823
|
await this._verifyLegacyBodyContent(target, response.content);
|
|
815
824
|
return response;
|
|
@@ -832,7 +841,7 @@ export class AgentMdManager {
|
|
|
832
841
|
if (!remote.exists)
|
|
833
842
|
throw ownershipFailure('conflict', 'pending legacy agent.md original document is missing');
|
|
834
843
|
if (remote.content === pending.content && remote.etag === pending.content_etag) {
|
|
835
|
-
const saved = this.
|
|
844
|
+
const saved = await this._saveCommittedRecord(target, { content: pending.content, remote_etag: remote.etag, pending_operation: '', pending_content: '', pending_content_etag: '', pending_error: '', pending_condition: {}, pending_relation: {}, pending_authorization: '' });
|
|
836
845
|
if (!saved.aid)
|
|
837
846
|
throw new StateError('agent.md pending completion persistence failed');
|
|
838
847
|
this._clearConfirmedDraft(target, pending.content);
|