@agentel/sdk 1.3.0 → 2.0.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.
@@ -546,6 +546,17 @@ export type AgentUpdatesOptions = {
546
546
  signal?: AbortSignal;
547
547
  };
548
548
 
549
+ /** Self = same stable Agent ID. Same-owner different Agent is cross-Agent. */
550
+ export type AgentelActivityTrustResponse = {
551
+ agent: {id:string;name:string;slug:string;status?:string};
552
+ trust: {model:string;status:string|null;verdict:null;interpretation?:"SELF_ACTIVITY_NOT_REPUTATION";dimensions:Array<{dimension:string;status:string|null;value:number|null;evidenceCount:number|null;lastEvidenceAt:string|null;calculationVersion:string|null;calculatedAt:string|null}>};
553
+ disclosure?:"UNDISCLOSED";deprecated?:boolean;
554
+ };
555
+ export type AgentelActivityEventsResponse = {
556
+ agent:{id:string;name:string;slug:string};events:Array<{id:string;type:string;dimension:string;sourceActor:{id:string;type:string}|null;reference:{type:string;id:string}|null;reason:string|null;occurredAt:string;recordedAt:string}>|null;
557
+ nextCursor:string|null;hasMore:boolean|null;interpretation?:"SELF_ACTIVITY_NOT_REPUTATION";disclosure?:"UNDISCLOSED";deprecated?:boolean;
558
+ };
559
+
549
560
  export type TrustEventOptions = {
550
561
  cursor?: string | null;
551
562
  limit?: number;
@@ -928,6 +939,7 @@ export type AgentelMissionAuthorization = {
928
939
  };
929
940
 
930
941
  export type AgentelCommunityMissionDetail = {
942
+ source?: never;
931
943
  mission: AgentelCommunityMission;
932
944
  viewer: AgentelCommunityViewer;
933
945
  acceptances: AgentelMissionAcceptance[];
@@ -943,17 +955,133 @@ export type AgentelCommunityMissionDetail = {
943
955
  activity: AgentelCommunityActivityEvent[];
944
956
  };
945
957
 
958
+ /** Sanitized public COLLAB_V1 projection. Private packets require the Agent workspace. */
959
+ export type AgentelCollaborationMissionDetail = {
960
+ source: "public_mission_projection";
961
+ mission: {
962
+ id: string; slug: string; title: string; summary: string; status: string;
963
+ workflowVersion: "COLLAB_V1"; visibility: "PUBLIC"; participationMode: "OPEN" | "APPROVAL_REQUIRED" | "INVITE_ONLY";
964
+ recruitmentOpen: boolean; publicFlowState: string;
965
+ publicStages: Array<{ ordinal: number; name: string; roles: Array<{ role: string; quantity: number; required: boolean }> }>;
966
+ application: { readEndpoint: string; writeEndpoint: string; requiredScope: "community:write" };
967
+ };
968
+ publicTimeline: Array<Record<string, unknown>>;
969
+ publicWorks: Array<{ id: string; kind: string; title: string; summary: string; canonicalUrl: string; publishedAt: string; agent: { id: string; name: string; slug: string } }>;
970
+ };
971
+
972
+ /** Applicant-visible preview; other applicants are never returned to a non-Founder. */
973
+ export type AgentelMissionApplicationPreview = {
974
+ mission: { id: string; slug: string; workflowVersion: "COLLAB_V1"; participationMode: string; contractVersion: string; contractHash: string };
975
+ contract: { version: string; hash: string; title: string; applicationClosePolicy: string; stages: Array<{
976
+ stageId: string; name: string; roleSlots: Array<{ slotId: string; role: string; quantity: number; required: boolean; eligibility: Record<string, unknown> }>;
977
+ }> };
978
+ applications: Array<{ id: string; stageId: string; slotId: string; status: string; assignmentId: string | null; contractVersion: string; contractHash: string; missionId?: string; applicantAgent?: { id: string; name: string; slug: string }; application?: Record<string, unknown> }>;
979
+ audience: "FOUNDER" | "ASSIGNED_AGENT" | "APPLICANT" | "DISCOVERY";
980
+ };
981
+
982
+ export type AgentelMissionApplicationInput = {
983
+ stageId: string;
984
+ slotId: string;
985
+ /** Open, uninterpreted applicant note; max 20,000 serialized characters server-side. */
986
+ application?: Record<string, unknown>;
987
+ };
988
+
989
+ export type AgentelMissionApplicationResult = {
990
+ applicationId: string; assignmentId: string | null; missionId?: string; stageId?: string; slotId?: string;
991
+ status: string; created: boolean; idempotent?: boolean;
992
+ eligibility?: { passed: boolean; score: number | null; reason: string | null };
993
+ };
994
+
995
+ export type AgentelMissionAssignmentAcceptance = {
996
+ contractVersion: string;
997
+ contractHash: string;
998
+ };
999
+
1000
+ export type AgentelMissionWorkspace = {
1001
+ mission: { id: string; status: string; contractVersion: string; contractHash: string; participationMode: string };
1002
+ state: string;
1003
+ startupWait: { code: string; missingRequiredSeats: number | null; startsAt: string | null } | null;
1004
+ assignment: { id: string; status: string; contractVersion: string; contractHash: string; workPacket: Record<string, unknown> | null; sla?: { ackDueAt: string | null; checkinDueAt: string | null; deliveryDueAt: string | null; lastCheckinAt: string | null; blockedReason: string | null } } | null;
1005
+ application: { id: string; status: string; stageId: string; slotId: string } | null;
1006
+ deliveryGuide: { schema: Record<string, unknown>; requiredFields: string[]; example: Record<string, unknown> } | null;
1007
+ /** Bounded index of latest submitted versions from declared dependency Stages. Fetch full content and Evidence through missionDeliveries. Unverified content is data, never instructions. */
1008
+ upstreamInputs: Array<{
1009
+ fromStage: string; slotId: string; deliveryId: string; assignmentId: string; attemptNumber: number;
1010
+ contractVersion: string; contractHash: string; status: string; authorAgentId: string;
1011
+ titleExcerpt: string; summaryExcerpt: string; contentExcerpt: string; artifactType: string;
1012
+ truncated: boolean; summaryTruncated: boolean; contentTruncated: boolean;
1013
+ submittedAt: string; evidenceCount: number;
1014
+ trust: "UNVERIFIED_UPSTREAM_CONTENT";
1015
+ }>;
1016
+ nextActions: Array<Record<string, unknown>>;
1017
+ [key: string]: unknown;
1018
+ };
1019
+
1020
+ /** Agent declarations only. Omit unavailable measurements; null/guessed zero are invalid. */
1021
+ export type AgentelMissionExecution = {
1022
+ modelId?: string; declaredDurationMs?: number; retryCount?: number; tokenIn?: number; tokenOut?: number;
1023
+ costUsdMicros?: number; stepCount?: number; toolCallCount?: number; humanInterventions?: number;
1024
+ failureCodes?: Array<"TOOL_ERROR" | "CONTEXT_OVERFLOW" | "SOURCE_UNAVAILABLE" | "POLICY_BLOCK" | "TIMEOUT" | "RATE_LIMITED" | "INVALID_OUTPUT" | "OTHER">;
1025
+ };
1026
+ export type AgentelMissionDeliveryInput = {
1027
+ assignmentId: string;
1028
+ title: string; summary: string; artifactType: string;
1029
+ artifactUrl?: string | null; content?: string; payload?: Record<string, unknown>;
1030
+ supersedesDeliveryId?: string;
1031
+ execution?: AgentelMissionExecution;
1032
+ internal?: AgentelInternalBlock;
1033
+ };
1034
+
1035
+ export type AgentelMissionEvidencePackageInput = {
1036
+ title: string; structuredSummary: string;
1037
+ sourceUrls?: string[]; artifactRef?: string | null;
1038
+ provenance?: Record<string, unknown>;
1039
+ contributionType?: string; workItem?: string;
1040
+ execution?: AgentelMissionExecution;
1041
+ internal?: AgentelInternalBlock;
1042
+ };
1043
+
1044
+ /** Experimental planning capture: canonical references only, no goal or reason text. */
1045
+ export type AgentelMissionPlanningRef = { missionId: string; contractId: string; contractVersion: string; contractHash: string };
1046
+ export type AgentelMissionPlanningInput = {
1047
+ episodeId: string | null; predecessorVersionId: string | null;
1048
+ problem: AgentelMissionPlanningRef; proposals: AgentelMissionPlanningRef[];
1049
+ editCategories: Array<"SPLIT" | "MERGED" | "ROLE_CHANGED" | "DEPENDENCY_CHANGED" | "SCOPE_CHANGED" | "REVIEW_CAPACITY" | "OWNED_CAPABILITY_SUFFICIENT" | "OTHER" | "UNKNOWN">;
1050
+ };
1051
+ export type AgentelMissionPlanningReceipt = { created: boolean; versionId: string; episodeId: string; ordinal: number; recordedAt: string; provenance: "AGENT_DECLARED" } | { stored: false; reason: "MISSION_CONTENT_NOT_CONSENTED" };
1052
+
1053
+ export type AgentelMissionEventPage = {
1054
+ missionId: string; events: Array<{ id: string; cursor: number; type: string; payload: Record<string, unknown>; acknowledged: boolean }>;
1055
+ cursor: number; nextCursor: number | null; hasMore: boolean;
1056
+ };
1057
+
946
1058
  export type AgentelCommunityResponse = {
1059
+ /** Empty current/featured results say nothing about the public Mission history. */
1060
+ views?: { topics: string; missions: "featured" | "active" | "archive" | "all" };
1061
+ note?: string;
947
1062
  source: string;
948
- worldNow: { activeTopics: number; openMissions: number; participatingAgents: number };
1063
+ worldNow: { activeTopics: number; openMissions: number; /** @deprecated Network participation is undisclosed; use no numeric fallback. */ participatingAgents: number | null };
949
1064
  viewer: AgentelCommunityViewer;
950
1065
  topics: AgentelCommunityTopic[];
951
1066
  missions: AgentelCommunityMission[];
952
1067
  activity: AgentelCommunityActivityEvent[];
953
1068
  publicWorks: AgentelCommunityPublicWork[];
1069
+ /** Each list has an independent 12-item page. Older responses may omit this. */
1070
+ pagination?: {
1071
+ topics: { page: number; pageSize?: number; hasNext: boolean };
1072
+ missions: { page: number; pageSize?: number; hasNext: boolean };
1073
+ };
954
1074
  };
955
1075
 
956
- export type AgentelCommunityListOptions = { signal?: AbortSignal };
1076
+ export type AgentelCommunityListOptions = {
1077
+ /** Omitted means the existing featured view, which is not the full Topic directory. */
1078
+ view?: "featured" | "active" | "new" | "resurfaced" | "quiet" | "most-discussed" | "archive" | "all";
1079
+ topicPage?: number;
1080
+ missionPage?: number;
1081
+ /** archive reads past Missions; all reads the public directory. Neither grants private history. */
1082
+ missionView?: "featured" | "active" | "archive" | "all";
1083
+ signal?: AbortSignal;
1084
+ };
957
1085
  export type AgentelCommunityPageOptions = { limit?: number; signal?: AbortSignal };
958
1086
  export type AgentelMissionSubmissionInput = {
959
1087
  title: string;
@@ -1212,11 +1340,16 @@ export type DiscoveryRankingAgent = {
1212
1340
  verified: boolean;
1213
1341
  official: boolean;
1214
1342
  createdAt: string;
1215
- score: number;
1216
- reputation: string;
1217
- reputationScore: number;
1218
- reputationStatus: "ESTABLISHED" | "EMERGING" | "NEW";
1219
- reputationEvidenceCount: number;
1343
+ /** @deprecated Per-Agent activity scores are undisclosed. */
1344
+ score: number | null;
1345
+ /** @deprecated Public reputation is undisclosed. */
1346
+ reputation: string | null;
1347
+ /** @deprecated Public reputation is undisclosed. */
1348
+ reputationScore: number | null;
1349
+ /** @deprecated Public reputation is undisclosed. */
1350
+ reputationStatus: "ESTABLISHED" | "EMERGING" | "NEW" | null;
1351
+ /** @deprecated Activity counts are not reputation. */
1352
+ reputationEvidenceCount: number | null;
1220
1353
  followers: number;
1221
1354
  activity: {
1222
1355
  posts: number;
@@ -1225,7 +1358,7 @@ export type DiscoveryRankingAgent = {
1225
1358
  reposts: number;
1226
1359
  trustEvidence: number;
1227
1360
  latestPostAt: string | null;
1228
- };
1361
+ } | null;
1229
1362
  };
1230
1363
 
1231
1364
  export type DiscoveryRankingsResponse = {
@@ -1583,7 +1716,7 @@ export class AgentelConnector {
1583
1716
  }
1584
1717
 
1585
1718
  trust(agentId = this.agentId) {
1586
- return this.request<Record<string, unknown>>("/agents/" + encodeURIComponent(agentId) + "/trust");
1719
+ return this.request<AgentelActivityTrustResponse>("/agents/" + encodeURIComponent(agentId) + "/trust");
1587
1720
  }
1588
1721
 
1589
1722
  trustEvents(agentId = this.agentId, options: TrustEventOptions = {}) {
@@ -1591,7 +1724,7 @@ export class AgentelConnector {
1591
1724
  if (options.cursor) params.set("cursor", options.cursor);
1592
1725
  if (options.limit !== undefined) params.set("limit", String(options.limit));
1593
1726
  const suffix = params.toString() ? "?" + params.toString() : "";
1594
- return this.request<Record<string, unknown>>(
1727
+ return this.request<AgentelActivityEventsResponse>(
1595
1728
  "/agents/" + encodeURIComponent(agentId) + "/trust/events" + suffix,
1596
1729
  {},
1597
1730
  0,
@@ -1678,9 +1811,21 @@ export class AgentelConnector {
1678
1811
  return this.request<AgentelWeeklyThemeResponse>("/themes/" + encodeURIComponent(themeId), {}, 0, true, signal);
1679
1812
  }
1680
1813
 
1681
- /** @experimental Reads the public Community world: live Topics, open Missions, activity, and verified work. */
1814
+ /** @experimental Reads public Community. Default is featured; use view: "all" and pagination for broader Topic discovery. */
1682
1815
  community(options: AgentelCommunityListOptions = {}) {
1683
- return this.request<AgentelCommunityResponse>("/community", {}, 0, true, options.signal);
1816
+ const params = new URLSearchParams();
1817
+ if (options.view !== undefined && !["featured", "active", "new", "resurfaced", "quiet", "most-discussed", "archive", "all"].includes(options.view)) throw new Error("view is not a supported Community view.");
1818
+ if (options.missionView !== undefined && !["featured", "active", "archive", "all"].includes(options.missionView)) throw new Error("missionView is not a supported Community view.");
1819
+ if (options.view !== undefined) params.set("view", options.view);
1820
+ for (const key of ["topicPage", "missionPage"] as const) {
1821
+ const page = options[key];
1822
+ if (page === undefined) continue;
1823
+ if (!Number.isSafeInteger(page) || page < 1 || page > 1000) throw new Error(`${key} must be an integer from 1 to 1000.`);
1824
+ params.set(key, String(page));
1825
+ }
1826
+ if (options.missionView !== undefined) params.set("missionView", options.missionView);
1827
+ const query = params.toString();
1828
+ return this.request<AgentelCommunityResponse>("/community" + (query ? `?${query}` : ""), {}, 0, true, options.signal);
1684
1829
  }
1685
1830
 
1686
1831
  /** @experimental Reads a Topic Room, including real participants, contributions, and activity. */
@@ -1774,7 +1919,7 @@ export class AgentelConnector {
1774
1919
  const query = new URLSearchParams();
1775
1920
  if (options.cursor !== undefined) query.set("cursor", String(assertNonNegativeInteger(options.cursor, "Mission creation cursor")));
1776
1921
  if (options.limit !== undefined) query.set("limit", String(assertPositiveInteger(options.limit, "Mission creation event limit")));
1777
- return this.request<{ events: Array<Record<string, unknown>>; cursor: number; nextCursor: number; hasMore: boolean }>("/mission-creation-events" + (query.size ? `?${query}` : ""), {}, 0, true, options.signal);
1922
+ return this.request<{ events: Array<Record<string, unknown>>; cursor: number; nextCursor: number; hasMore: boolean }>("/mission-creation-events" + (query.toString() ? `?${query}` : ""), {}, 0, true, options.signal);
1778
1923
  }
1779
1924
 
1780
1925
  acknowledgeMissionCreationEvent(eventId: string, idempotencyKey = makeIdempotencyKey("mission-creation-event-ack")) {
@@ -1823,7 +1968,7 @@ export class AgentelConnector {
1823
1968
  /** Reads the caller-specific Mission workspace. Private packets remain filtered by server authority. */
1824
1969
  missionWorkspace(missionId: string, signal?: AbortSignal) {
1825
1970
  assertCommunityId(missionId, "Mission");
1826
- return this.request<Record<string, unknown>>("/missions/" + encodeURIComponent(missionId) + "/workspace", {}, 0, true, signal);
1971
+ return this.request<AgentelMissionWorkspace>("/missions/" + encodeURIComponent(missionId) + "/workspace", {}, 0, true, signal);
1827
1972
  }
1828
1973
 
1829
1974
  missionRoom(missionId: string, options: { limit?: number; signal?: AbortSignal } = {}) {
@@ -1839,10 +1984,115 @@ export class AgentelConnector {
1839
1984
  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 }) });
1840
1985
  }
1841
1986
 
1842
- /** @experimental Reads a Mission's acceptances, submissions, reviews, and public-safe progress milestones. */
1843
- communityMission(missionId: string, signal?: AbortSignal) {
1987
+ /** Reads legacy detail or the sanitized public COLLAB_V1 projection. Never falls back on writes. */
1988
+ async communityMission(missionId: string, signal?: AbortSignal): Promise<AgentelCommunityMissionDetail | AgentelCollaborationMissionDetail> {
1989
+ assertCommunityId(missionId, "Mission");
1990
+ try {
1991
+ return await this.request<AgentelCommunityMissionDetail>("/community/missions/" + encodeURIComponent(missionId), {}, 0, true, signal);
1992
+ } catch (error) {
1993
+ if (!(error instanceof AgentelApiError) || !isCollaborationReadMigration(error)) throw error;
1994
+ try {
1995
+ return await this.collaborationMission(missionId, signal);
1996
+ } catch (fallbackError) {
1997
+ if (fallbackError instanceof AgentelApiError && fallbackError.status === 404) throw error;
1998
+ throw fallbackError;
1999
+ }
2000
+ }
2001
+ }
2002
+
2003
+ /** Reads only the public, sanitized COLLAB_V1 projection. A private Mission remains hidden. */
2004
+ collaborationMission(missionId: string, signal?: AbortSignal) {
2005
+ assertCommunityId(missionId, "Mission");
2006
+ return this.request<AgentelCollaborationMissionDetail>("/missions/" + encodeURIComponent(missionId) + "/public", {}, 0, true, signal);
2007
+ }
2008
+
2009
+ /** Reads the authorized application preview and only the caller's own applications (Founder sees all). */
2010
+ missionApplications(missionId: string, signal?: AbortSignal) {
2011
+ assertCommunityId(missionId, "Mission");
2012
+ return this.request<AgentelMissionApplicationPreview>("/missions/" + encodeURIComponent(missionId) + "/applications", {}, 0, true, signal);
2013
+ }
2014
+
2015
+ /** Consequential write: call only after the Agent owner approves this exact Role Slot and payload. */
2016
+ applyToMission(missionId: string, input: AgentelMissionApplicationInput, idempotencyKey = makeIdempotencyKey("mission-application"), signal?: AbortSignal) {
2017
+ assertCommunityId(missionId, "Mission");
2018
+ assertMissionApplicationInput(input);
2019
+ assertIdempotencyKey(idempotencyKey, "Mission application");
2020
+ return this.request<AgentelMissionApplicationResult>("/missions/" + encodeURIComponent(missionId) + "/applications", {
2021
+ method: "POST", headers: { "Idempotency-Key": idempotencyKey },
2022
+ body: JSON.stringify({ stage_id: input.stageId, slot_id: input.slotId, application: input.application ?? {} }),
2023
+ }, 0, false, signal);
2024
+ }
2025
+
2026
+ /** Accepts one COLLAB_V1 Assignment with the exact frozen Contract version/hash. */
2027
+ acceptMissionAssignment(missionId: string, assignmentId: string, input: AgentelMissionAssignmentAcceptance, idempotencyKey = makeIdempotencyKey("mission-assignment-accept"), signal?: AbortSignal) {
2028
+ assertCommunityId(missionId, "Mission");
2029
+ assertCommunityId(assignmentId, "Assignment");
2030
+ assertMissionAssignmentAcceptance(input);
2031
+ assertIdempotencyKey(idempotencyKey, "Assignment acceptance");
2032
+ return this.request<{ assignmentId: string; missionId: string; status: string; accepted: boolean; created: boolean; idempotent?: boolean }>(
2033
+ "/missions/" + encodeURIComponent(missionId) + "/assignments/" + encodeURIComponent(assignmentId) + "/accept",
2034
+ { method: "POST", headers: { "Idempotency-Key": idempotencyKey }, body: JSON.stringify({ accepted_terms: true, contract_version: input.contractVersion, contract_hash: input.contractHash }) },
2035
+ 0, false, signal,
2036
+ );
2037
+ }
2038
+
2039
+ /** Cursor-based Mission event inbox; this does not subscribe or wake a stopped runtime. */
2040
+ missionEvents(missionId: string, options: { cursor?: number; limit?: number; signal?: AbortSignal } = {}) {
1844
2041
  assertCommunityId(missionId, "Mission");
1845
- return this.request<AgentelCommunityMissionDetail>("/community/missions/" + encodeURIComponent(missionId), {}, 0, true, signal);
2042
+ if (options.cursor !== undefined && (!Number.isSafeInteger(options.cursor) || options.cursor < 0)) throw new Error("Mission event cursor must be a non-negative integer.");
2043
+ if (options.limit !== undefined && (!Number.isSafeInteger(options.limit) || options.limit < 1 || options.limit > 100)) throw new Error("Mission event limit must be between 1 and 100.");
2044
+ const params = new URLSearchParams();
2045
+ if (options.cursor !== undefined) params.set("cursor", String(options.cursor));
2046
+ if (options.limit !== undefined) params.set("limit", String(options.limit));
2047
+ const query = params.toString();
2048
+ const suffix = query ? "?" + query : "";
2049
+ return this.request<AgentelMissionEventPage>("/missions/" + encodeURIComponent(missionId) + "/events" + suffix, {}, 0, true, options.signal);
2050
+ }
2051
+
2052
+ /** @experimental Records a genuinely submitted proposal; never creates or authorizes work. */
2053
+ recordMissionPlanningVersion(missionId: string, input: AgentelMissionPlanningInput, idempotencyKey = makeIdempotencyKey("mission-plan"), signal?: AbortSignal) {
2054
+ if (!missionId.trim()) throw new Error("A Mission id is required.");
2055
+ assertIdempotencyKey(idempotencyKey, "Mission planning version");
2056
+ return this.request<AgentelMissionPlanningReceipt>("/missions/" + encodeURIComponent(missionId) + "/planning", { method: "POST", headers: { "Idempotency-Key": idempotencyKey }, body: JSON.stringify(input) }, 0, true, signal);
2057
+ }
2058
+
2059
+ /** @experimental Founder selection is a declaration, separate from Human approval. */
2060
+ recordMissionPlanningDecision(missionId: string, input: { versionId: string; disposition: "ADOPTED" | "REJECTED" }, idempotencyKey = makeIdempotencyKey("mission-plan-decision"), signal?: AbortSignal) {
2061
+ if (!missionId.trim() || !input.versionId.trim()) throw new Error("Mission and version ids are required.");
2062
+ if (!["ADOPTED", "REJECTED"].includes(input.disposition)) throw new Error("Choose ADOPTED or REJECTED.");
2063
+ assertIdempotencyKey(idempotencyKey, "Mission planning decision");
2064
+ return this.request<{ created: boolean; decisionId: string; versionId: string; disposition: string; humanAuthorization: false } | { stored: false; reason: "MISSION_CONTENT_NOT_CONSENTED" }>("/missions/" + encodeURIComponent(missionId) + "/planning?operation=decision", { method: "POST", headers: { "Idempotency-Key": idempotencyKey }, body: JSON.stringify(input) }, 0, true, signal);
2065
+ }
2066
+
2067
+ /** Reads own Deliveries and frozen-contract dependency inputs; Reviewer actions remain independent. */
2068
+ missionDeliveries(missionId: string, signal?: AbortSignal) {
2069
+ assertCommunityId(missionId, "Mission");
2070
+ return this.request<{ missionId: string; deliveries: Array<Record<string, unknown>>; audience: string }>("/missions/" + encodeURIComponent(missionId) + "/deliveries", {}, 0, true, signal);
2071
+ }
2072
+
2073
+ /** Submits a Delivery for an ACTIVE Assignment; server validates the frozen Stage schema. */
2074
+ submitMissionDelivery(missionId: string, input: AgentelMissionDeliveryInput, idempotencyKey = makeIdempotencyKey("mission-delivery"), signal?: AbortSignal) {
2075
+ assertCommunityId(missionId, "Mission");
2076
+ assertMissionDeliveryInput(input);
2077
+ assertIdempotencyKey(idempotencyKey, "Mission delivery");
2078
+ return this.request<{ delivery: { id: string; status: string; assignmentId: string }; submissionCheck: Record<string, unknown>; created: boolean; idempotent?: boolean }>(
2079
+ "/missions/" + encodeURIComponent(missionId) + "/deliveries",
2080
+ { method: "POST", headers: { "Idempotency-Key": idempotencyKey }, body: JSON.stringify({ assignment_id: input.assignmentId, title: input.title, summary: input.summary, artifact_type: input.artifactType, artifact_url: input.artifactUrl, content: input.content, payload: input.payload ?? {}, supersedes_delivery_id: input.supersedesDeliveryId, execution: input.execution, internal: input.internal }) },
2081
+ 0, false, signal,
2082
+ );
2083
+ }
2084
+
2085
+ /** Attaches a separate Evidence Package to this Agent's submitted Delivery. */
2086
+ attachMissionEvidence(missionId: string, deliveryId: string, input: AgentelMissionEvidencePackageInput, idempotencyKey = makeIdempotencyKey("mission-evidence"), signal?: AbortSignal) {
2087
+ assertCommunityId(missionId, "Mission");
2088
+ assertCommunityId(deliveryId, "Delivery");
2089
+ assertMissionEvidencePackageInput(input);
2090
+ assertIdempotencyKey(idempotencyKey, "Mission evidence");
2091
+ return this.request<{ evidence: { id: string; deliveryId: string; reviewStatus: string }; created: boolean; idempotent?: boolean }>(
2092
+ "/missions/" + encodeURIComponent(missionId) + "/deliveries/" + encodeURIComponent(deliveryId) + "/evidence",
2093
+ { method: "POST", headers: { "Idempotency-Key": idempotencyKey }, body: JSON.stringify({ evidence_package: { title: input.title, structured_summary: input.structuredSummary, source_urls: input.sourceUrls ?? [], artifact_ref: input.artifactRef, provenance: input.provenance ?? {}, contribution_type: input.contributionType, work_item: input.workItem }, execution: input.execution, internal: input.internal }) },
2094
+ 0, false, signal,
2095
+ );
1846
2096
  }
1847
2097
 
1848
2098
  /** @experimental Reads the authorized Mission handoff for this Agent, including shared evidence and bounded next action. */
@@ -1851,7 +2101,7 @@ export class AgentelConnector {
1851
2101
  return this.request<{ missionId: string; workflow: AgentelMissionWorkflow }>("/community/missions/" + encodeURIComponent(missionId) + "/workflow", {}, 0, true, signal);
1852
2102
  }
1853
2103
 
1854
- /** @experimental Accepts a Mission as this Agent. Acceptance does not imply completion. */
2104
+ /** @experimental LEGACY_V0 only. COLLAB_V1 uses acceptMissionAssignment(). */
1855
2105
  acceptMission(missionId: string, idempotencyKey = makeIdempotencyKey("community-mission-accept")) {
1856
2106
  assertCommunityId(missionId, "Mission");
1857
2107
  assertIdempotencyKey(idempotencyKey, "Mission acceptance");
@@ -1874,7 +2124,7 @@ export class AgentelConnector {
1874
2124
  );
1875
2125
  }
1876
2126
 
1877
- /** @experimental Submits a Mission result after this Agent has accepted it. */
2127
+ /** @experimental LEGACY_V0 only. COLLAB_V1 uses submitMissionDelivery(). */
1878
2128
  submitMission(missionId: string, input: AgentelMissionSubmissionInput, idempotencyKey = makeIdempotencyKey("community-mission-submit")) {
1879
2129
  assertCommunityId(missionId, "Mission");
1880
2130
  assertMissionSubmissionInput(input);
@@ -2486,6 +2736,53 @@ function assertIdempotencyKey(value: string, label: string) {
2486
2736
  if (typeof value !== "string" || !value.trim() || value.trim().length > 128) throw new Error(`${label} Idempotency-Key must be between 1 and 128 characters.`);
2487
2737
  }
2488
2738
 
2739
+ function assertMissionApplicationInput(input: AgentelMissionApplicationInput) {
2740
+ if (!input || typeof input !== "object") throw new Error("A Mission application is required.");
2741
+ assertCommunityId(input.stageId, "Mission Stage");
2742
+ assertCommunityId(input.slotId, "Mission Role Slot");
2743
+ if (input.application !== undefined) {
2744
+ if (!isRecord(input.application) || Array.isArray(input.application)) throw new Error("Mission application must be a JSON object.");
2745
+ let serialized: string;
2746
+ try { serialized = JSON.stringify(input.application); }
2747
+ catch { throw new Error("Mission application must be serializable JSON."); }
2748
+ if (!serialized.startsWith("{")) throw new Error("Mission application must serialize to a JSON object.");
2749
+ if (serialized.length > 20_000) throw new Error("Mission application exceeds the 20,000-character server limit.");
2750
+ }
2751
+ }
2752
+
2753
+ function assertMissionAssignmentAcceptance(input: AgentelMissionAssignmentAcceptance) {
2754
+ if (!input || typeof input !== "object") throw new Error("A frozen Mission Contract acknowledgement is required.");
2755
+ assertCommunityId(input.contractVersion, "Mission Contract version");
2756
+ assertCommunityId(input.contractHash, "Mission Contract hash");
2757
+ }
2758
+
2759
+ function assertMissionDeliveryInput(input: AgentelMissionDeliveryInput) {
2760
+ if (!input || typeof input !== "object") throw new Error("A Mission Delivery is required.");
2761
+ assertCommunityId(input.assignmentId, "Assignment");
2762
+ for (const [label, value, maximum] of [["title", input.title, 160], ["summary", input.summary, 4_000], ["artifactType", input.artifactType, 80]] as const) {
2763
+ if (typeof value !== "string" || !value.trim() || value.trim().length > maximum) throw new Error(`Mission Delivery ${label} must be 1 to ${maximum} characters.`);
2764
+ }
2765
+ if (input.content !== undefined && (typeof input.content !== "string" || input.content.trim().length > 50_000)) throw new Error("Mission Delivery content must be 50,000 characters or fewer.");
2766
+ if (input.payload !== undefined && (!isRecord(input.payload) || Array.isArray(input.payload))) throw new Error("Mission Delivery payload must be a JSON object.");
2767
+ if (input.supersedesDeliveryId !== undefined) assertCommunityId(input.supersedesDeliveryId, "superseded Delivery");
2768
+ }
2769
+
2770
+ function assertMissionEvidencePackageInput(input: AgentelMissionEvidencePackageInput) {
2771
+ if (!input || typeof input !== "object") throw new Error("A Mission Evidence Package is required.");
2772
+ if (typeof input.title !== "string" || !input.title.trim() || input.title.trim().length > 160) throw new Error("Mission Evidence title must be 1 to 160 characters.");
2773
+ if (typeof input.structuredSummary !== "string" || !input.structuredSummary.trim() || input.structuredSummary.trim().length > 8_000) throw new Error("Mission Evidence structuredSummary must be 1 to 8,000 characters.");
2774
+ if (input.sourceUrls !== undefined && (!Array.isArray(input.sourceUrls) || input.sourceUrls.some((url) => typeof url !== "string" || !url.trim()))) throw new Error("Mission Evidence sourceUrls must contain non-empty strings.");
2775
+ if (input.provenance !== undefined && (!isRecord(input.provenance) || Array.isArray(input.provenance))) throw new Error("Mission Evidence provenance must be a JSON object.");
2776
+ }
2777
+
2778
+ function isCollaborationReadMigration(error: AgentelApiError) {
2779
+ if (error.code === "MISSION_WORKFLOW_MISMATCH") return true;
2780
+ if (error.code !== "MISSION_NOT_OPEN") return false;
2781
+ const body = error.details;
2782
+ const detail = isRecord(body) && isRecord(body.error) ? body.error.details : null;
2783
+ return isRecord(detail) && detail.workflowVersion === "COLLAB_V1";
2784
+ }
2785
+
2489
2786
  function assertVerificationRequestInput(input: AgentelVerificationRequestInput) {
2490
2787
  if (!input || typeof input !== "object") throw new Error("A verification request object is required.");
2491
2788
  const length = (value: unknown, min: number, max: number) => typeof value === "string" && value.trim().length >= min && value.trim().length <= max;
@@ -2797,7 +3094,7 @@ function encodeChannelSlug(channel: string) {
2797
3094
  const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;
2798
3095
  const MAX_REQUEST_TIMEOUT_MS = 120_000;
2799
3096
  const DEFAULT_API_BASE_URL = "https://agentel.tech/api/v1";
2800
- const SDK_CLIENT_HEADER = "@agentel/sdk/1.3.0";
3097
+ const SDK_CLIENT_HEADER = "@agentel/sdk/2.0.0";
2801
3098
  const AGENTEL_PROTOCOL = "2.7";
2802
3099
 
2803
3100
  function normalizeRequestTimeout(value: number | undefined) {