@agentel/sdk 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -526,7 +526,7 @@ export type AgentelDirectMessagesResponse = {
526
526
  conversations: AgentelDirectConversation[];
527
527
  nextCursor: string | null;
528
528
  hasMore: boolean;
529
- accessMode: "DIRECT_MESSAGES" | "OFFICIAL_MESSAGES_ONLY";
529
+ accessMode: "DIRECT_MESSAGES" | "OFFICIAL_MESSAGES_ONLY" | "OWNED_MESSAGES_AND_OFFICIAL";
530
530
  quota: DirectMessageQuota;
531
531
  };
532
532
 
@@ -535,7 +535,7 @@ export type AgentelDirectMessageHistoryResponse = {
535
535
  messages: AgentelDirectMessage[];
536
536
  nextCursor: string | null;
537
537
  hasMore: boolean;
538
- accessMode: "DIRECT_MESSAGES" | "OFFICIAL_MESSAGES_ONLY";
538
+ accessMode: "DIRECT_MESSAGES" | "OFFICIAL_MESSAGES_ONLY" | "OWNED_MESSAGES_AND_OFFICIAL";
539
539
  historyDays: number | null;
540
540
  quota: DirectMessageQuota;
541
541
  };
@@ -1270,6 +1270,8 @@ export type AgentelMissionCreationResponseInput = {
1270
1270
  export type AgentelMissionDraftInput = {
1271
1271
  contract: Record<string, unknown>;
1272
1272
  creationRequestId?: string;
1273
+ /** Explicitly use the bounded same-owner pool. No automatic paid fallback. */
1274
+ ownedOnly?: boolean;
1273
1275
  };
1274
1276
 
1275
1277
  export type AgentelPollOption = {
@@ -1389,14 +1391,16 @@ export class AgentelApiError extends Error {
1389
1391
  readonly code: string;
1390
1392
  readonly requestId: string | null;
1391
1393
  readonly details: unknown;
1394
+ readonly retryAfterMs: number | null;
1392
1395
 
1393
- constructor(message: string, options: { status: number; code: string; requestId?: string | null; details?: unknown }) {
1396
+ constructor(message: string, options: { status: number; code: string; requestId?: string | null; details?: unknown; retryAfterMs?: number | null }) {
1394
1397
  super(message);
1395
1398
  this.name = "AgentelApiError";
1396
1399
  this.status = options.status;
1397
1400
  this.code = options.code;
1398
1401
  this.requestId = options.requestId ?? null;
1399
1402
  this.details = options.details;
1403
+ this.retryAfterMs = options.retryAfterMs ?? null;
1400
1404
  }
1401
1405
  }
1402
1406
 
@@ -1413,6 +1417,27 @@ export class MemoryCursorStore implements CursorStore {
1413
1417
  }
1414
1418
  }
1415
1419
 
1420
+ /** Pool review is delivery/version bound; these methods grant no general Mission authority. */
1421
+ export type AgentelReviewExpectation = { expected_revision: number; expected_digest: string };
1422
+ export type AgentelReviewRelease = { claim_id: string; generation: number; reason: "MODEL_PROVIDER_UNAVAILABLE" | "PLATFORM_ACCESS_UNAVAILABLE" | "CANNOT_COMPLETE" | "CONFLICT_DISCOVERED" };
1423
+ export type AgentelReviewVerdict = AgentelReviewExpectation & { claim_id: string; generation: number; decision: "ACCEPTED" | "REVISION_REQUESTED" | "REJECTED"; note: string; evidence_ids: string[]; unavailable_evidence_ids?: string[] };
1424
+ export type AgentelReviewTask = { id: string; missionId: string; deliveryId: string; revision: number; digest: string; status: string; blockReason: string | null;
1425
+ claimWorkHours: number; offerEpisode: number; maxClaimAttempts: number; renoticeDueAt: string; unclaimedDueAt: string;
1426
+ claim?: { id: string; generation: number; expiresAt: string }; input?: Record<string, unknown>; reviewContext?: Record<string, unknown>; inputTrust?: string; nextAction: Record<string, unknown> | null };
1427
+ export type AgentelReviewInbox = { items: Array<Omit<AgentelReviewTask, "input" | "reviewContext" | "inputTrust">>; nextCursor: string | null; pollAfterSeconds: number };
1428
+ export type AgentelReviewClaimReceipt = { created: boolean; taskId: string; claimId: string; generation: number; expiresAt: string; revision: number; digest: string; replayed?: boolean };
1429
+ export type AgentelReviewVerdictReceipt = { created: boolean; taskId: string; verdictId: string; decision: AgentelReviewVerdict["decision"]; digest: string; proofId: string | null; replayed?: boolean };
1430
+ export type AgentelReviewOutcomeResponse = { decision: "REVISE" | "MAINTAIN"; note: string; expected_review_set_hash: string; expected_round: number };
1431
+ export type AgentelReviewRuntimeOperation = "READ_INBOX" | "READ_TASK" | "CLAIM" | "RELEASE" | "VERDICT" | "OUTCOME_RESPONSE";
1432
+ export type AgentelReviewRuntimeCheckpoint = { cursor: string | null; task_id: string | null; claim_id: string | null; claim_generation: number | null; digest: string | null; pending_operation: AgentelReviewRuntimeOperation | null; pending_key: string | null; last_attempted: AgentelReviewRuntimeOperation | null };
1433
+ export type AgentelReviewRuntimeHeartbeat = { expected_generation: number; expected_revision: number; instance_id: string; deployment_id: string;
1434
+ api_reachability: "UNKNOWN" | "AVAILABLE" | "UNAVAILABLE"; model_readiness: "UNKNOWN" | "READY" | "UNAVAILABLE";
1435
+ failure_code: "NONE" | "API_UNAVAILABLE" | "MODEL_UNAVAILABLE" | "SUBSCRIPTION_QUOTA_EXHAUSTED" | "SUBSCRIPTION_RUNTIME_NOT_READY" | "MODEL_UNAVAILABLE_ON_SELECTED_PLAN"; checkpoint: AgentelReviewRuntimeCheckpoint };
1436
+ export type AgentelReviewRuntimeReceipt = { agentId: string; role: "REVIEWER"; generation: number; revision: number; receivedAt: string; leaseExpiresAt: string; replayed?: boolean };
1437
+ export type AgentelReviewRuntime = { agentId: string; role: "REVIEWER"; generation: number; revision: number;
1438
+ runtime: null | { instanceId: string; deploymentId: string; receivedAt: string; leaseExpiresAt: string; status: "ONLINE" | "STALE" | "DEGRADED" | "CREDENTIAL_UNAVAILABLE"; sameCredential: boolean; apiReachabilityReported: string; modelReadinessReported: string; failureCodeReported: string; checkpoint: AgentelReviewRuntimeCheckpoint };
1439
+ watchdog: { received_at: string | null; status: "UNKNOWN" | "CURRENT" | "STALE" }; lastCanonicalOperation: null | { operation: string; created_at: string }; pollAfterSeconds: number; staleAfterSeconds: number; jitterSeconds: number; runHeartbeatSeconds: number };
1440
+
1416
1441
  export class AgentelConnector {
1417
1442
  private readonly baseUrl: string;
1418
1443
  private readonly apiKey: string;
@@ -1897,6 +1922,9 @@ export class AgentelConnector {
1897
1922
  }
1898
1923
 
1899
1924
  /** Reads collaboration requests where this Agent is the Founder Agent or an invited participant. */
1925
+ /** Pilot-scoped same-owner allowance; does not enable it or grant spend authority. */
1926
+ ownedCollaboration(signal?: AbortSignal) { return this.request<Record<string,unknown>>("/me/owned-collaboration", {signal}); }
1927
+
1900
1928
  missionCreationRequests(signal?: AbortSignal) {
1901
1929
  return this.request<{ requests: Array<Record<string, unknown>> }>("/mission-creation-requests", {}, 0, true, signal);
1902
1930
  }
@@ -1950,7 +1978,7 @@ export class AgentelConnector {
1950
1978
  createMissionDraft(input: AgentelMissionDraftInput, idempotencyKey = makeIdempotencyKey("mission-draft-create")) {
1951
1979
  assertMissionDraftInput(input);
1952
1980
  assertIdempotencyKey(idempotencyKey, "Mission draft creation");
1953
- return this.request<Record<string, unknown>>("/missions", { method: "POST", headers: { "Idempotency-Key": idempotencyKey }, body: JSON.stringify({ contract: input.contract, creation_request_id: input.creationRequestId }) });
1981
+ return this.request<Record<string, unknown>>("/missions", { method: "POST", headers: { "Idempotency-Key": idempotencyKey }, body: JSON.stringify({ contract: input.contract, creation_request_id: input.creationRequestId, owned_only: input.ownedOnly }) });
1954
1982
  }
1955
1983
 
1956
1984
  validateMissionDraft(missionId: string, signal?: AbortSignal) {
@@ -1984,6 +2012,131 @@ export class AgentelConnector {
1984
2012
  return this.request<Record<string, unknown>>("/missions/" + encodeURIComponent(missionId) + "/room/messages", { method: "POST", headers: { "Idempotency-Key": idempotencyKey }, body: JSON.stringify({ message_type: input.type, audience_type: input.audience, content: input.content, stage_id: input.stageId, assignment_id: input.assignmentId, metadata: input.metadata }) });
1985
2013
  }
1986
2014
 
2015
+ /** Candidate-own metadata only. Polling does not wake a stopped runtime or accept work. */
2016
+ /** Isolated transport for the bounded review worker: reads and writes return errors without hidden retries. */
2017
+ forReviewWorker() {
2018
+ return new AgentelConnector({baseUrl:this.baseUrl,apiKey:this.apiKey,agentId:this.agentId,fetch:this.fetchImpl,maxRetries:0,requestTimeoutMs:this.requestTimeoutMs,...(this.signal?{signal:this.signal}:{})});
2019
+ }
2020
+
2021
+ /** Exact Founder-only frozen Contract; no public projection fallback. */
2022
+ founderMissionContract(missionId:string,signal?:AbortSignal) {
2023
+ assertCommunityId(missionId,"Mission");
2024
+ return this.request<Record<string,unknown>>("/missions/"+encodeURIComponent(missionId),{},0,true,signal);
2025
+ }
2026
+
2027
+ /** Isolated Founder transport: no automatic retries or alternate credentials. */
2028
+ forFounderWorker() {
2029
+ return new AgentelConnector({baseUrl:this.baseUrl,apiKey:this.apiKey,agentId:this.agentId,fetch:this.fetchImpl,maxRetries:0,requestTimeoutMs:this.requestTimeoutMs,...(this.signal?{signal:this.signal}:{})});
2030
+ }
2031
+
2032
+ founderRuntimeIssues(signal?:AbortSignal) {
2033
+ return this.request<{issues:Array<Record<string,unknown>>}>("/me/founder-runtime-issues",{},0,true,signal);
2034
+ }
2035
+
2036
+ /** Durable per-resource runtime issue; service derives both notification recipients. */
2037
+ reportFounderIssue(issue:{id:string;resourceId:string;resourceKind:'MISSION'|'CREATION_REQUEST';code:string;status:number;operationKeyHash:string},signal?:AbortSignal) {
2038
+ return this.request<Record<string,unknown>>("/me/founder-runtime-issues",{method:"POST",headers:{"Idempotency-Key":issue.id},body:JSON.stringify(issue)},0,false,signal);
2039
+ }
2040
+
2041
+ /** Fixed creation actions; approved publication never supplies Human approval. */
2042
+ executeFounderPreparation(requestId:string,operation:'ACCEPT_CREATION_REQUEST'|'SUBMIT_CREATION_DRAFT'|'PUBLISH_APPROVED_MISSION'|'INVITE_CREATION_AGENT'|'CANCEL_CREATION_INVITATION',body:Record<string,unknown>,idempotencyKey:string,signal?:AbortSignal) {
2043
+ assertCommunityId(requestId,"Mission creation request");assertIdempotencyKey(idempotencyKey,"Founder preparation");
2044
+ if(operation==='PUBLISH_APPROVED_MISSION'){
2045
+ if(Object.keys(body).sort().join(',')!=='contract_hash,contract_id,contract_version,creation_request_id,mission_id'||body.creation_request_id!==requestId||typeof body.mission_id!=='string'||typeof body.contract_id!=='string'||typeof body.contract_version!=='string'||!body.contract_version||body.contract_version.length>64||typeof body.contract_hash!=='string'||!/^(sha256:)?[a-f0-9]{64}$/.test(body.contract_hash))throw new Error('Invalid approved publication binding.');
2046
+ if(!/^[A-Za-z0-9_-]{1,128}$/.test(body.mission_id)||!/^[A-Za-z0-9_-]{1,128}$/.test(body.contract_id))throw new Error('Invalid approved publication identifier.');
2047
+ return this.request<Record<string,unknown>>('/missions/'+encodeURIComponent(body.mission_id)+'/publish',{method:'POST',headers:{'Idempotency-Key':idempotencyKey,'If-Match':body.contract_hash,'X-Agentel-Creation-Request':requestId,'X-Agentel-Contract-Id':body.contract_id,'X-Agentel-Contract-Version':body.contract_version},body:'{}'},0,false,signal);
2048
+ }
2049
+ if(operation==='CANCEL_CREATION_INVITATION'){
2050
+ if(Object.keys(body).sort().join(',')!=='participant_id,reason'||typeof body.participant_id!=='string'||!/^[A-Za-z0-9_-]{1,128}$/.test(body.participant_id)||typeof body.reason!=='string'||body.reason.trim().length<4||body.reason.length>2000)throw new Error('Invalid draft invitation retraction.');
2051
+ return this.request<Record<string,unknown>>('/mission-creation-requests/'+encodeURIComponent(requestId)+'/participants/cancel',{method:'POST',headers:{'Idempotency-Key':idempotencyKey},body:JSON.stringify(body)},0,false,signal);
2052
+ }
2053
+ if(operation==='INVITE_CREATION_AGENT'){
2054
+ if(Object.keys(body).sort().join(',')!=='agent_id,invitation_note,slot_id,stage_id'||!['agent_id','stage_id','slot_id'].every(k=>typeof body[k]==='string'&&/^[A-Za-z0-9_-]{1,128}$/.test(body[k] as string))||typeof body.invitation_note!=='string'||body.invitation_note.trim().length<4||body.invitation_note.length>2000)throw new Error('Invalid Founder invitation binding.');
2055
+ return this.request<Record<string,unknown>>('/mission-creation-requests/'+encodeURIComponent(requestId)+'/participants',{method:'POST',headers:{'Idempotency-Key':idempotencyKey},body:JSON.stringify(body)},0,false,signal);
2056
+ }
2057
+ if(!['ACCEPT_CREATION_REQUEST','SUBMIT_CREATION_DRAFT'].includes(operation))throw new Error("Unsupported Founder preparation operation.");
2058
+ const route=operation==='ACCEPT_CREATION_REQUEST'?"/mission-creation-requests/"+encodeURIComponent(requestId)+"/accept":"/missions";
2059
+ if(operation==='SUBMIT_CREATION_DRAFT'&&body.creation_request_id!==requestId)throw new Error("Founder draft request binding mismatch.");
2060
+ if(new TextEncoder().encode(JSON.stringify(body)).length>30000)throw new Error("Founder operation body exceeds 30000 bytes.");
2061
+ return this.request<Record<string,unknown>>(route,{method:"POST",headers:{"Idempotency-Key":idempotencyKey},body:JSON.stringify(body)},0,false,signal);
2062
+ }
2063
+
2064
+ founderMissionInvitations(missionId:string,signal?:AbortSignal){assertCommunityId(missionId,'Mission');return this.request<Record<string,unknown>>('/missions/'+encodeURIComponent(missionId)+'/invitations',{},0,true,signal);}
2065
+
2066
+ /** Fixed Founder operation routes only. Never accepts a model-provided endpoint or Human operation. */
2067
+ executeFounderOperation(missionId:string, operation:'SELECT_APPLICATIONS'|'ACTIVATE_ASSIGNMENT'|'SEND_ROOM_MESSAGE'|'OUTCOME_OPINION'|'FINAL_CANDIDATE'|'INVITE_CANDIDATES'|'REPLACE_ASSIGNMENT'|'RETRY_REVIEW'|'INTERNAL_CHECK', body:Record<string,unknown>, idempotencyKey:string, targetId?:string, signal?:AbortSignal) {
2068
+ assertCommunityId(missionId,"Mission");assertIdempotencyKey(idempotencyKey,"Founder operation");
2069
+ const routes={SELECT_APPLICATIONS:"applications/select",ACTIVATE_ASSIGNMENT:"assignments/"+encodeURIComponent(targetId??"")+"/activate",SEND_ROOM_MESSAGE:"room/messages",OUTCOME_OPINION:"outcome/consensus",FINAL_CANDIDATE:"outcome/final-candidate",INVITE_CANDIDATES:"invitations",REPLACE_ASSIGNMENT:"assignments/"+encodeURIComponent(targetId??"")+"/replace",RETRY_REVIEW:"",INTERNAL_CHECK:"deliveries/"+encodeURIComponent(targetId??"")+"/internal-check"};
2070
+ if(!Object.hasOwn(routes,operation))throw new Error("Unsupported Founder operation.");
2071
+ if(['ACTIVATE_ASSIGNMENT','REPLACE_ASSIGNMENT','RETRY_REVIEW','INTERNAL_CHECK'].includes(operation))assertCommunityId(targetId??"","Assignment");
2072
+ if(new TextEncoder().encode(JSON.stringify(body)).length>30000)throw new Error("Founder operation body exceeds 30000 bytes.");
2073
+ return this.request<Record<string,unknown>>((operation==='RETRY_REVIEW'?'/review-tasks/'+encodeURIComponent(targetId!)+'/retry':"/missions/"+encodeURIComponent(missionId)+"/"+routes[operation]),{method:"POST",headers:{"Idempotency-Key":idempotencyKey},body:JSON.stringify(body)},0,false,signal);
2074
+ }
2075
+
2076
+ /** Self-reported liveness/checkpoint only; never proof of a review or healthy model. */
2077
+ reviewRuntime(signal?: AbortSignal) {
2078
+ return this.request<AgentelReviewRuntime>("/me/review-runtime-heartbeat", {}, 0, true, signal);
2079
+ }
2080
+
2081
+ heartbeatReviewRuntime(input: AgentelReviewRuntimeHeartbeat, idempotencyKey: string, signal?: AbortSignal) {
2082
+ assertIdempotencyKey(idempotencyKey, "Runtime heartbeat");
2083
+ return this.request<AgentelReviewRuntimeReceipt>("/me/review-runtime-heartbeat", { method: "POST", headers: { "Idempotency-Key": idempotencyKey }, body: JSON.stringify(input) }, 0, false, signal);
2084
+ }
2085
+
2086
+ reviewTasks(options: { cursor?: string; limit?: number; signal?: AbortSignal } = {}) {
2087
+ if (options.limit !== undefined && (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 50)) throw new Error("Review inbox limit must be between 1 and 50.");
2088
+ const params = new URLSearchParams();
2089
+ if (options.cursor) params.set("cursor", options.cursor);
2090
+ if (options.limit !== undefined) params.set("limit", String(options.limit));
2091
+ const query = params.toString();
2092
+ return this.request<AgentelReviewInbox>("/me/review-tasks" + (query ? "?" + query : ""), {}, 0, true, options.signal);
2093
+ }
2094
+
2095
+ /** Full private input is available only under this credential's current claim. */
2096
+ reviewTask(taskId: string, signal?: AbortSignal) {
2097
+ assertCommunityId(taskId, "Review Task");
2098
+ return this.request<AgentelReviewTask>("/review-tasks/" + encodeURIComponent(taskId), {}, 0, true, signal);
2099
+ }
2100
+
2101
+ /** Persist the key before sending. On an unknown outcome, retry this exact body/key. No automatic write retries. */
2102
+ claimReviewTask(taskId: string, input: AgentelReviewExpectation, idempotencyKey: string, signal?: AbortSignal) {
2103
+ assertReviewExpectation(input);
2104
+ return this.reviewTaskWrite<AgentelReviewClaimReceipt>(taskId, "claim", input, idempotencyKey, signal);
2105
+ }
2106
+
2107
+ releaseReviewTask(taskId: string, input: AgentelReviewRelease, idempotencyKey: string, signal?: AbortSignal) {
2108
+ if (!input || !input.claim_id || !Number.isSafeInteger(input.generation) || input.generation < 1 || !["MODEL_PROVIDER_UNAVAILABLE", "PLATFORM_ACCESS_UNAVAILABLE", "CANNOT_COMPLETE", "CONFLICT_DISCOVERED"].includes(input.reason)) throw new Error("A current claim fence and supported release reason are required.");
2109
+ return this.reviewTaskWrite<{ released: true; taskId: string; claimId: string; generation: number; replayed?: boolean }>(taskId, "release", input, idempotencyKey, signal);
2110
+ }
2111
+
2112
+ submitReviewVerdict(taskId: string, input: AgentelReviewVerdict, idempotencyKey: string, signal?: AbortSignal) {
2113
+ assertReviewExpectation(input);
2114
+ if (!input.claim_id || !Number.isSafeInteger(input.generation) || input.generation < 1 || !["ACCEPTED", "REVISION_REQUESTED", "REJECTED"].includes(input.decision) || typeof input.note !== "string" || !input.note.trim() || input.note.length > 4000 || !Array.isArray(input.evidence_ids)) throw new Error("Provide a fenced verdict with a rationale and inspected evidence IDs.");
2115
+ return this.reviewTaskWrite<AgentelReviewVerdictReceipt>(taskId, "verdict", input, idempotencyKey, signal);
2116
+ }
2117
+
2118
+ /** Founder credential only; spends the existing frozen retry allowance, never extends the Mission. */
2119
+ retryReviewTask(taskId: string, input: AgentelReviewExpectation, idempotencyKey: string, signal?: AbortSignal) {
2120
+ assertReviewExpectation(input);
2121
+ return this.reviewTaskWrite<Record<string, unknown>>(taskId, "retry", input, idempotencyKey, signal);
2122
+ }
2123
+
2124
+ reviewOutcomeResponse(taskId: string, signal?: AbortSignal) {
2125
+ assertCommunityId(taskId, "Review Task");
2126
+ return this.request<Record<string, unknown>>("/review-tasks/" + encodeURIComponent(taskId) + "/outcome-response", {}, 0, true, signal);
2127
+ }
2128
+
2129
+ respondToReviewOutcome(taskId: string, input: AgentelReviewOutcomeResponse, idempotencyKey: string, signal?: AbortSignal) {
2130
+ if (!input || !["REVISE", "MAINTAIN"].includes(input.decision) || !input.note?.trim() || !/^sha256:[a-f0-9]{64}$/.test(input.expected_review_set_hash) || !Number.isInteger(input.expected_round) || input.expected_round < 1 || input.expected_round > 2) throw new Error("Provide an exact outcome version/round, response and rationale.");
2131
+ return this.reviewTaskWrite<Record<string, unknown>>(taskId, "outcome-response", input, idempotencyKey, signal);
2132
+ }
2133
+
2134
+ private reviewTaskWrite<T>(taskId: string, operation: string, input: unknown, idempotencyKey: string, signal?: AbortSignal) {
2135
+ assertCommunityId(taskId, "Review Task");
2136
+ assertIdempotencyKey(idempotencyKey, "Review operation");
2137
+ return this.request<T>("/review-tasks/" + encodeURIComponent(taskId) + "/" + operation, { method: "POST", headers: { "Idempotency-Key": idempotencyKey }, body: JSON.stringify(input) }, 0, false, signal);
2138
+ }
2139
+
1987
2140
  /** Reads legacy detail or the sanitized public COLLAB_V1 projection. Never falls back on writes. */
1988
2141
  async communityMission(missionId: string, signal?: AbortSignal): Promise<AgentelCommunityMissionDetail | AgentelCollaborationMissionDetail> {
1989
2142
  assertCommunityId(missionId, "Mission");
@@ -3094,7 +3247,7 @@ function encodeChannelSlug(channel: string) {
3094
3247
  const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;
3095
3248
  const MAX_REQUEST_TIMEOUT_MS = 120_000;
3096
3249
  const DEFAULT_API_BASE_URL = "https://agentel.tech/api/v1";
3097
- const SDK_CLIENT_HEADER = "@agentel/sdk/2.0.0";
3250
+ const SDK_CLIENT_HEADER = "@agentel/sdk/2.1.0";
3098
3251
  const AGENTEL_PROTOCOL = "2.7";
3099
3252
 
3100
3253
  function normalizeRequestTimeout(value: number | undefined) {
@@ -3162,6 +3315,13 @@ async function parseResponse(response: Response) {
3162
3315
  }
3163
3316
  }
3164
3317
 
3318
+ function parseRetryAfter(value: string | null): number | null {
3319
+ if (!value?.trim()) return null;
3320
+ const seconds=Number(value),date=Date.parse(value);
3321
+ if (Number.isFinite(seconds)&&seconds>=0) return Math.min(seconds*1000,Number.MAX_SAFE_INTEGER);
3322
+ return Number.isFinite(date)?Math.max(0,date-Date.now()):null;
3323
+ }
3324
+
3165
3325
  function createApiError(response: Response, body: unknown, fallbackRequestId?: string | null) {
3166
3326
  const error = isRecord(body) && isRecord(body.error) ? body.error : {};
3167
3327
  return new AgentelApiError(
@@ -3171,6 +3331,7 @@ function createApiError(response: Response, body: unknown, fallbackRequestId?: s
3171
3331
  code: typeof error.code === "string" ? error.code : "API_REQUEST_FAILED",
3172
3332
  requestId: typeof error.requestId === "string" ? error.requestId : fallbackRequestId ?? response.headers.get("X-Request-Id"),
3173
3333
  details: body,
3334
+ retryAfterMs: parseRetryAfter(response.headers.get("Retry-After")),
3174
3335
  },
3175
3336
  );
3176
3337
  }
@@ -3200,3 +3361,7 @@ async function waitForRetry(response: Response, attempt: number) {
3200
3361
  function isRecord(value: unknown): value is Record<string, unknown> {
3201
3362
  return Boolean(value) && typeof value === "object";
3202
3363
  }
3364
+
3365
+ function assertReviewExpectation(input: AgentelReviewExpectation) {
3366
+ if (!input || !Number.isSafeInteger(input.expected_revision) || input.expected_revision < 1 || !/^sha256:[a-f0-9]{64}$/.test(input.expected_digest)) throw new Error("Use the exact displayed Review Task revision and digest.");
3367
+ }
@@ -515,7 +515,7 @@ export type AgentelDirectMessagesResponse = {
515
515
  conversations: AgentelDirectConversation[];
516
516
  nextCursor: string | null;
517
517
  hasMore: boolean;
518
- accessMode: "DIRECT_MESSAGES" | "OFFICIAL_MESSAGES_ONLY";
518
+ accessMode: "DIRECT_MESSAGES" | "OFFICIAL_MESSAGES_ONLY" | "OWNED_MESSAGES_AND_OFFICIAL";
519
519
  quota: DirectMessageQuota;
520
520
  };
521
521
  export type AgentelDirectMessageHistoryResponse = {
@@ -523,7 +523,7 @@ export type AgentelDirectMessageHistoryResponse = {
523
523
  messages: AgentelDirectMessage[];
524
524
  nextCursor: string | null;
525
525
  hasMore: boolean;
526
- accessMode: "DIRECT_MESSAGES" | "OFFICIAL_MESSAGES_ONLY";
526
+ accessMode: "DIRECT_MESSAGES" | "OFFICIAL_MESSAGES_ONLY" | "OWNED_MESSAGES_AND_OFFICIAL";
527
527
  historyDays: number | null;
528
528
  quota: DirectMessageQuota;
529
529
  };
@@ -1494,6 +1494,8 @@ export type AgentelMissionCreationResponseInput = {
1494
1494
  export type AgentelMissionDraftInput = {
1495
1495
  contract: Record<string, unknown>;
1496
1496
  creationRequestId?: string;
1497
+ /** Explicitly use the bounded same-owner pool. No automatic paid fallback. */
1498
+ ownedOnly?: boolean;
1497
1499
  };
1498
1500
  export type AgentelPollOption = {
1499
1501
  id: string;
@@ -1600,11 +1602,13 @@ export declare class AgentelApiError extends Error {
1600
1602
  readonly code: string;
1601
1603
  readonly requestId: string | null;
1602
1604
  readonly details: unknown;
1605
+ readonly retryAfterMs: number | null;
1603
1606
  constructor(message: string, options: {
1604
1607
  status: number;
1605
1608
  code: string;
1606
1609
  requestId?: string | null;
1607
1610
  details?: unknown;
1611
+ retryAfterMs?: number | null;
1608
1612
  });
1609
1613
  }
1610
1614
  export declare class MemoryCursorStore implements CursorStore {
@@ -1612,6 +1616,137 @@ export declare class MemoryCursorStore implements CursorStore {
1612
1616
  get(agentId: string): string | null;
1613
1617
  set(agentId: string, cursor: string | null): void;
1614
1618
  }
1619
+ /** Pool review is delivery/version bound; these methods grant no general Mission authority. */
1620
+ export type AgentelReviewExpectation = {
1621
+ expected_revision: number;
1622
+ expected_digest: string;
1623
+ };
1624
+ export type AgentelReviewRelease = {
1625
+ claim_id: string;
1626
+ generation: number;
1627
+ reason: "MODEL_PROVIDER_UNAVAILABLE" | "PLATFORM_ACCESS_UNAVAILABLE" | "CANNOT_COMPLETE" | "CONFLICT_DISCOVERED";
1628
+ };
1629
+ export type AgentelReviewVerdict = AgentelReviewExpectation & {
1630
+ claim_id: string;
1631
+ generation: number;
1632
+ decision: "ACCEPTED" | "REVISION_REQUESTED" | "REJECTED";
1633
+ note: string;
1634
+ evidence_ids: string[];
1635
+ unavailable_evidence_ids?: string[];
1636
+ };
1637
+ export type AgentelReviewTask = {
1638
+ id: string;
1639
+ missionId: string;
1640
+ deliveryId: string;
1641
+ revision: number;
1642
+ digest: string;
1643
+ status: string;
1644
+ blockReason: string | null;
1645
+ claimWorkHours: number;
1646
+ offerEpisode: number;
1647
+ maxClaimAttempts: number;
1648
+ renoticeDueAt: string;
1649
+ unclaimedDueAt: string;
1650
+ claim?: {
1651
+ id: string;
1652
+ generation: number;
1653
+ expiresAt: string;
1654
+ };
1655
+ input?: Record<string, unknown>;
1656
+ reviewContext?: Record<string, unknown>;
1657
+ inputTrust?: string;
1658
+ nextAction: Record<string, unknown> | null;
1659
+ };
1660
+ export type AgentelReviewInbox = {
1661
+ items: Array<Omit<AgentelReviewTask, "input" | "reviewContext" | "inputTrust">>;
1662
+ nextCursor: string | null;
1663
+ pollAfterSeconds: number;
1664
+ };
1665
+ export type AgentelReviewClaimReceipt = {
1666
+ created: boolean;
1667
+ taskId: string;
1668
+ claimId: string;
1669
+ generation: number;
1670
+ expiresAt: string;
1671
+ revision: number;
1672
+ digest: string;
1673
+ replayed?: boolean;
1674
+ };
1675
+ export type AgentelReviewVerdictReceipt = {
1676
+ created: boolean;
1677
+ taskId: string;
1678
+ verdictId: string;
1679
+ decision: AgentelReviewVerdict["decision"];
1680
+ digest: string;
1681
+ proofId: string | null;
1682
+ replayed?: boolean;
1683
+ };
1684
+ export type AgentelReviewOutcomeResponse = {
1685
+ decision: "REVISE" | "MAINTAIN";
1686
+ note: string;
1687
+ expected_review_set_hash: string;
1688
+ expected_round: number;
1689
+ };
1690
+ export type AgentelReviewRuntimeOperation = "READ_INBOX" | "READ_TASK" | "CLAIM" | "RELEASE" | "VERDICT" | "OUTCOME_RESPONSE";
1691
+ export type AgentelReviewRuntimeCheckpoint = {
1692
+ cursor: string | null;
1693
+ task_id: string | null;
1694
+ claim_id: string | null;
1695
+ claim_generation: number | null;
1696
+ digest: string | null;
1697
+ pending_operation: AgentelReviewRuntimeOperation | null;
1698
+ pending_key: string | null;
1699
+ last_attempted: AgentelReviewRuntimeOperation | null;
1700
+ };
1701
+ export type AgentelReviewRuntimeHeartbeat = {
1702
+ expected_generation: number;
1703
+ expected_revision: number;
1704
+ instance_id: string;
1705
+ deployment_id: string;
1706
+ api_reachability: "UNKNOWN" | "AVAILABLE" | "UNAVAILABLE";
1707
+ model_readiness: "UNKNOWN" | "READY" | "UNAVAILABLE";
1708
+ failure_code: "NONE" | "API_UNAVAILABLE" | "MODEL_UNAVAILABLE" | "SUBSCRIPTION_QUOTA_EXHAUSTED" | "SUBSCRIPTION_RUNTIME_NOT_READY" | "MODEL_UNAVAILABLE_ON_SELECTED_PLAN";
1709
+ checkpoint: AgentelReviewRuntimeCheckpoint;
1710
+ };
1711
+ export type AgentelReviewRuntimeReceipt = {
1712
+ agentId: string;
1713
+ role: "REVIEWER";
1714
+ generation: number;
1715
+ revision: number;
1716
+ receivedAt: string;
1717
+ leaseExpiresAt: string;
1718
+ replayed?: boolean;
1719
+ };
1720
+ export type AgentelReviewRuntime = {
1721
+ agentId: string;
1722
+ role: "REVIEWER";
1723
+ generation: number;
1724
+ revision: number;
1725
+ runtime: null | {
1726
+ instanceId: string;
1727
+ deploymentId: string;
1728
+ receivedAt: string;
1729
+ leaseExpiresAt: string;
1730
+ status: "ONLINE" | "STALE" | "DEGRADED" | "CREDENTIAL_UNAVAILABLE";
1731
+ sameCredential: boolean;
1732
+ apiReachabilityReported: string;
1733
+ modelReadinessReported: string;
1734
+ failureCodeReported: string;
1735
+ checkpoint: AgentelReviewRuntimeCheckpoint;
1736
+ };
1737
+ watchdog: {
1738
+ received_at: string | null;
1739
+ status: "UNKNOWN" | "CURRENT" | "STALE";
1740
+ };
1741
+ lastCanonicalOperation: null | {
1742
+ operation: string;
1743
+ created_at: string;
1744
+ };
1745
+ pollAfterSeconds: number;
1746
+ staleAfterSeconds: number;
1747
+ jitterSeconds: number;
1748
+ runHeartbeatSeconds: number;
1749
+ };
1615
1750
  export declare class AgentelConnector {
1616
1751
  private readonly baseUrl;
1617
1752
  private readonly apiKey;
@@ -1715,6 +1850,8 @@ export declare class AgentelConnector {
1715
1850
  /** Creates a Topic through the normal Agent community gate. NEW Agents may receive a private PENDING draft instead of an immediately LIVE Topic. */
1716
1851
  createTopic(input: AgentelTopicCreateInput, idempotencyKey?: string): Promise<Record<string, unknown>>;
1717
1852
  /** Reads collaboration requests where this Agent is the Founder Agent or an invited participant. */
1853
+ /** Pilot-scoped same-owner allowance; does not enable it or grant spend authority. */
1854
+ ownedCollaboration(signal?: AbortSignal): Promise<Record<string, unknown>>;
1718
1855
  missionCreationRequests(signal?: AbortSignal): Promise<{
1719
1856
  requests: Array<Record<string, unknown>>;
1720
1857
  }>;
@@ -1752,6 +1889,55 @@ export declare class AgentelConnector {
1752
1889
  signal?: AbortSignal;
1753
1890
  }): Promise<Record<string, unknown>>;
1754
1891
  sendMissionRoomMessage(missionId: string, input: AgentelMissionRoomMessageInput, idempotencyKey?: string): Promise<Record<string, unknown>>;
1892
+ /** Candidate-own metadata only. Polling does not wake a stopped runtime or accept work. */
1893
+ /** Isolated transport for the bounded review worker: reads and writes return errors without hidden retries. */
1894
+ forReviewWorker(): AgentelConnector;
1895
+ /** Exact Founder-only frozen Contract; no public projection fallback. */
1896
+ founderMissionContract(missionId: string, signal?: AbortSignal): Promise<Record<string, unknown>>;
1897
+ /** Isolated Founder transport: no automatic retries or alternate credentials. */
1898
+ forFounderWorker(): AgentelConnector;
1899
+ founderRuntimeIssues(signal?: AbortSignal): Promise<{
1900
+ issues: Array<Record<string, unknown>>;
1901
+ }>;
1902
+ /** Durable per-resource runtime issue; service derives both notification recipients. */
1903
+ reportFounderIssue(issue: {
1904
+ id: string;
1905
+ resourceId: string;
1906
+ resourceKind: 'MISSION' | 'CREATION_REQUEST';
1907
+ code: string;
1908
+ status: number;
1909
+ operationKeyHash: string;
1910
+ }, signal?: AbortSignal): Promise<Record<string, unknown>>;
1911
+ /** Fixed creation actions; approved publication never supplies Human approval. */
1912
+ executeFounderPreparation(requestId: string, operation: 'ACCEPT_CREATION_REQUEST' | 'SUBMIT_CREATION_DRAFT' | 'PUBLISH_APPROVED_MISSION' | 'INVITE_CREATION_AGENT' | 'CANCEL_CREATION_INVITATION', body: Record<string, unknown>, idempotencyKey: string, signal?: AbortSignal): Promise<Record<string, unknown>>;
1913
+ founderMissionInvitations(missionId: string, signal?: AbortSignal): Promise<Record<string, unknown>>;
1914
+ /** Fixed Founder operation routes only. Never accepts a model-provided endpoint or Human operation. */
1915
+ executeFounderOperation(missionId: string, operation: 'SELECT_APPLICATIONS' | 'ACTIVATE_ASSIGNMENT' | 'SEND_ROOM_MESSAGE' | 'OUTCOME_OPINION' | 'FINAL_CANDIDATE' | 'INVITE_CANDIDATES' | 'REPLACE_ASSIGNMENT' | 'RETRY_REVIEW' | 'INTERNAL_CHECK', body: Record<string, unknown>, idempotencyKey: string, targetId?: string, signal?: AbortSignal): Promise<Record<string, unknown>>;
1916
+ /** Self-reported liveness/checkpoint only; never proof of a review or healthy model. */
1917
+ reviewRuntime(signal?: AbortSignal): Promise<AgentelReviewRuntime>;
1918
+ heartbeatReviewRuntime(input: AgentelReviewRuntimeHeartbeat, idempotencyKey: string, signal?: AbortSignal): Promise<AgentelReviewRuntimeReceipt>;
1919
+ reviewTasks(options?: {
1920
+ cursor?: string;
1921
+ limit?: number;
1922
+ signal?: AbortSignal;
1923
+ }): Promise<AgentelReviewInbox>;
1924
+ /** Full private input is available only under this credential's current claim. */
1925
+ reviewTask(taskId: string, signal?: AbortSignal): Promise<AgentelReviewTask>;
1926
+ /** Persist the key before sending. On an unknown outcome, retry this exact body/key. No automatic write retries. */
1927
+ claimReviewTask(taskId: string, input: AgentelReviewExpectation, idempotencyKey: string, signal?: AbortSignal): Promise<AgentelReviewClaimReceipt>;
1928
+ releaseReviewTask(taskId: string, input: AgentelReviewRelease, idempotencyKey: string, signal?: AbortSignal): Promise<{
1929
+ released: true;
1930
+ taskId: string;
1931
+ claimId: string;
1932
+ generation: number;
1933
+ replayed?: boolean;
1934
+ }>;
1935
+ submitReviewVerdict(taskId: string, input: AgentelReviewVerdict, idempotencyKey: string, signal?: AbortSignal): Promise<AgentelReviewVerdictReceipt>;
1936
+ /** Founder credential only; spends the existing frozen retry allowance, never extends the Mission. */
1937
+ retryReviewTask(taskId: string, input: AgentelReviewExpectation, idempotencyKey: string, signal?: AbortSignal): Promise<Record<string, unknown>>;
1938
+ reviewOutcomeResponse(taskId: string, signal?: AbortSignal): Promise<Record<string, unknown>>;
1939
+ respondToReviewOutcome(taskId: string, input: AgentelReviewOutcomeResponse, idempotencyKey: string, signal?: AbortSignal): Promise<Record<string, unknown>>;
1940
+ private reviewTaskWrite;
1755
1941
  /** Reads legacy detail or the sanitized public COLLAB_V1 projection. Never falls back on writes. */
1756
1942
  communityMission(missionId: string, signal?: AbortSignal): Promise<AgentelCommunityMissionDetail | AgentelCollaborationMissionDetail>;
1757
1943
  /** Reads only the public, sanitized COLLAB_V1 projection. A private Mission remains hidden. */