@covia/covia-sdk 1.7.2 → 1.7.4

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/README.md CHANGED
@@ -577,12 +577,14 @@ The SDK provides a hierarchy of typed errors:
577
577
 
578
578
  ```typescript
579
579
  import {
580
+ Venue,
580
581
  CoviaError, // Base error
581
582
  GridError, // HTTP API errors (4xx/5xx)
582
583
  NotFoundError, // 404 responses
583
584
  AssetNotFoundError, // Asset not found
584
585
  JobNotFoundError, // Job not found
585
- CoviaConnectionError,// Connection failures
586
+ CoviaConnectionError,// Transport/connect failures (url, method, attempts)
587
+ VenueIdentityChangedError, // Same address now reports a different DID
586
588
  CoviaTimeoutError, // Timeout exceeded
587
589
  JobFailedError, // Job finished with non-COMPLETE status
588
590
  RateLimitError, // 429 after bounded retries (carries retryAfterSeconds)
@@ -609,6 +611,32 @@ try {
609
611
  }
610
612
  ```
611
613
 
614
+ Transport failures include the exact request target and method. A failed
615
+ `Venue.connect()` additionally includes every candidate and failed validation
616
+ request:
617
+
618
+ ```typescript
619
+ try {
620
+ await Venue.connect("localhost:8080");
621
+ } catch (err) {
622
+ if (err instanceof CoviaConnectionError) {
623
+ console.error(err.candidates);
624
+ for (const attempt of err.attempts) {
625
+ console.error(attempt.method, attempt.url, attempt.error.message);
626
+ }
627
+ }
628
+ }
629
+
630
+ try {
631
+ await venue.status();
632
+ } catch (err) {
633
+ if (err instanceof VenueIdentityChangedError) {
634
+ console.error(`Venue changed from ${err.oldDid} to ${err.newDid}`);
635
+ // Reconnect and re-authorise explicitly; the old handle is not rebound.
636
+ }
637
+ }
638
+ ```
639
+
612
640
  ## Job Status
613
641
 
614
642
  ```typescript
package/dist/index.d.mts CHANGED
@@ -367,6 +367,13 @@ declare class AgentManager {
367
367
  * No polling required.
368
368
  */
369
369
  chat(agentId: string, message: unknown, sessionId?: string): Promise<AgentChatResult>;
370
+ /**
371
+ * Set (or clear, by omitting `title` / passing an empty string) a
372
+ * session's free-form human-facing title — persisted on the venue in
373
+ * the session's own metadata, visible to every client and party in the
374
+ * session (not a per-browser local override).
375
+ */
376
+ renameSession(agentId: string, sessionId: string, title?: string): Promise<AgentRenameSessionResult>;
370
377
  trigger(agentId: string): Promise<AgentTriggerResult>;
371
378
  /**
372
379
  * List the caller's agents. **Job-free** on covia ≥ 0.4: goes through
@@ -715,6 +722,8 @@ declare class Venue implements VenueInterface {
715
722
  * responded (the https candidate if an http fallback failed; the resolved
716
723
  * endpoint for a did:web id), and `venue.venueId` is the DID the venue
717
724
  * reported. The validated API root is `${venue.baseUrl}/api/v1`.
725
+ * @throws {CoviaConnectionError} If no candidate can be validated.
726
+ * @throws {VenueIdentityChangedError} If a known/resolved DID reports a different identity.
718
727
  */
719
728
  static connect(venueId: string | Venue, auth?: Auth): Promise<Venue>;
720
729
  /**
@@ -760,6 +769,7 @@ declare class Venue implements VenueInterface {
760
769
  /**
761
770
  * Get venue status
762
771
  * @returns {Promise<StatusData>}
772
+ * @throws {VenueIdentityChangedError} If this address reports a different known DID.
763
773
  */
764
774
  status(): Promise<StatusData>;
765
775
  /**
@@ -774,6 +784,7 @@ declare class Venue implements VenueInterface {
774
784
  * @param options.pollIntervalMs - Delay between polls (default 1000).
775
785
  * @returns The ready {@link StatusData}.
776
786
  * @throws {CoviaTimeoutError} If the venue is not ready within the timeout.
787
+ * @throws {VenueIdentityChangedError} Immediately if the venue's DID changed.
777
788
  */
778
789
  waitUntilReady(options?: {
779
790
  timeoutMs?: number;
@@ -1079,6 +1090,12 @@ interface AgentSuspendResult {
1079
1090
  agentId: string;
1080
1091
  status: string;
1081
1092
  }
1093
+ interface AgentRenameSessionResult {
1094
+ agentId: string;
1095
+ sessionId: string;
1096
+ /** Absent when the title was cleared (an omitted/blank title on the call). */
1097
+ title?: string;
1098
+ }
1082
1099
  interface AgentResumeInput {
1083
1100
  agentId: string;
1084
1101
  autoWake?: boolean;
@@ -1323,9 +1340,47 @@ declare class GridError extends CoviaError {
1323
1340
  responseBody: unknown;
1324
1341
  constructor(statusCode: number, message: string, responseBody?: unknown);
1325
1342
  }
1326
- /** Raised when the SDK cannot connect to the venue. */
1343
+ /** One failed HTTP request made while resolving/validating a venue connection. */
1344
+ interface ConnectionAttempt {
1345
+ readonly url: string;
1346
+ readonly method: string;
1347
+ readonly error: CoviaError;
1348
+ }
1349
+ interface CoviaConnectionErrorOptions {
1350
+ /** Exact request target for a single transport failure. */
1351
+ url?: string;
1352
+ /** HTTP method for a single transport failure. */
1353
+ method?: string;
1354
+ /** Original exception, or the final failed attempt for an aggregate error. */
1355
+ cause?: unknown;
1356
+ /** Ordered venue base URLs considered by `Venue.connect()`. */
1357
+ candidates?: readonly string[];
1358
+ /** Ordered failed requests made while validating those candidates. */
1359
+ attempts?: readonly ConnectionAttempt[];
1360
+ }
1361
+ /**
1362
+ * Raised when an HTTP request cannot be made, or when `Venue.connect()` cannot
1363
+ * validate any candidate. HTTP responses still use `GridError`; this class is
1364
+ * for transport failures and connection-attempt aggregation.
1365
+ */
1327
1366
  declare class CoviaConnectionError extends CoviaError {
1328
- constructor(message: string);
1367
+ readonly url: string | null;
1368
+ readonly method: string | null;
1369
+ readonly cause: unknown;
1370
+ readonly candidates: readonly string[];
1371
+ readonly attempts: readonly ConnectionAttempt[];
1372
+ constructor(message: string, options?: CoviaConnectionErrorOptions);
1373
+ }
1374
+ /**
1375
+ * Raised when a known venue address reports a different DID. The instance
1376
+ * remains bound to `oldDid`; callers must explicitly reconnect/re-authorise
1377
+ * against `newDid` rather than silently continuing under a new identity.
1378
+ */
1379
+ declare class VenueIdentityChangedError extends CoviaError {
1380
+ readonly oldDid: string;
1381
+ readonly newDid: string;
1382
+ readonly baseUrl: string;
1383
+ constructor(oldDid: string, newDid: string, baseUrl: string);
1329
1384
  }
1330
1385
  /** Raised when an operation or polling loop times out. */
1331
1386
  declare class CoviaTimeoutError extends CoviaError {
@@ -1638,4 +1693,4 @@ declare function grant(ownerPrivateKey: Uint8Array, audienceDID: string, withRes
1638
1693
  */
1639
1694
  declare function relayDelegation(privateKey: Uint8Array, venueDID: string, lifetimeSeconds: number, caps?: UCANCapability[]): string;
1640
1695
 
1641
- export { type AdapterInfo, AdapterManager, type AdaptersResult, Agent, type AgentCancelTaskInput, type AgentCard, type AgentChatInput, type AgentChatResult, type AgentCompleteTaskResult, type AgentContextInput, type AgentCreateInput, type AgentCreateResult, type AgentDeleteInput, type AgentDeleteResult, type AgentFailTaskResult, type AgentForkInput, type AgentForkResult, type AgentInfoResult, type AgentListInput, type AgentListResult, AgentManager, type AgentMessageInput, type AgentMessageResult, type AgentRequestInput, type AgentRequestResult, type AgentResumeInput, AgentStatus, type AgentSuspendResult, type AgentTriggerInput, type AgentTriggerResult, type AgentUpdateInput, Asset, type AssetID, type AssetList, type AssetListOptions, AssetManager, type AssetMetadata, type AssetMetadataStore, AssetNotFoundError, type AssetPinResult, Auth, BasicAuth, BearerAuth, ChatSession, type ContentDetails, type ContentHashResult, CoviaConnectionError, CoviaError, CoviaTimeoutError, type Credentials, CredentialsHTTP, type DIDDocument, type DIDURL, DataAsset, Ed25519Auth, type FunctionInfo, type FunctionsResult, Grid, GridError, type GroupCount, type InvokeOptions, type InvokePayload, Job, JobFailedError, JobManager, type JobMetadata, JobNotFoundError, JobStatus, KeyPairAuth, type MCPDiscovery, Namespace, NoAuth, NotFoundError, Operation, type OperationDetails, type OperationInfo, OperationManager, type OperationPayload, type OperationRunner, RateLimitError, RunStatus, type SSEEvent, type SecretExtractInput, type SecretExtractResult, SecretManager, type SecretSetInput, type SecretSetResult, type StatsData, type StatusData, type UCANAttenuation, type UCANCapability, type UCANIssueInput, type UCANIssueResult, UCANManager, type UCANVerifyResult, VENUE_RELAY, Venue, type VenueConstructor, type VenueData, type VenueInterface, type VenueOptions, type WorkspaceAggregateResult, type WorkspaceAppendInput, type WorkspaceAppendResult, type WorkspaceCopyResult, type WorkspaceCountResult, type WorkspaceDeleteInput, type WorkspaceDeleteResult, type WorkspaceInspectInput, type WorkspaceInspectResult, type WorkspaceListInput, type WorkspaceListResult, WorkspaceManager, type WorkspaceReadInput, type WorkspaceReadResult, type WorkspaceSliceInput, type WorkspaceSliceResult, type WorkspaceWriteInput, type WorkspaceWriteResult, assetHash, createSSEEvent, createUCANJWT, decodePublicKey, didFor, didFromPublicKey, didMethod, didUrl, encodePublicKey, fetchStreamWithError, fetchWithError, generateKeyPair, getAssetIdFromPath, getAssetIdFromVenueId, getAssetMetadataStore, getParsedAssetId, grant, hexToPrivateKey, identityToken, isDid, isJobComplete, isJobFinished, isJobPaused, logger, parseDidUrl, parseRetryAfterMs, parseSSEStream, privateKeyToHex, relayDelegation, retryDelayMs, setAssetMetadataStore, venueBaseUrlCandidates };
1696
+ export { type AdapterInfo, AdapterManager, type AdaptersResult, Agent, type AgentCancelTaskInput, type AgentCard, type AgentChatInput, type AgentChatResult, type AgentCompleteTaskResult, type AgentContextInput, type AgentCreateInput, type AgentCreateResult, type AgentDeleteInput, type AgentDeleteResult, type AgentFailTaskResult, type AgentForkInput, type AgentForkResult, type AgentInfoResult, type AgentListInput, type AgentListResult, AgentManager, type AgentMessageInput, type AgentMessageResult, type AgentRenameSessionResult, type AgentRequestInput, type AgentRequestResult, type AgentResumeInput, AgentStatus, type AgentSuspendResult, type AgentTriggerInput, type AgentTriggerResult, type AgentUpdateInput, Asset, type AssetID, type AssetList, type AssetListOptions, AssetManager, type AssetMetadata, type AssetMetadataStore, AssetNotFoundError, type AssetPinResult, Auth, BasicAuth, BearerAuth, ChatSession, type ConnectionAttempt, type ContentDetails, type ContentHashResult, CoviaConnectionError, type CoviaConnectionErrorOptions, CoviaError, CoviaTimeoutError, type Credentials, CredentialsHTTP, type DIDDocument, type DIDURL, DataAsset, Ed25519Auth, type FunctionInfo, type FunctionsResult, Grid, GridError, type GroupCount, type InvokeOptions, type InvokePayload, Job, JobFailedError, JobManager, type JobMetadata, JobNotFoundError, JobStatus, KeyPairAuth, type MCPDiscovery, Namespace, NoAuth, NotFoundError, Operation, type OperationDetails, type OperationInfo, OperationManager, type OperationPayload, type OperationRunner, RateLimitError, RunStatus, type SSEEvent, type SecretExtractInput, type SecretExtractResult, SecretManager, type SecretSetInput, type SecretSetResult, type StatsData, type StatusData, type UCANAttenuation, type UCANCapability, type UCANIssueInput, type UCANIssueResult, UCANManager, type UCANVerifyResult, VENUE_RELAY, Venue, type VenueConstructor, type VenueData, VenueIdentityChangedError, type VenueInterface, type VenueOptions, type WorkspaceAggregateResult, type WorkspaceAppendInput, type WorkspaceAppendResult, type WorkspaceCopyResult, type WorkspaceCountResult, type WorkspaceDeleteInput, type WorkspaceDeleteResult, type WorkspaceInspectInput, type WorkspaceInspectResult, type WorkspaceListInput, type WorkspaceListResult, WorkspaceManager, type WorkspaceReadInput, type WorkspaceReadResult, type WorkspaceSliceInput, type WorkspaceSliceResult, type WorkspaceWriteInput, type WorkspaceWriteResult, assetHash, createSSEEvent, createUCANJWT, decodePublicKey, didFor, didFromPublicKey, didMethod, didUrl, encodePublicKey, fetchStreamWithError, fetchWithError, generateKeyPair, getAssetIdFromPath, getAssetIdFromVenueId, getAssetMetadataStore, getParsedAssetId, grant, hexToPrivateKey, identityToken, isDid, isJobComplete, isJobFinished, isJobPaused, logger, parseDidUrl, parseRetryAfterMs, parseSSEStream, privateKeyToHex, relayDelegation, retryDelayMs, setAssetMetadataStore, venueBaseUrlCandidates };
package/dist/index.d.ts CHANGED
@@ -367,6 +367,13 @@ declare class AgentManager {
367
367
  * No polling required.
368
368
  */
369
369
  chat(agentId: string, message: unknown, sessionId?: string): Promise<AgentChatResult>;
370
+ /**
371
+ * Set (or clear, by omitting `title` / passing an empty string) a
372
+ * session's free-form human-facing title — persisted on the venue in
373
+ * the session's own metadata, visible to every client and party in the
374
+ * session (not a per-browser local override).
375
+ */
376
+ renameSession(agentId: string, sessionId: string, title?: string): Promise<AgentRenameSessionResult>;
370
377
  trigger(agentId: string): Promise<AgentTriggerResult>;
371
378
  /**
372
379
  * List the caller's agents. **Job-free** on covia ≥ 0.4: goes through
@@ -715,6 +722,8 @@ declare class Venue implements VenueInterface {
715
722
  * responded (the https candidate if an http fallback failed; the resolved
716
723
  * endpoint for a did:web id), and `venue.venueId` is the DID the venue
717
724
  * reported. The validated API root is `${venue.baseUrl}/api/v1`.
725
+ * @throws {CoviaConnectionError} If no candidate can be validated.
726
+ * @throws {VenueIdentityChangedError} If a known/resolved DID reports a different identity.
718
727
  */
719
728
  static connect(venueId: string | Venue, auth?: Auth): Promise<Venue>;
720
729
  /**
@@ -760,6 +769,7 @@ declare class Venue implements VenueInterface {
760
769
  /**
761
770
  * Get venue status
762
771
  * @returns {Promise<StatusData>}
772
+ * @throws {VenueIdentityChangedError} If this address reports a different known DID.
763
773
  */
764
774
  status(): Promise<StatusData>;
765
775
  /**
@@ -774,6 +784,7 @@ declare class Venue implements VenueInterface {
774
784
  * @param options.pollIntervalMs - Delay between polls (default 1000).
775
785
  * @returns The ready {@link StatusData}.
776
786
  * @throws {CoviaTimeoutError} If the venue is not ready within the timeout.
787
+ * @throws {VenueIdentityChangedError} Immediately if the venue's DID changed.
777
788
  */
778
789
  waitUntilReady(options?: {
779
790
  timeoutMs?: number;
@@ -1079,6 +1090,12 @@ interface AgentSuspendResult {
1079
1090
  agentId: string;
1080
1091
  status: string;
1081
1092
  }
1093
+ interface AgentRenameSessionResult {
1094
+ agentId: string;
1095
+ sessionId: string;
1096
+ /** Absent when the title was cleared (an omitted/blank title on the call). */
1097
+ title?: string;
1098
+ }
1082
1099
  interface AgentResumeInput {
1083
1100
  agentId: string;
1084
1101
  autoWake?: boolean;
@@ -1323,9 +1340,47 @@ declare class GridError extends CoviaError {
1323
1340
  responseBody: unknown;
1324
1341
  constructor(statusCode: number, message: string, responseBody?: unknown);
1325
1342
  }
1326
- /** Raised when the SDK cannot connect to the venue. */
1343
+ /** One failed HTTP request made while resolving/validating a venue connection. */
1344
+ interface ConnectionAttempt {
1345
+ readonly url: string;
1346
+ readonly method: string;
1347
+ readonly error: CoviaError;
1348
+ }
1349
+ interface CoviaConnectionErrorOptions {
1350
+ /** Exact request target for a single transport failure. */
1351
+ url?: string;
1352
+ /** HTTP method for a single transport failure. */
1353
+ method?: string;
1354
+ /** Original exception, or the final failed attempt for an aggregate error. */
1355
+ cause?: unknown;
1356
+ /** Ordered venue base URLs considered by `Venue.connect()`. */
1357
+ candidates?: readonly string[];
1358
+ /** Ordered failed requests made while validating those candidates. */
1359
+ attempts?: readonly ConnectionAttempt[];
1360
+ }
1361
+ /**
1362
+ * Raised when an HTTP request cannot be made, or when `Venue.connect()` cannot
1363
+ * validate any candidate. HTTP responses still use `GridError`; this class is
1364
+ * for transport failures and connection-attempt aggregation.
1365
+ */
1327
1366
  declare class CoviaConnectionError extends CoviaError {
1328
- constructor(message: string);
1367
+ readonly url: string | null;
1368
+ readonly method: string | null;
1369
+ readonly cause: unknown;
1370
+ readonly candidates: readonly string[];
1371
+ readonly attempts: readonly ConnectionAttempt[];
1372
+ constructor(message: string, options?: CoviaConnectionErrorOptions);
1373
+ }
1374
+ /**
1375
+ * Raised when a known venue address reports a different DID. The instance
1376
+ * remains bound to `oldDid`; callers must explicitly reconnect/re-authorise
1377
+ * against `newDid` rather than silently continuing under a new identity.
1378
+ */
1379
+ declare class VenueIdentityChangedError extends CoviaError {
1380
+ readonly oldDid: string;
1381
+ readonly newDid: string;
1382
+ readonly baseUrl: string;
1383
+ constructor(oldDid: string, newDid: string, baseUrl: string);
1329
1384
  }
1330
1385
  /** Raised when an operation or polling loop times out. */
1331
1386
  declare class CoviaTimeoutError extends CoviaError {
@@ -1638,4 +1693,4 @@ declare function grant(ownerPrivateKey: Uint8Array, audienceDID: string, withRes
1638
1693
  */
1639
1694
  declare function relayDelegation(privateKey: Uint8Array, venueDID: string, lifetimeSeconds: number, caps?: UCANCapability[]): string;
1640
1695
 
1641
- export { type AdapterInfo, AdapterManager, type AdaptersResult, Agent, type AgentCancelTaskInput, type AgentCard, type AgentChatInput, type AgentChatResult, type AgentCompleteTaskResult, type AgentContextInput, type AgentCreateInput, type AgentCreateResult, type AgentDeleteInput, type AgentDeleteResult, type AgentFailTaskResult, type AgentForkInput, type AgentForkResult, type AgentInfoResult, type AgentListInput, type AgentListResult, AgentManager, type AgentMessageInput, type AgentMessageResult, type AgentRequestInput, type AgentRequestResult, type AgentResumeInput, AgentStatus, type AgentSuspendResult, type AgentTriggerInput, type AgentTriggerResult, type AgentUpdateInput, Asset, type AssetID, type AssetList, type AssetListOptions, AssetManager, type AssetMetadata, type AssetMetadataStore, AssetNotFoundError, type AssetPinResult, Auth, BasicAuth, BearerAuth, ChatSession, type ContentDetails, type ContentHashResult, CoviaConnectionError, CoviaError, CoviaTimeoutError, type Credentials, CredentialsHTTP, type DIDDocument, type DIDURL, DataAsset, Ed25519Auth, type FunctionInfo, type FunctionsResult, Grid, GridError, type GroupCount, type InvokeOptions, type InvokePayload, Job, JobFailedError, JobManager, type JobMetadata, JobNotFoundError, JobStatus, KeyPairAuth, type MCPDiscovery, Namespace, NoAuth, NotFoundError, Operation, type OperationDetails, type OperationInfo, OperationManager, type OperationPayload, type OperationRunner, RateLimitError, RunStatus, type SSEEvent, type SecretExtractInput, type SecretExtractResult, SecretManager, type SecretSetInput, type SecretSetResult, type StatsData, type StatusData, type UCANAttenuation, type UCANCapability, type UCANIssueInput, type UCANIssueResult, UCANManager, type UCANVerifyResult, VENUE_RELAY, Venue, type VenueConstructor, type VenueData, type VenueInterface, type VenueOptions, type WorkspaceAggregateResult, type WorkspaceAppendInput, type WorkspaceAppendResult, type WorkspaceCopyResult, type WorkspaceCountResult, type WorkspaceDeleteInput, type WorkspaceDeleteResult, type WorkspaceInspectInput, type WorkspaceInspectResult, type WorkspaceListInput, type WorkspaceListResult, WorkspaceManager, type WorkspaceReadInput, type WorkspaceReadResult, type WorkspaceSliceInput, type WorkspaceSliceResult, type WorkspaceWriteInput, type WorkspaceWriteResult, assetHash, createSSEEvent, createUCANJWT, decodePublicKey, didFor, didFromPublicKey, didMethod, didUrl, encodePublicKey, fetchStreamWithError, fetchWithError, generateKeyPair, getAssetIdFromPath, getAssetIdFromVenueId, getAssetMetadataStore, getParsedAssetId, grant, hexToPrivateKey, identityToken, isDid, isJobComplete, isJobFinished, isJobPaused, logger, parseDidUrl, parseRetryAfterMs, parseSSEStream, privateKeyToHex, relayDelegation, retryDelayMs, setAssetMetadataStore, venueBaseUrlCandidates };
1696
+ export { type AdapterInfo, AdapterManager, type AdaptersResult, Agent, type AgentCancelTaskInput, type AgentCard, type AgentChatInput, type AgentChatResult, type AgentCompleteTaskResult, type AgentContextInput, type AgentCreateInput, type AgentCreateResult, type AgentDeleteInput, type AgentDeleteResult, type AgentFailTaskResult, type AgentForkInput, type AgentForkResult, type AgentInfoResult, type AgentListInput, type AgentListResult, AgentManager, type AgentMessageInput, type AgentMessageResult, type AgentRenameSessionResult, type AgentRequestInput, type AgentRequestResult, type AgentResumeInput, AgentStatus, type AgentSuspendResult, type AgentTriggerInput, type AgentTriggerResult, type AgentUpdateInput, Asset, type AssetID, type AssetList, type AssetListOptions, AssetManager, type AssetMetadata, type AssetMetadataStore, AssetNotFoundError, type AssetPinResult, Auth, BasicAuth, BearerAuth, ChatSession, type ConnectionAttempt, type ContentDetails, type ContentHashResult, CoviaConnectionError, type CoviaConnectionErrorOptions, CoviaError, CoviaTimeoutError, type Credentials, CredentialsHTTP, type DIDDocument, type DIDURL, DataAsset, Ed25519Auth, type FunctionInfo, type FunctionsResult, Grid, GridError, type GroupCount, type InvokeOptions, type InvokePayload, Job, JobFailedError, JobManager, type JobMetadata, JobNotFoundError, JobStatus, KeyPairAuth, type MCPDiscovery, Namespace, NoAuth, NotFoundError, Operation, type OperationDetails, type OperationInfo, OperationManager, type OperationPayload, type OperationRunner, RateLimitError, RunStatus, type SSEEvent, type SecretExtractInput, type SecretExtractResult, SecretManager, type SecretSetInput, type SecretSetResult, type StatsData, type StatusData, type UCANAttenuation, type UCANCapability, type UCANIssueInput, type UCANIssueResult, UCANManager, type UCANVerifyResult, VENUE_RELAY, Venue, type VenueConstructor, type VenueData, VenueIdentityChangedError, type VenueInterface, type VenueOptions, type WorkspaceAggregateResult, type WorkspaceAppendInput, type WorkspaceAppendResult, type WorkspaceCopyResult, type WorkspaceCountResult, type WorkspaceDeleteInput, type WorkspaceDeleteResult, type WorkspaceInspectInput, type WorkspaceInspectResult, type WorkspaceListInput, type WorkspaceListResult, WorkspaceManager, type WorkspaceReadInput, type WorkspaceReadResult, type WorkspaceSliceInput, type WorkspaceSliceResult, type WorkspaceWriteInput, type WorkspaceWriteResult, assetHash, createSSEEvent, createUCANJWT, decodePublicKey, didFor, didFromPublicKey, didMethod, didUrl, encodePublicKey, fetchStreamWithError, fetchWithError, generateKeyPair, getAssetIdFromPath, getAssetIdFromVenueId, getAssetMetadataStore, getParsedAssetId, grant, hexToPrivateKey, identityToken, isDid, isJobComplete, isJobFinished, isJobPaused, logger, parseDidUrl, parseRetryAfterMs, parseSSEStream, privateKeyToHex, relayDelegation, retryDelayMs, setAssetMetadataStore, venueBaseUrlCandidates };
package/dist/index.js CHANGED
@@ -46,9 +46,23 @@ var GridError = class extends CoviaError {
46
46
  }
47
47
  };
48
48
  var CoviaConnectionError = class extends CoviaError {
49
- constructor(message) {
49
+ constructor(message, options = {}) {
50
50
  super(message);
51
51
  this.name = "CoviaConnectionError";
52
+ this.url = options.url ?? null;
53
+ this.method = options.method?.toUpperCase() ?? null;
54
+ this.cause = options.cause;
55
+ this.candidates = [...options.candidates ?? []];
56
+ this.attempts = [...options.attempts ?? []];
57
+ }
58
+ };
59
+ var VenueIdentityChangedError = class extends CoviaError {
60
+ constructor(oldDid, newDid, baseUrl) {
61
+ super(`Venue identity changed at ${baseUrl}: expected ${oldDid}, received ${newDid}`);
62
+ this.oldDid = oldDid;
63
+ this.newDid = newDid;
64
+ this.baseUrl = baseUrl;
65
+ this.name = "VenueIdentityChangedError";
52
66
  }
53
67
  };
54
68
  var CoviaTimeoutError = class extends CoviaError {
@@ -63,7 +77,8 @@ var JobFailedError = class extends CoviaError {
63
77
  const status = jobData.status ?? "unknown";
64
78
  let msg = `Job ${id} ${status}`;
65
79
  const output = jobData.output;
66
- const errText = output && typeof output === "object" && "error" in output ? output.error : void 0;
80
+ const outputErrText = output && typeof output === "object" && "error" in output ? output.error : void 0;
81
+ const errText = typeof jobData.error === "string" ? jobData.error : outputErrText;
67
82
  if (typeof errText === "string") {
68
83
  msg += `: ${errText}`;
69
84
  }
@@ -1308,13 +1323,14 @@ async function throwHttpError(response) {
1308
1323
  }
1309
1324
  throw new GridError(response.status, message, body);
1310
1325
  }
1311
- function wrapError(error) {
1312
- if (error instanceof CoviaError) return error;
1313
- const msg = error.message ?? String(error);
1314
- if (error instanceof TypeError) {
1315
- return new CoviaConnectionError(msg);
1316
- }
1317
- return new CoviaError(`Request failed: ${msg}`);
1326
+ function wrapConnectionError(error, url, method) {
1327
+ if (error instanceof CoviaConnectionError && error.url && error.method) return error;
1328
+ const detail = error instanceof Error ? error.message : String(error);
1329
+ return new CoviaConnectionError(`${method} ${url} failed: ${detail}`, {
1330
+ url,
1331
+ method,
1332
+ cause: error
1333
+ });
1318
1334
  }
1319
1335
  var RETRY_MAX_ATTEMPTS = 4;
1320
1336
  var RETRY_BASE_MS = 200;
@@ -1335,7 +1351,7 @@ function retryDelayMs(attempt, retryAfterMs, remainingBudgetMs, random) {
1335
1351
  }
1336
1352
  var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
1337
1353
  async function fetchWithError(url, options) {
1338
- const method = options?.method ?? "GET";
1354
+ const method = (options?.method ?? "GET").toUpperCase();
1339
1355
  const deadline = Date.now() + RETRY_BUDGET_MS;
1340
1356
  for (let attempt = 1; ; attempt++) {
1341
1357
  logger.debug(`${method} ${url}`);
@@ -1345,7 +1361,7 @@ async function fetchWithError(url, options) {
1345
1361
  } catch (error) {
1346
1362
  const msg = error.message ?? String(error);
1347
1363
  logger.debug(`Connection failed: ${method} ${url} \u2014 ${msg}`);
1348
- throw wrapError(error);
1364
+ throw wrapConnectionError(error, url, method);
1349
1365
  }
1350
1366
  logger.debug(`${method} ${url} \u2192 ${response.status}`);
1351
1367
  if (response.status === 429) {
@@ -1367,7 +1383,7 @@ async function fetchWithError(url, options) {
1367
1383
  }
1368
1384
  }
1369
1385
  async function fetchStreamWithError(url, options) {
1370
- const method = options?.method ?? "GET";
1386
+ const method = (options?.method ?? "GET").toUpperCase();
1371
1387
  logger.debug(`${method} ${url}`);
1372
1388
  let response;
1373
1389
  try {
@@ -1375,7 +1391,7 @@ async function fetchStreamWithError(url, options) {
1375
1391
  } catch (error) {
1376
1392
  const msg = error.message ?? String(error);
1377
1393
  logger.debug(`Connection failed: ${method} ${url} \u2014 ${msg}`);
1378
- throw wrapError(error);
1394
+ throw wrapConnectionError(error, url, method);
1379
1395
  }
1380
1396
  logger.debug(`${method} ${url} \u2192 ${response.status}`);
1381
1397
  if (!response.ok) {
@@ -1667,6 +1683,15 @@ var AgentManager = class {
1667
1683
  async chat(agentId, message, sessionId) {
1668
1684
  return this.venue.operations.run("v/ops/agent/chat", { agentId, message, sessionId });
1669
1685
  }
1686
+ /**
1687
+ * Set (or clear, by omitting `title` / passing an empty string) a
1688
+ * session's free-form human-facing title — persisted on the venue in
1689
+ * the session's own metadata, visible to every client and party in the
1690
+ * session (not a per-browser local override).
1691
+ */
1692
+ async renameSession(agentId, sessionId, title) {
1693
+ return this.venue.operations.run("v/ops/agent/rename-session", { agentId, sessionId, title });
1694
+ }
1670
1695
  async trigger(agentId) {
1671
1696
  return this.venue.operations.run("v/ops/agent/trigger", { agentId });
1672
1697
  }
@@ -2070,7 +2095,9 @@ var AssetManager = class {
2070
2095
  }
2071
2096
  }
2072
2097
  try {
2073
- const data = await fetchWithError(`${this.venue.baseUrl}/api/v1/assets/${assetId}`);
2098
+ const data = await fetchWithError(`${this.venue.baseUrl}/api/v1/assets/${assetId}`, {
2099
+ headers: this._buildHeaders(null)
2100
+ });
2074
2101
  if (hash) {
2075
2102
  cache.set(assetId, data);
2076
2103
  getAssetMetadataStore()?.put(normaliseHash(hash), data);
@@ -2099,7 +2126,9 @@ var AssetManager = class {
2099
2126
  if (options.limit !== void 0) {
2100
2127
  params.set("limit", String(options.limit));
2101
2128
  }
2102
- return fetchWithError(`${this.venue.baseUrl}/api/v1/assets?${params.toString()}`);
2129
+ return fetchWithError(`${this.venue.baseUrl}/api/v1/assets?${params.toString()}`, {
2130
+ headers: this._buildHeaders(null)
2131
+ });
2103
2132
  }
2104
2133
  /**
2105
2134
  * Register a new asset
@@ -2118,7 +2147,9 @@ var AssetManager = class {
2118
2147
  */
2119
2148
  async getMetadata(assetId) {
2120
2149
  try {
2121
- return await fetchWithError(`${this.venue.baseUrl}/api/v1/assets/${assetId}`);
2150
+ return await fetchWithError(`${this.venue.baseUrl}/api/v1/assets/${assetId}`, {
2151
+ headers: this._buildHeaders(null)
2152
+ });
2122
2153
  } catch (error) {
2123
2154
  if (error instanceof NotFoundError) {
2124
2155
  throw new AssetNotFoundError(assetId);
@@ -2152,7 +2183,9 @@ var AssetManager = class {
2152
2183
  */
2153
2184
  async getContent(assetId) {
2154
2185
  try {
2155
- const response = await fetchStreamWithError(`${this.venue.baseUrl}/api/v1/assets/${assetId}/content`);
2186
+ const response = await fetchStreamWithError(`${this.venue.baseUrl}/api/v1/assets/${assetId}/content`, {
2187
+ headers: this._buildHeaders(null)
2188
+ });
2156
2189
  return response.body;
2157
2190
  } catch (error) {
2158
2191
  if (error instanceof NotFoundError) {
@@ -2549,6 +2582,20 @@ function venueBaseUrlCandidates(venueId) {
2549
2582
  }
2550
2583
  return schemelessVenueCandidates(venueId);
2551
2584
  }
2585
+ function asCoviaError(error) {
2586
+ if (error instanceof CoviaError) return error;
2587
+ const message = error instanceof Error ? error.message : String(error);
2588
+ return new CoviaError(message);
2589
+ }
2590
+ function assertVenueIdentity(expectedDid, actualDid, baseUrl) {
2591
+ if (expectedDid && actualDid && expectedDid !== actualDid) {
2592
+ throw new VenueIdentityChangedError(expectedDid, actualDid, baseUrl);
2593
+ }
2594
+ }
2595
+ function connectionFailureMessage(venueId, attempts) {
2596
+ const detail = attempts.map(({ method, url, error }) => `${method} ${url}: ${error.message}`).join("; ");
2597
+ return `Could not connect to venue ${venueId}${detail ? `. Attempts: ${detail}` : ""}`;
2598
+ }
2552
2599
  var Venue = class _Venue {
2553
2600
  constructor(options = {}) {
2554
2601
  /** Connection-level private-jobs mode — see {@link setPrivate}. */
@@ -2619,20 +2666,26 @@ var Venue = class _Venue {
2619
2666
  * responded (the https candidate if an http fallback failed; the resolved
2620
2667
  * endpoint for a did:web id), and `venue.venueId` is the DID the venue
2621
2668
  * reported. The validated API root is `${venue.baseUrl}/api/v1`.
2669
+ * @throws {CoviaConnectionError} If no candidate can be validated.
2670
+ * @throws {VenueIdentityChangedError} If a known/resolved DID reports a different identity.
2622
2671
  */
2623
2672
  static async connect(venueId, auth) {
2624
2673
  if (venueId instanceof _Venue) {
2625
- return new _Venue({
2674
+ const connected = new _Venue({
2626
2675
  baseUrl: venueId.baseUrl,
2627
2676
  venueId: venueId.venueId,
2628
2677
  name: venueId.metadata.name,
2629
2678
  auth,
2630
2679
  status: venueId.lastKnownStatus
2631
2680
  });
2681
+ await connected.status();
2682
+ return connected;
2632
2683
  }
2633
2684
  if (typeof venueId === "string") {
2634
2685
  let candidates;
2686
+ let expectedDid;
2635
2687
  if (venueId.startsWith("did:web:")) {
2688
+ expectedDid = venueId;
2636
2689
  const didDoc = await resolver.resolve(venueId);
2637
2690
  if (!didDoc.didDocument) {
2638
2691
  throw new CoviaError("Invalid DID document");
@@ -2645,10 +2698,15 @@ var Venue = class _Venue {
2645
2698
  } else {
2646
2699
  candidates = venueBaseUrlCandidates(venueId);
2647
2700
  }
2648
- let lastError;
2701
+ const attempts = [];
2649
2702
  for (const baseUrl of candidates) {
2703
+ const statusUrl = baseUrl + "/api/v1/status";
2650
2704
  try {
2651
- const data = await fetchWithError(baseUrl + "/api/v1/status");
2705
+ const data = await fetchWithError(statusUrl);
2706
+ if (!data.did) {
2707
+ throw new CoviaError(`Venue status at ${statusUrl} did not include a DID`);
2708
+ }
2709
+ assertVenueIdentity(expectedDid, data.did, baseUrl);
2652
2710
  return new _Venue({
2653
2711
  baseUrl,
2654
2712
  venueId: data.did,
@@ -2657,19 +2715,30 @@ var Venue = class _Venue {
2657
2715
  status: data
2658
2716
  });
2659
2717
  } catch (error) {
2660
- if (error instanceof GridError && (error.statusCode === 401 || error.statusCode === 403)) {
2718
+ if (error instanceof VenueIdentityChangedError) throw error;
2719
+ const statusError = asCoviaError(error);
2720
+ attempts.push({ url: statusUrl, method: "GET", error: statusError });
2721
+ if (statusError instanceof GridError && (statusError.statusCode === 401 || statusError.statusCode === 403)) {
2722
+ const didDocumentUrl = baseUrl + "/.well-known/did.json";
2661
2723
  try {
2662
- const doc = await fetchWithError(baseUrl + "/.well-known/did.json");
2724
+ const doc = await fetchWithError(didDocumentUrl);
2663
2725
  if (doc?.id) {
2726
+ assertVenueIdentity(expectedDid, doc.id, baseUrl);
2664
2727
  return new _Venue({ baseUrl, venueId: doc.id, auth });
2665
2728
  }
2666
- } catch {
2729
+ throw new CoviaError(`DID document at ${didDocumentUrl} did not include an id`);
2730
+ } catch (fallbackError) {
2731
+ if (fallbackError instanceof VenueIdentityChangedError) throw fallbackError;
2732
+ attempts.push({ url: didDocumentUrl, method: "GET", error: asCoviaError(fallbackError) });
2667
2733
  }
2668
2734
  }
2669
- lastError = error;
2670
2735
  }
2671
2736
  }
2672
- throw lastError instanceof Error ? lastError : new CoviaError(`Could not connect to venue: ${venueId}`);
2737
+ throw new CoviaConnectionError(connectionFailureMessage(venueId, attempts), {
2738
+ candidates,
2739
+ attempts,
2740
+ cause: attempts.length > 0 ? attempts[attempts.length - 1].error : void 0
2741
+ });
2673
2742
  }
2674
2743
  throw new CoviaError("Invalid venue ID parameter. Must be a string (URL/DNS) or Venue instance.");
2675
2744
  }
@@ -2736,9 +2805,17 @@ var Venue = class _Venue {
2736
2805
  /**
2737
2806
  * Get venue status
2738
2807
  * @returns {Promise<StatusData>}
2808
+ * @throws {VenueIdentityChangedError} If this address reports a different known DID.
2739
2809
  */
2740
2810
  async status() {
2741
2811
  const data = await fetchWithError(`${this.baseUrl}/api/v1/status`);
2812
+ if (data.did) {
2813
+ if (this.venueId) {
2814
+ assertVenueIdentity(this.venueId, data.did, this.baseUrl);
2815
+ } else {
2816
+ this.venueId = data.did;
2817
+ }
2818
+ }
2742
2819
  this.lastKnownStatus = data;
2743
2820
  return data;
2744
2821
  }
@@ -2754,6 +2831,7 @@ var Venue = class _Venue {
2754
2831
  * @param options.pollIntervalMs - Delay between polls (default 1000).
2755
2832
  * @returns The ready {@link StatusData}.
2756
2833
  * @throws {CoviaTimeoutError} If the venue is not ready within the timeout.
2834
+ * @throws {VenueIdentityChangedError} Immediately if the venue's DID changed.
2757
2835
  */
2758
2836
  async waitUntilReady(options = {}) {
2759
2837
  const timeoutMs = options.timeoutMs ?? 6e4;
@@ -2763,7 +2841,8 @@ var Venue = class _Venue {
2763
2841
  try {
2764
2842
  const data = await this.status();
2765
2843
  if (data.status == null || data.status.toUpperCase() === "OK") return data;
2766
- } catch {
2844
+ } catch (error) {
2845
+ if (error instanceof VenueIdentityChangedError) throw error;
2767
2846
  }
2768
2847
  if (Date.now() - start >= timeoutMs) {
2769
2848
  throw new CoviaTimeoutError(`Venue ${this.baseUrl} not ready within ${timeoutMs}ms`);
@@ -2904,6 +2983,7 @@ exports.SecretManager = SecretManager;
2904
2983
  exports.UCANManager = UCANManager;
2905
2984
  exports.VENUE_RELAY = VENUE_RELAY;
2906
2985
  exports.Venue = Venue;
2986
+ exports.VenueIdentityChangedError = VenueIdentityChangedError;
2907
2987
  exports.WorkspaceManager = WorkspaceManager;
2908
2988
  exports.assetHash = assetHash;
2909
2989
  exports.createSSEEvent = createSSEEvent;
package/dist/index.mjs CHANGED
@@ -44,9 +44,23 @@ var GridError = class extends CoviaError {
44
44
  }
45
45
  };
46
46
  var CoviaConnectionError = class extends CoviaError {
47
- constructor(message) {
47
+ constructor(message, options = {}) {
48
48
  super(message);
49
49
  this.name = "CoviaConnectionError";
50
+ this.url = options.url ?? null;
51
+ this.method = options.method?.toUpperCase() ?? null;
52
+ this.cause = options.cause;
53
+ this.candidates = [...options.candidates ?? []];
54
+ this.attempts = [...options.attempts ?? []];
55
+ }
56
+ };
57
+ var VenueIdentityChangedError = class extends CoviaError {
58
+ constructor(oldDid, newDid, baseUrl) {
59
+ super(`Venue identity changed at ${baseUrl}: expected ${oldDid}, received ${newDid}`);
60
+ this.oldDid = oldDid;
61
+ this.newDid = newDid;
62
+ this.baseUrl = baseUrl;
63
+ this.name = "VenueIdentityChangedError";
50
64
  }
51
65
  };
52
66
  var CoviaTimeoutError = class extends CoviaError {
@@ -61,7 +75,8 @@ var JobFailedError = class extends CoviaError {
61
75
  const status = jobData.status ?? "unknown";
62
76
  let msg = `Job ${id} ${status}`;
63
77
  const output = jobData.output;
64
- const errText = output && typeof output === "object" && "error" in output ? output.error : void 0;
78
+ const outputErrText = output && typeof output === "object" && "error" in output ? output.error : void 0;
79
+ const errText = typeof jobData.error === "string" ? jobData.error : outputErrText;
65
80
  if (typeof errText === "string") {
66
81
  msg += `: ${errText}`;
67
82
  }
@@ -1306,13 +1321,14 @@ async function throwHttpError(response) {
1306
1321
  }
1307
1322
  throw new GridError(response.status, message, body);
1308
1323
  }
1309
- function wrapError(error) {
1310
- if (error instanceof CoviaError) return error;
1311
- const msg = error.message ?? String(error);
1312
- if (error instanceof TypeError) {
1313
- return new CoviaConnectionError(msg);
1314
- }
1315
- return new CoviaError(`Request failed: ${msg}`);
1324
+ function wrapConnectionError(error, url, method) {
1325
+ if (error instanceof CoviaConnectionError && error.url && error.method) return error;
1326
+ const detail = error instanceof Error ? error.message : String(error);
1327
+ return new CoviaConnectionError(`${method} ${url} failed: ${detail}`, {
1328
+ url,
1329
+ method,
1330
+ cause: error
1331
+ });
1316
1332
  }
1317
1333
  var RETRY_MAX_ATTEMPTS = 4;
1318
1334
  var RETRY_BASE_MS = 200;
@@ -1333,7 +1349,7 @@ function retryDelayMs(attempt, retryAfterMs, remainingBudgetMs, random) {
1333
1349
  }
1334
1350
  var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
1335
1351
  async function fetchWithError(url, options) {
1336
- const method = options?.method ?? "GET";
1352
+ const method = (options?.method ?? "GET").toUpperCase();
1337
1353
  const deadline = Date.now() + RETRY_BUDGET_MS;
1338
1354
  for (let attempt = 1; ; attempt++) {
1339
1355
  logger.debug(`${method} ${url}`);
@@ -1343,7 +1359,7 @@ async function fetchWithError(url, options) {
1343
1359
  } catch (error) {
1344
1360
  const msg = error.message ?? String(error);
1345
1361
  logger.debug(`Connection failed: ${method} ${url} \u2014 ${msg}`);
1346
- throw wrapError(error);
1362
+ throw wrapConnectionError(error, url, method);
1347
1363
  }
1348
1364
  logger.debug(`${method} ${url} \u2192 ${response.status}`);
1349
1365
  if (response.status === 429) {
@@ -1365,7 +1381,7 @@ async function fetchWithError(url, options) {
1365
1381
  }
1366
1382
  }
1367
1383
  async function fetchStreamWithError(url, options) {
1368
- const method = options?.method ?? "GET";
1384
+ const method = (options?.method ?? "GET").toUpperCase();
1369
1385
  logger.debug(`${method} ${url}`);
1370
1386
  let response;
1371
1387
  try {
@@ -1373,7 +1389,7 @@ async function fetchStreamWithError(url, options) {
1373
1389
  } catch (error) {
1374
1390
  const msg = error.message ?? String(error);
1375
1391
  logger.debug(`Connection failed: ${method} ${url} \u2014 ${msg}`);
1376
- throw wrapError(error);
1392
+ throw wrapConnectionError(error, url, method);
1377
1393
  }
1378
1394
  logger.debug(`${method} ${url} \u2192 ${response.status}`);
1379
1395
  if (!response.ok) {
@@ -1665,6 +1681,15 @@ var AgentManager = class {
1665
1681
  async chat(agentId, message, sessionId) {
1666
1682
  return this.venue.operations.run("v/ops/agent/chat", { agentId, message, sessionId });
1667
1683
  }
1684
+ /**
1685
+ * Set (or clear, by omitting `title` / passing an empty string) a
1686
+ * session's free-form human-facing title — persisted on the venue in
1687
+ * the session's own metadata, visible to every client and party in the
1688
+ * session (not a per-browser local override).
1689
+ */
1690
+ async renameSession(agentId, sessionId, title) {
1691
+ return this.venue.operations.run("v/ops/agent/rename-session", { agentId, sessionId, title });
1692
+ }
1668
1693
  async trigger(agentId) {
1669
1694
  return this.venue.operations.run("v/ops/agent/trigger", { agentId });
1670
1695
  }
@@ -2068,7 +2093,9 @@ var AssetManager = class {
2068
2093
  }
2069
2094
  }
2070
2095
  try {
2071
- const data = await fetchWithError(`${this.venue.baseUrl}/api/v1/assets/${assetId}`);
2096
+ const data = await fetchWithError(`${this.venue.baseUrl}/api/v1/assets/${assetId}`, {
2097
+ headers: this._buildHeaders(null)
2098
+ });
2072
2099
  if (hash) {
2073
2100
  cache.set(assetId, data);
2074
2101
  getAssetMetadataStore()?.put(normaliseHash(hash), data);
@@ -2097,7 +2124,9 @@ var AssetManager = class {
2097
2124
  if (options.limit !== void 0) {
2098
2125
  params.set("limit", String(options.limit));
2099
2126
  }
2100
- return fetchWithError(`${this.venue.baseUrl}/api/v1/assets?${params.toString()}`);
2127
+ return fetchWithError(`${this.venue.baseUrl}/api/v1/assets?${params.toString()}`, {
2128
+ headers: this._buildHeaders(null)
2129
+ });
2101
2130
  }
2102
2131
  /**
2103
2132
  * Register a new asset
@@ -2116,7 +2145,9 @@ var AssetManager = class {
2116
2145
  */
2117
2146
  async getMetadata(assetId) {
2118
2147
  try {
2119
- return await fetchWithError(`${this.venue.baseUrl}/api/v1/assets/${assetId}`);
2148
+ return await fetchWithError(`${this.venue.baseUrl}/api/v1/assets/${assetId}`, {
2149
+ headers: this._buildHeaders(null)
2150
+ });
2120
2151
  } catch (error) {
2121
2152
  if (error instanceof NotFoundError) {
2122
2153
  throw new AssetNotFoundError(assetId);
@@ -2150,7 +2181,9 @@ var AssetManager = class {
2150
2181
  */
2151
2182
  async getContent(assetId) {
2152
2183
  try {
2153
- const response = await fetchStreamWithError(`${this.venue.baseUrl}/api/v1/assets/${assetId}/content`);
2184
+ const response = await fetchStreamWithError(`${this.venue.baseUrl}/api/v1/assets/${assetId}/content`, {
2185
+ headers: this._buildHeaders(null)
2186
+ });
2154
2187
  return response.body;
2155
2188
  } catch (error) {
2156
2189
  if (error instanceof NotFoundError) {
@@ -2547,6 +2580,20 @@ function venueBaseUrlCandidates(venueId) {
2547
2580
  }
2548
2581
  return schemelessVenueCandidates(venueId);
2549
2582
  }
2583
+ function asCoviaError(error) {
2584
+ if (error instanceof CoviaError) return error;
2585
+ const message = error instanceof Error ? error.message : String(error);
2586
+ return new CoviaError(message);
2587
+ }
2588
+ function assertVenueIdentity(expectedDid, actualDid, baseUrl) {
2589
+ if (expectedDid && actualDid && expectedDid !== actualDid) {
2590
+ throw new VenueIdentityChangedError(expectedDid, actualDid, baseUrl);
2591
+ }
2592
+ }
2593
+ function connectionFailureMessage(venueId, attempts) {
2594
+ const detail = attempts.map(({ method, url, error }) => `${method} ${url}: ${error.message}`).join("; ");
2595
+ return `Could not connect to venue ${venueId}${detail ? `. Attempts: ${detail}` : ""}`;
2596
+ }
2550
2597
  var Venue = class _Venue {
2551
2598
  constructor(options = {}) {
2552
2599
  /** Connection-level private-jobs mode — see {@link setPrivate}. */
@@ -2617,20 +2664,26 @@ var Venue = class _Venue {
2617
2664
  * responded (the https candidate if an http fallback failed; the resolved
2618
2665
  * endpoint for a did:web id), and `venue.venueId` is the DID the venue
2619
2666
  * reported. The validated API root is `${venue.baseUrl}/api/v1`.
2667
+ * @throws {CoviaConnectionError} If no candidate can be validated.
2668
+ * @throws {VenueIdentityChangedError} If a known/resolved DID reports a different identity.
2620
2669
  */
2621
2670
  static async connect(venueId, auth) {
2622
2671
  if (venueId instanceof _Venue) {
2623
- return new _Venue({
2672
+ const connected = new _Venue({
2624
2673
  baseUrl: venueId.baseUrl,
2625
2674
  venueId: venueId.venueId,
2626
2675
  name: venueId.metadata.name,
2627
2676
  auth,
2628
2677
  status: venueId.lastKnownStatus
2629
2678
  });
2679
+ await connected.status();
2680
+ return connected;
2630
2681
  }
2631
2682
  if (typeof venueId === "string") {
2632
2683
  let candidates;
2684
+ let expectedDid;
2633
2685
  if (venueId.startsWith("did:web:")) {
2686
+ expectedDid = venueId;
2634
2687
  const didDoc = await resolver.resolve(venueId);
2635
2688
  if (!didDoc.didDocument) {
2636
2689
  throw new CoviaError("Invalid DID document");
@@ -2643,10 +2696,15 @@ var Venue = class _Venue {
2643
2696
  } else {
2644
2697
  candidates = venueBaseUrlCandidates(venueId);
2645
2698
  }
2646
- let lastError;
2699
+ const attempts = [];
2647
2700
  for (const baseUrl of candidates) {
2701
+ const statusUrl = baseUrl + "/api/v1/status";
2648
2702
  try {
2649
- const data = await fetchWithError(baseUrl + "/api/v1/status");
2703
+ const data = await fetchWithError(statusUrl);
2704
+ if (!data.did) {
2705
+ throw new CoviaError(`Venue status at ${statusUrl} did not include a DID`);
2706
+ }
2707
+ assertVenueIdentity(expectedDid, data.did, baseUrl);
2650
2708
  return new _Venue({
2651
2709
  baseUrl,
2652
2710
  venueId: data.did,
@@ -2655,19 +2713,30 @@ var Venue = class _Venue {
2655
2713
  status: data
2656
2714
  });
2657
2715
  } catch (error) {
2658
- if (error instanceof GridError && (error.statusCode === 401 || error.statusCode === 403)) {
2716
+ if (error instanceof VenueIdentityChangedError) throw error;
2717
+ const statusError = asCoviaError(error);
2718
+ attempts.push({ url: statusUrl, method: "GET", error: statusError });
2719
+ if (statusError instanceof GridError && (statusError.statusCode === 401 || statusError.statusCode === 403)) {
2720
+ const didDocumentUrl = baseUrl + "/.well-known/did.json";
2659
2721
  try {
2660
- const doc = await fetchWithError(baseUrl + "/.well-known/did.json");
2722
+ const doc = await fetchWithError(didDocumentUrl);
2661
2723
  if (doc?.id) {
2724
+ assertVenueIdentity(expectedDid, doc.id, baseUrl);
2662
2725
  return new _Venue({ baseUrl, venueId: doc.id, auth });
2663
2726
  }
2664
- } catch {
2727
+ throw new CoviaError(`DID document at ${didDocumentUrl} did not include an id`);
2728
+ } catch (fallbackError) {
2729
+ if (fallbackError instanceof VenueIdentityChangedError) throw fallbackError;
2730
+ attempts.push({ url: didDocumentUrl, method: "GET", error: asCoviaError(fallbackError) });
2665
2731
  }
2666
2732
  }
2667
- lastError = error;
2668
2733
  }
2669
2734
  }
2670
- throw lastError instanceof Error ? lastError : new CoviaError(`Could not connect to venue: ${venueId}`);
2735
+ throw new CoviaConnectionError(connectionFailureMessage(venueId, attempts), {
2736
+ candidates,
2737
+ attempts,
2738
+ cause: attempts.length > 0 ? attempts[attempts.length - 1].error : void 0
2739
+ });
2671
2740
  }
2672
2741
  throw new CoviaError("Invalid venue ID parameter. Must be a string (URL/DNS) or Venue instance.");
2673
2742
  }
@@ -2734,9 +2803,17 @@ var Venue = class _Venue {
2734
2803
  /**
2735
2804
  * Get venue status
2736
2805
  * @returns {Promise<StatusData>}
2806
+ * @throws {VenueIdentityChangedError} If this address reports a different known DID.
2737
2807
  */
2738
2808
  async status() {
2739
2809
  const data = await fetchWithError(`${this.baseUrl}/api/v1/status`);
2810
+ if (data.did) {
2811
+ if (this.venueId) {
2812
+ assertVenueIdentity(this.venueId, data.did, this.baseUrl);
2813
+ } else {
2814
+ this.venueId = data.did;
2815
+ }
2816
+ }
2740
2817
  this.lastKnownStatus = data;
2741
2818
  return data;
2742
2819
  }
@@ -2752,6 +2829,7 @@ var Venue = class _Venue {
2752
2829
  * @param options.pollIntervalMs - Delay between polls (default 1000).
2753
2830
  * @returns The ready {@link StatusData}.
2754
2831
  * @throws {CoviaTimeoutError} If the venue is not ready within the timeout.
2832
+ * @throws {VenueIdentityChangedError} Immediately if the venue's DID changed.
2755
2833
  */
2756
2834
  async waitUntilReady(options = {}) {
2757
2835
  const timeoutMs = options.timeoutMs ?? 6e4;
@@ -2761,7 +2839,8 @@ var Venue = class _Venue {
2761
2839
  try {
2762
2840
  const data = await this.status();
2763
2841
  if (data.status == null || data.status.toUpperCase() === "OK") return data;
2764
- } catch {
2842
+ } catch (error) {
2843
+ if (error instanceof VenueIdentityChangedError) throw error;
2765
2844
  }
2766
2845
  if (Date.now() - start >= timeoutMs) {
2767
2846
  throw new CoviaTimeoutError(`Venue ${this.baseUrl} not ready within ${timeoutMs}ms`);
@@ -2866,4 +2945,4 @@ function relayDelegation(privateKey, venueDID, lifetimeSeconds, caps = []) {
2866
2945
  (*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) *)
2867
2946
  */
2868
2947
 
2869
- export { AdapterManager, Agent, AgentManager, AgentStatus, Asset, AssetManager, AssetNotFoundError, Auth, BasicAuth, BearerAuth, ChatSession, CoviaConnectionError, CoviaError, CoviaTimeoutError, CredentialsHTTP, DataAsset, Ed25519Auth, Grid, GridError, Job, JobFailedError, JobManager, JobNotFoundError, JobStatus, KeyPairAuth, Namespace, NoAuth, NotFoundError, Operation, OperationManager, RateLimitError, RunStatus, SecretManager, UCANManager, VENUE_RELAY, Venue, WorkspaceManager, assetHash, createSSEEvent, createUCANJWT, decodePublicKey, didFor, didFromPublicKey, didMethod, didUrl, encodePublicKey, fetchStreamWithError, fetchWithError, generateKeyPair, getAssetIdFromPath, getAssetIdFromVenueId, getAssetMetadataStore, getParsedAssetId, grant, hexToPrivateKey, identityToken, isDid, isJobComplete, isJobFinished, isJobPaused, logger, parseDidUrl, parseRetryAfterMs, parseSSEStream, privateKeyToHex, relayDelegation, retryDelayMs, setAssetMetadataStore, venueBaseUrlCandidates };
2948
+ export { AdapterManager, Agent, AgentManager, AgentStatus, Asset, AssetManager, AssetNotFoundError, Auth, BasicAuth, BearerAuth, ChatSession, CoviaConnectionError, CoviaError, CoviaTimeoutError, CredentialsHTTP, DataAsset, Ed25519Auth, Grid, GridError, Job, JobFailedError, JobManager, JobNotFoundError, JobStatus, KeyPairAuth, Namespace, NoAuth, NotFoundError, Operation, OperationManager, RateLimitError, RunStatus, SecretManager, UCANManager, VENUE_RELAY, Venue, VenueIdentityChangedError, WorkspaceManager, assetHash, createSSEEvent, createUCANJWT, decodePublicKey, didFor, didFromPublicKey, didMethod, didUrl, encodePublicKey, fetchStreamWithError, fetchWithError, generateKeyPair, getAssetIdFromPath, getAssetIdFromVenueId, getAssetMetadataStore, getParsedAssetId, grant, hexToPrivateKey, identityToken, isDid, isJobComplete, isJobFinished, isJobPaused, logger, parseDidUrl, parseRetryAfterMs, parseSSEStream, privateKeyToHex, relayDelegation, retryDelayMs, setAssetMetadataStore, venueBaseUrlCandidates };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@covia/covia-sdk",
3
- "version": "1.7.2",
3
+ "version": "1.7.4",
4
4
  "description": "Typescript library for covia-ai",
5
5
  "packageManager": "pnpm@11.9.0",
6
6
  "main": "./dist/index.js",