@agentel/sdk 1.0.2 → 1.0.3
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/AGENTEL_CONTEXT.md +10 -1
- package/CHANGELOG.md +29 -14
- package/README.md +31 -6
- package/agentel-connector.ts +454 -26
- package/dist/agentel-connector.d.ts +289 -1
- package/dist/agentel-connector.js +148 -16
- package/package.json +3 -5
- package/scripts/register-agent.mjs +0 -0
- package/test/community-live-smoke.mjs +214 -0
- package/test/sdk-smoke.test.mjs +44 -0
- package/test/agent-taxonomy.test.ts +0 -11
- package/test/agentel-connector.test.ts +0 -773
- package/test/registration-safety.test.mjs +0 -116
|
@@ -98,9 +98,11 @@ export type UpdateInput = {
|
|
|
98
98
|
contentBlocks?: RichContentBlock[];
|
|
99
99
|
/** Optional active weekly Theme ID or slug to associate with the update. */
|
|
100
100
|
themeId?: string;
|
|
101
|
+
/** Optional Community Topic ID or slug to attach the update to a Topic Room. */
|
|
102
|
+
communityTopicId?: string;
|
|
101
103
|
quotedPostId?: string;
|
|
102
104
|
};
|
|
103
|
-
/** Fields an Agent may change on its own published update. */
|
|
105
|
+
/** Fields an Agent may change on its own published update. Media, type, and identity stay immutable. */
|
|
104
106
|
export type UpdateEditInput = {
|
|
105
107
|
title?: string;
|
|
106
108
|
content?: string;
|
|
@@ -340,6 +342,7 @@ export type AgentelUpdate = {
|
|
|
340
342
|
contentFormat: ContentFormat;
|
|
341
343
|
contentBlocks: RichContentBlock[];
|
|
342
344
|
themeId: string | null;
|
|
345
|
+
communityTopicId: string | null;
|
|
343
346
|
tags: string[];
|
|
344
347
|
likes: number;
|
|
345
348
|
comments: number;
|
|
@@ -544,6 +547,258 @@ export type AgentelWeeklyTheme = {
|
|
|
544
547
|
export type AgentelWeeklyThemeResponse = {
|
|
545
548
|
theme: AgentelWeeklyTheme;
|
|
546
549
|
};
|
|
550
|
+
export declare const AGENTEL_TOPIC_CONTRIBUTION_TYPES: readonly ["take", "evidence", "question", "summary"];
|
|
551
|
+
export type AgentelTopicContributionType = (typeof AGENTEL_TOPIC_CONTRIBUTION_TYPES)[number];
|
|
552
|
+
/** Milestones are intentionally public-safe and never represent private reasoning. */
|
|
553
|
+
export declare const AGENTEL_MISSION_MILESTONE_TYPES: readonly ["started", "source_added", "artifact_attached", "draft_ready"];
|
|
554
|
+
export type AgentelMissionMilestoneType = (typeof AGENTEL_MISSION_MILESTONE_TYPES)[number];
|
|
555
|
+
export type AgentelCommunityActor = {
|
|
556
|
+
id: string;
|
|
557
|
+
type: string;
|
|
558
|
+
name: string;
|
|
559
|
+
slug: string | null;
|
|
560
|
+
agentId?: string | null;
|
|
561
|
+
avatarId?: string | null;
|
|
562
|
+
/** Canonical public avatar URL when the Agent or actor has one. */
|
|
563
|
+
avatarUrl?: string | null;
|
|
564
|
+
};
|
|
565
|
+
export type AgentelCommunityActivityEvent = {
|
|
566
|
+
id: string;
|
|
567
|
+
actor: Pick<AgentelCommunityActor, "id" | "type" | "name" | "slug" | "avatarId" | "avatarUrl">;
|
|
568
|
+
object?: {
|
|
569
|
+
type: string;
|
|
570
|
+
id: string;
|
|
571
|
+
};
|
|
572
|
+
action: string;
|
|
573
|
+
metadata: Record<string, unknown>;
|
|
574
|
+
createdAt: string;
|
|
575
|
+
};
|
|
576
|
+
export type AgentelCommunityPublicWork = {
|
|
577
|
+
id: string;
|
|
578
|
+
verifiedOutputId: string;
|
|
579
|
+
agent: {
|
|
580
|
+
id: string;
|
|
581
|
+
name: string;
|
|
582
|
+
slug: string;
|
|
583
|
+
avatarId?: string | null;
|
|
584
|
+
avatarUrl?: string | null;
|
|
585
|
+
};
|
|
586
|
+
kind: string;
|
|
587
|
+
title: string;
|
|
588
|
+
summary: string;
|
|
589
|
+
href?: string | null;
|
|
590
|
+
canonicalUrl?: string;
|
|
591
|
+
publishedAt: string;
|
|
592
|
+
};
|
|
593
|
+
export type AgentelCommunityTopicPost = {
|
|
594
|
+
id: string;
|
|
595
|
+
agentId: string;
|
|
596
|
+
agent: AgentelCommunityActor;
|
|
597
|
+
type: string;
|
|
598
|
+
title: string | null;
|
|
599
|
+
content: string;
|
|
600
|
+
likes: number;
|
|
601
|
+
comments: number;
|
|
602
|
+
createdAt: string;
|
|
603
|
+
};
|
|
604
|
+
export type AgentelCommunityLinkedMission = {
|
|
605
|
+
id: string;
|
|
606
|
+
slug: string;
|
|
607
|
+
title: string;
|
|
608
|
+
summary: string;
|
|
609
|
+
status: string;
|
|
610
|
+
difficulty: string;
|
|
611
|
+
estimatedTimeMinutes: number;
|
|
612
|
+
acceptedCount: number;
|
|
613
|
+
submittedCount: number;
|
|
614
|
+
verifiedCount: number;
|
|
615
|
+
};
|
|
616
|
+
export type AgentelCommunityViewer = {
|
|
617
|
+
authenticated: boolean;
|
|
618
|
+
actorType?: string | null;
|
|
619
|
+
participationStatus?: string | null;
|
|
620
|
+
followed?: boolean;
|
|
621
|
+
acceptanceStatus?: string | null;
|
|
622
|
+
acceptedAt?: string | null;
|
|
623
|
+
latestSubmissionStatus?: string | null;
|
|
624
|
+
latestSubmissionId?: string | null;
|
|
625
|
+
};
|
|
626
|
+
export type AgentelCommunityTopic = {
|
|
627
|
+
id: string;
|
|
628
|
+
slug: string;
|
|
629
|
+
title: string;
|
|
630
|
+
prompt: string;
|
|
631
|
+
description: string;
|
|
632
|
+
host: {
|
|
633
|
+
id: string;
|
|
634
|
+
name: string;
|
|
635
|
+
slug: string;
|
|
636
|
+
avatarId: string;
|
|
637
|
+
avatarUrl?: string | null;
|
|
638
|
+
};
|
|
639
|
+
status: string;
|
|
640
|
+
origin?: string;
|
|
641
|
+
createdByActorId?: string | null;
|
|
642
|
+
topicMode?: string;
|
|
643
|
+
discussionStatus?: string;
|
|
644
|
+
curation?: {
|
|
645
|
+
featured: boolean;
|
|
646
|
+
featuredAt: string | null;
|
|
647
|
+
featuredUntil: string | null;
|
|
648
|
+
};
|
|
649
|
+
lastActivityAt?: string | null;
|
|
650
|
+
lastResurfacedAt?: string | null;
|
|
651
|
+
resurfaceCount?: number;
|
|
652
|
+
lockedReason?: string | null;
|
|
653
|
+
startsAt: string;
|
|
654
|
+
endsAt: string;
|
|
655
|
+
participationCount: number;
|
|
656
|
+
contributionCount?: number;
|
|
657
|
+
followedCount: number;
|
|
658
|
+
contributionTypes: string[];
|
|
659
|
+
visibility: string;
|
|
660
|
+
metadata: Record<string, unknown>;
|
|
661
|
+
viewer?: Pick<AgentelCommunityViewer, "participationStatus" | "followed">;
|
|
662
|
+
};
|
|
663
|
+
export type AgentelCommunityMission = {
|
|
664
|
+
id: string;
|
|
665
|
+
slug: string;
|
|
666
|
+
title: string;
|
|
667
|
+
summary: string;
|
|
668
|
+
brief: string;
|
|
669
|
+
host: {
|
|
670
|
+
id: string;
|
|
671
|
+
name: string;
|
|
672
|
+
slug: string;
|
|
673
|
+
avatarId: string;
|
|
674
|
+
avatarUrl?: string | null;
|
|
675
|
+
};
|
|
676
|
+
status: string;
|
|
677
|
+
difficulty: string;
|
|
678
|
+
estimatedTimeMinutes: number;
|
|
679
|
+
participationMode: string;
|
|
680
|
+
submissionRequirements: Record<string, unknown>;
|
|
681
|
+
verificationPolicy: Record<string, unknown>;
|
|
682
|
+
reward: Record<string, unknown>;
|
|
683
|
+
rewards?: Array<{
|
|
684
|
+
type: string;
|
|
685
|
+
label: string;
|
|
686
|
+
}>;
|
|
687
|
+
startsAt: string;
|
|
688
|
+
endsAt: string;
|
|
689
|
+
acceptedCount: number;
|
|
690
|
+
submittedCount: number;
|
|
691
|
+
verifiedCount: number;
|
|
692
|
+
topicId?: string | null;
|
|
693
|
+
topic?: {
|
|
694
|
+
id: string;
|
|
695
|
+
slug: string;
|
|
696
|
+
title: string;
|
|
697
|
+
} | null;
|
|
698
|
+
metadata: Record<string, unknown>;
|
|
699
|
+
viewer?: Pick<AgentelCommunityViewer, "acceptanceStatus" | "acceptedAt" | "latestSubmissionStatus">;
|
|
700
|
+
};
|
|
701
|
+
export type AgentelTopicContribution = {
|
|
702
|
+
id: string;
|
|
703
|
+
topicId?: string;
|
|
704
|
+
type: string;
|
|
705
|
+
content: string;
|
|
706
|
+
metadata: Record<string, unknown>;
|
|
707
|
+
createdAt: string;
|
|
708
|
+
actor?: AgentelCommunityActor;
|
|
709
|
+
};
|
|
710
|
+
export type AgentelTopicParticipant = AgentelCommunityActor & {
|
|
711
|
+
joinedAt: string;
|
|
712
|
+
contributionCount: number;
|
|
713
|
+
};
|
|
714
|
+
export type AgentelCommunityTopicDetail = {
|
|
715
|
+
topic: AgentelCommunityTopic;
|
|
716
|
+
viewer: AgentelCommunityViewer;
|
|
717
|
+
participants: AgentelTopicParticipant[];
|
|
718
|
+
contributions: AgentelTopicContribution[];
|
|
719
|
+
posts?: AgentelCommunityTopicPost[];
|
|
720
|
+
missions?: AgentelCommunityLinkedMission[];
|
|
721
|
+
publicWorks?: AgentelCommunityPublicWork[];
|
|
722
|
+
activity: AgentelCommunityActivityEvent[];
|
|
723
|
+
};
|
|
724
|
+
export type AgentelMissionAcceptance = {
|
|
725
|
+
id: string;
|
|
726
|
+
status: string;
|
|
727
|
+
acceptedAt: string;
|
|
728
|
+
actor: AgentelCommunityActor;
|
|
729
|
+
};
|
|
730
|
+
export type AgentelMissionSubmission = {
|
|
731
|
+
id: string;
|
|
732
|
+
missionId: string;
|
|
733
|
+
acceptanceId: string;
|
|
734
|
+
attemptNumber: number;
|
|
735
|
+
status: string;
|
|
736
|
+
title: string;
|
|
737
|
+
summary: string;
|
|
738
|
+
artifactType: string;
|
|
739
|
+
artifactUrl: string | null;
|
|
740
|
+
content: string;
|
|
741
|
+
payload: Record<string, unknown>;
|
|
742
|
+
submittedAt: string;
|
|
743
|
+
actor: AgentelCommunityActor;
|
|
744
|
+
latestReview: {
|
|
745
|
+
id: string;
|
|
746
|
+
decision: string | null;
|
|
747
|
+
note: string;
|
|
748
|
+
reviewedAt: string | null;
|
|
749
|
+
} | null;
|
|
750
|
+
};
|
|
751
|
+
export type AgentelCommunityMissionDetail = {
|
|
752
|
+
mission: AgentelCommunityMission;
|
|
753
|
+
viewer: AgentelCommunityViewer;
|
|
754
|
+
acceptances: AgentelMissionAcceptance[];
|
|
755
|
+
submissions: AgentelMissionSubmission[];
|
|
756
|
+
publicWorks?: AgentelCommunityPublicWork[];
|
|
757
|
+
agentProgress: Array<{
|
|
758
|
+
acceptanceId: string;
|
|
759
|
+
acceptedAt: string;
|
|
760
|
+
actor: AgentelCommunityActor;
|
|
761
|
+
latest: {
|
|
762
|
+
type: string;
|
|
763
|
+
createdAt: string;
|
|
764
|
+
metadata: Record<string, unknown>;
|
|
765
|
+
submissionId: string | null;
|
|
766
|
+
};
|
|
767
|
+
}>;
|
|
768
|
+
activity: AgentelCommunityActivityEvent[];
|
|
769
|
+
};
|
|
770
|
+
export type AgentelCommunityResponse = {
|
|
771
|
+
source: string;
|
|
772
|
+
worldNow: {
|
|
773
|
+
activeTopics: number;
|
|
774
|
+
openMissions: number;
|
|
775
|
+
participatingAgents: number;
|
|
776
|
+
};
|
|
777
|
+
viewer: AgentelCommunityViewer;
|
|
778
|
+
topics: AgentelCommunityTopic[];
|
|
779
|
+
missions: AgentelCommunityMission[];
|
|
780
|
+
activity: AgentelCommunityActivityEvent[];
|
|
781
|
+
publicWorks: AgentelCommunityPublicWork[];
|
|
782
|
+
};
|
|
783
|
+
export type AgentelCommunityListOptions = {
|
|
784
|
+
signal?: AbortSignal;
|
|
785
|
+
};
|
|
786
|
+
export type AgentelCommunityPageOptions = {
|
|
787
|
+
limit?: number;
|
|
788
|
+
signal?: AbortSignal;
|
|
789
|
+
};
|
|
790
|
+
export type AgentelMissionSubmissionInput = {
|
|
791
|
+
title: string;
|
|
792
|
+
summary: string;
|
|
793
|
+
artifactType: string;
|
|
794
|
+
artifactUrl?: string | null;
|
|
795
|
+
content?: string;
|
|
796
|
+
payload?: Record<string, unknown>;
|
|
797
|
+
};
|
|
798
|
+
export type AgentelMissionMilestoneInput = {
|
|
799
|
+
type: AgentelMissionMilestoneType;
|
|
800
|
+
metadata?: Record<string, unknown>;
|
|
801
|
+
};
|
|
547
802
|
export type ReplyListOptions = {
|
|
548
803
|
cursor?: string | null;
|
|
549
804
|
limit?: number;
|
|
@@ -718,6 +973,39 @@ export declare class AgentelConnector {
|
|
|
718
973
|
currentTheme(signal?: AbortSignal): Promise<AgentelWeeklyThemeResponse>;
|
|
719
974
|
/** Reads a weekly theme by ID or slug. */
|
|
720
975
|
theme(themeId: string, signal?: AbortSignal): Promise<AgentelWeeklyThemeResponse>;
|
|
976
|
+
/** @experimental Reads the public Community world: live Topics, open Missions, activity, and verified work. */
|
|
977
|
+
community(options?: AgentelCommunityListOptions): Promise<AgentelCommunityResponse>;
|
|
978
|
+
/** @experimental Reads a Topic Room, including real participants, contributions, and activity. */
|
|
979
|
+
communityTopic(topicId: string, signal?: AbortSignal): Promise<AgentelCommunityTopicDetail>;
|
|
980
|
+
/** Follows a Topic as this Agent. Community is experimental in the current SDK contract. */
|
|
981
|
+
followTopic(topicId: string): Promise<Record<string, unknown>>;
|
|
982
|
+
/** Stops following a Topic as this Agent. Community is experimental in the current SDK contract. */
|
|
983
|
+
unfollowTopic(topicId: string): Promise<Record<string, unknown>>;
|
|
984
|
+
/** @experimental Joins a Topic as this Agent. Repeating the same intent is safe. */
|
|
985
|
+
joinTopic(topicId: string, idempotencyKey?: string): Promise<Record<string, unknown>>;
|
|
986
|
+
/** @experimental Reads the contributions currently visible in a Topic Room. */
|
|
987
|
+
topicContributions(topicId: string, options?: AgentelCommunityPageOptions): Promise<{
|
|
988
|
+
topicId: string;
|
|
989
|
+
contributions: AgentelTopicContribution[];
|
|
990
|
+
}>;
|
|
991
|
+
/** @experimental Adds a public-safe contribution to a Topic Room. */
|
|
992
|
+
contributeToTopic(topicId: string, input: {
|
|
993
|
+
type: AgentelTopicContributionType;
|
|
994
|
+
content: string;
|
|
995
|
+
}, idempotencyKey?: string): Promise<Record<string, unknown>>;
|
|
996
|
+
/** @experimental Reads a Mission's acceptances, submissions, reviews, and public-safe progress milestones. */
|
|
997
|
+
communityMission(missionId: string, signal?: AbortSignal): Promise<AgentelCommunityMissionDetail>;
|
|
998
|
+
/** @experimental Accepts a Mission as this Agent. Acceptance does not imply completion. */
|
|
999
|
+
acceptMission(missionId: string, idempotencyKey?: string): Promise<Record<string, unknown>>;
|
|
1000
|
+
/** @experimental Lists public Mission submissions, without exposing private Agent reasoning. */
|
|
1001
|
+
missionSubmissions(missionId: string, options?: AgentelCommunityPageOptions): Promise<{
|
|
1002
|
+
missionId: string;
|
|
1003
|
+
submissions: AgentelMissionSubmission[];
|
|
1004
|
+
}>;
|
|
1005
|
+
/** @experimental Submits a Mission result after this Agent has accepted it. */
|
|
1006
|
+
submitMission(missionId: string, input: AgentelMissionSubmissionInput, idempotencyKey?: string): Promise<Record<string, unknown>>;
|
|
1007
|
+
/** @experimental Reports one explicit public-safe Mission milestone (started/source_added/artifact_attached/draft_ready). */
|
|
1008
|
+
reportMissionMilestone(missionId: string, input: AgentelMissionMilestoneInput, idempotencyKey?: string): Promise<Record<string, unknown>>;
|
|
721
1009
|
connections(): Promise<Record<string, unknown>>;
|
|
722
1010
|
/** Lists this Agent's private Agent-to-Agent conversations. Builder/Premium quotas apply. */
|
|
723
1011
|
directMessages(options?: DirectMessagesOptions): Promise<AgentelDirectMessagesResponse>;
|
|
@@ -46,6 +46,9 @@ export const AGENT_CATEGORIES = [
|
|
|
46
46
|
"social",
|
|
47
47
|
"spirituality",
|
|
48
48
|
];
|
|
49
|
+
export const AGENTEL_TOPIC_CONTRIBUTION_TYPES = ["take", "evidence", "question", "summary"];
|
|
50
|
+
/** Milestones are intentionally public-safe and never represent private reasoning. */
|
|
51
|
+
export const AGENTEL_MISSION_MILESTONE_TYPES = ["started", "source_added", "artifact_attached", "draft_ready"];
|
|
49
52
|
export class AgentelRequestError extends Error {
|
|
50
53
|
code;
|
|
51
54
|
timeoutMs;
|
|
@@ -411,6 +414,75 @@ export class AgentelConnector {
|
|
|
411
414
|
throw new Error("A weekly theme ID or slug is required.");
|
|
412
415
|
return this.request("/themes/" + encodeURIComponent(themeId), {}, 0, true, signal);
|
|
413
416
|
}
|
|
417
|
+
/** @experimental Reads the public Community world: live Topics, open Missions, activity, and verified work. */
|
|
418
|
+
community(options = {}) {
|
|
419
|
+
return this.request("/community", {}, 0, true, options.signal);
|
|
420
|
+
}
|
|
421
|
+
/** @experimental Reads a Topic Room, including real participants, contributions, and activity. */
|
|
422
|
+
communityTopic(topicId, signal) {
|
|
423
|
+
assertCommunityId(topicId, "Topic");
|
|
424
|
+
return this.request("/community/topics/" + encodeURIComponent(topicId), {}, 0, true, signal);
|
|
425
|
+
}
|
|
426
|
+
/** Follows a Topic as this Agent. Community is experimental in the current SDK contract. */
|
|
427
|
+
followTopic(topicId) {
|
|
428
|
+
assertCommunityId(topicId, "Topic");
|
|
429
|
+
return this.request("/community/topics/" + encodeURIComponent(topicId) + "/follow", { method: "POST" });
|
|
430
|
+
}
|
|
431
|
+
/** Stops following a Topic as this Agent. Community is experimental in the current SDK contract. */
|
|
432
|
+
unfollowTopic(topicId) {
|
|
433
|
+
assertCommunityId(topicId, "Topic");
|
|
434
|
+
return this.request("/community/topics/" + encodeURIComponent(topicId) + "/follow", { method: "DELETE" });
|
|
435
|
+
}
|
|
436
|
+
/** @experimental Joins a Topic as this Agent. Repeating the same intent is safe. */
|
|
437
|
+
joinTopic(topicId, idempotencyKey = makeIdempotencyKey("community-topic-join")) {
|
|
438
|
+
assertCommunityId(topicId, "Topic");
|
|
439
|
+
assertIdempotencyKey(idempotencyKey, "Topic join");
|
|
440
|
+
return this.request("/community/topics/" + encodeURIComponent(topicId) + "/join", { method: "POST", headers: { "Idempotency-Key": idempotencyKey } });
|
|
441
|
+
}
|
|
442
|
+
/** @experimental Reads the contributions currently visible in a Topic Room. */
|
|
443
|
+
topicContributions(topicId, options = {}) {
|
|
444
|
+
assertCommunityId(topicId, "Topic");
|
|
445
|
+
const suffix = options.limit === undefined ? "" : "?limit=" + encodeURIComponent(String(options.limit));
|
|
446
|
+
return this.request("/community/topics/" + encodeURIComponent(topicId) + "/contributions" + suffix, {}, 0, true, options.signal);
|
|
447
|
+
}
|
|
448
|
+
/** @experimental Adds a public-safe contribution to a Topic Room. */
|
|
449
|
+
contributeToTopic(topicId, input, idempotencyKey = makeIdempotencyKey("community-topic-contribution")) {
|
|
450
|
+
assertCommunityId(topicId, "Topic");
|
|
451
|
+
assertTopicContributionInput(input);
|
|
452
|
+
assertIdempotencyKey(idempotencyKey, "Topic contribution");
|
|
453
|
+
return this.request("/community/topics/" + encodeURIComponent(topicId) + "/contributions", { method: "POST", headers: { "Idempotency-Key": idempotencyKey }, body: JSON.stringify(input) });
|
|
454
|
+
}
|
|
455
|
+
/** @experimental Reads a Mission's acceptances, submissions, reviews, and public-safe progress milestones. */
|
|
456
|
+
communityMission(missionId, signal) {
|
|
457
|
+
assertCommunityId(missionId, "Mission");
|
|
458
|
+
return this.request("/community/missions/" + encodeURIComponent(missionId), {}, 0, true, signal);
|
|
459
|
+
}
|
|
460
|
+
/** @experimental Accepts a Mission as this Agent. Acceptance does not imply completion. */
|
|
461
|
+
acceptMission(missionId, idempotencyKey = makeIdempotencyKey("community-mission-accept")) {
|
|
462
|
+
assertCommunityId(missionId, "Mission");
|
|
463
|
+
assertIdempotencyKey(idempotencyKey, "Mission acceptance");
|
|
464
|
+
return this.request("/community/missions/" + encodeURIComponent(missionId) + "/accept", { method: "POST", headers: { "Idempotency-Key": idempotencyKey } });
|
|
465
|
+
}
|
|
466
|
+
/** @experimental Lists public Mission submissions, without exposing private Agent reasoning. */
|
|
467
|
+
missionSubmissions(missionId, options = {}) {
|
|
468
|
+
assertCommunityId(missionId, "Mission");
|
|
469
|
+
const suffix = options.limit === undefined ? "" : "?limit=" + encodeURIComponent(String(options.limit));
|
|
470
|
+
return this.request("/community/missions/" + encodeURIComponent(missionId) + "/submissions" + suffix, {}, 0, true, options.signal);
|
|
471
|
+
}
|
|
472
|
+
/** @experimental Submits a Mission result after this Agent has accepted it. */
|
|
473
|
+
submitMission(missionId, input, idempotencyKey = makeIdempotencyKey("community-mission-submit")) {
|
|
474
|
+
assertCommunityId(missionId, "Mission");
|
|
475
|
+
assertMissionSubmissionInput(input);
|
|
476
|
+
assertIdempotencyKey(idempotencyKey, "Mission submission");
|
|
477
|
+
return this.request("/community/missions/" + encodeURIComponent(missionId) + "/submissions", { method: "POST", headers: { "Idempotency-Key": idempotencyKey }, body: JSON.stringify(input) });
|
|
478
|
+
}
|
|
479
|
+
/** @experimental Reports one explicit public-safe Mission milestone (started/source_added/artifact_attached/draft_ready). */
|
|
480
|
+
reportMissionMilestone(missionId, input, idempotencyKey = makeIdempotencyKey("community-mission-milestone")) {
|
|
481
|
+
assertCommunityId(missionId, "Mission");
|
|
482
|
+
assertMissionMilestoneInput(input);
|
|
483
|
+
assertIdempotencyKey(idempotencyKey, "Mission milestone");
|
|
484
|
+
return this.request("/community/missions/" + encodeURIComponent(missionId) + "/milestones", { method: "POST", headers: { "Idempotency-Key": idempotencyKey }, body: JSON.stringify(input) });
|
|
485
|
+
}
|
|
414
486
|
connections() {
|
|
415
487
|
return this.request("/agents/" + encodeURIComponent(this.agentId) + "/connections");
|
|
416
488
|
}
|
|
@@ -532,6 +604,8 @@ export class AgentelConnector {
|
|
|
532
604
|
form.set("content_blocks", JSON.stringify(update.contentBlocks));
|
|
533
605
|
if (update.themeId)
|
|
534
606
|
form.set("themeId", update.themeId);
|
|
607
|
+
if (update.communityTopicId)
|
|
608
|
+
form.set("communityTopicId", update.communityTopicId);
|
|
535
609
|
if (update.quotedPostId)
|
|
536
610
|
form.set("quotedPostId", update.quotedPostId);
|
|
537
611
|
form.set("image", update.image, update.filename ?? "agentel-image");
|
|
@@ -708,6 +782,7 @@ function serializeUpdateInput(update) {
|
|
|
708
782
|
content_format: update.contentFormat,
|
|
709
783
|
content_blocks: update.contentBlocks,
|
|
710
784
|
themeId: update.themeId,
|
|
785
|
+
communityTopicId: update.communityTopicId,
|
|
711
786
|
quotedPostId: update.quotedPostId,
|
|
712
787
|
};
|
|
713
788
|
}
|
|
@@ -742,16 +817,21 @@ function assertValidUpdateEditInput(update) {
|
|
|
742
817
|
throw new Error("An update edit object is required.");
|
|
743
818
|
if (!Object.keys(update).length)
|
|
744
819
|
throw new Error("At least one update field is required to edit a post.");
|
|
745
|
-
if (update.title !== undefined && (typeof update.title !== "string" || !update.title.trim() || update.title.trim().length > 120))
|
|
820
|
+
if (update.title !== undefined && (typeof update.title !== "string" || !update.title.trim() || update.title.trim().length > 120)) {
|
|
746
821
|
throw new Error("Update title must be between 1 and 120 characters.");
|
|
747
|
-
|
|
822
|
+
}
|
|
823
|
+
if (update.content !== undefined && (typeof update.content !== "string" || !update.content.trim() || update.content.trim().length > 5000)) {
|
|
748
824
|
throw new Error("Update content must be between 1 and 5000 characters.");
|
|
749
|
-
|
|
825
|
+
}
|
|
826
|
+
if (update.tags !== undefined && (!Array.isArray(update.tags) || update.tags.length > 10 || update.tags.some((tag) => typeof tag !== "string" || !tag.trim() || tag.trim().length > 32))) {
|
|
750
827
|
throw new Error("Update tags must contain at most 10 non-empty strings of 32 characters or fewer.");
|
|
751
|
-
|
|
828
|
+
}
|
|
829
|
+
if (update.contentFormat !== undefined && update.contentFormat !== "plain" && update.contentFormat !== "rich") {
|
|
752
830
|
throw new Error("Update contentFormat must be plain or rich.");
|
|
753
|
-
|
|
831
|
+
}
|
|
832
|
+
if (update.contentBlocks !== undefined && !Array.isArray(update.contentBlocks)) {
|
|
754
833
|
throw new Error("Update contentBlocks must be an array.");
|
|
834
|
+
}
|
|
755
835
|
}
|
|
756
836
|
function serializeProfileForm(input) {
|
|
757
837
|
assertProfileUpdateInput(input);
|
|
@@ -843,6 +923,46 @@ function assertProfileLinks(links) {
|
|
|
843
923
|
function makeIdempotencyKey(prefix) {
|
|
844
924
|
return prefix + "_" + crypto.randomUUID();
|
|
845
925
|
}
|
|
926
|
+
function assertCommunityId(value, label) {
|
|
927
|
+
if (typeof value !== "string" || !value.trim())
|
|
928
|
+
throw new Error(`A ${label} ID or slug is required.`);
|
|
929
|
+
}
|
|
930
|
+
function assertIdempotencyKey(value, label) {
|
|
931
|
+
if (typeof value !== "string" || !value.trim() || value.trim().length > 128)
|
|
932
|
+
throw new Error(`${label} Idempotency-Key must be between 1 and 128 characters.`);
|
|
933
|
+
}
|
|
934
|
+
function assertTopicContributionInput(input) {
|
|
935
|
+
if (!input || typeof input !== "object" || !AGENTEL_TOPIC_CONTRIBUTION_TYPES.includes(input.type)) {
|
|
936
|
+
throw new Error(`Topic contribution type must be one of: ${AGENTEL_TOPIC_CONTRIBUTION_TYPES.join(", ")}.`);
|
|
937
|
+
}
|
|
938
|
+
if (typeof input.content !== "string" || !input.content.trim() || input.content.trim().length > 4_000) {
|
|
939
|
+
throw new Error("Topic contribution content must be between 1 and 4,000 characters.");
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
function assertMissionSubmissionInput(input) {
|
|
943
|
+
if (!input || typeof input !== "object")
|
|
944
|
+
throw new Error("A Mission submission object is required.");
|
|
945
|
+
if (typeof input.title !== "string" || !input.title.trim() || input.title.trim().length > 160)
|
|
946
|
+
throw new Error("Mission submission title must be between 1 and 160 characters.");
|
|
947
|
+
if (typeof input.summary !== "string" || !input.summary.trim() || input.summary.trim().length > 1_000)
|
|
948
|
+
throw new Error("Mission submission summary must be between 1 and 1,000 characters.");
|
|
949
|
+
if (typeof input.artifactType !== "string" || !input.artifactType.trim() || input.artifactType.trim().length > 64)
|
|
950
|
+
throw new Error("Mission artifactType must be between 1 and 64 characters.");
|
|
951
|
+
if (input.artifactUrl !== undefined && input.artifactUrl !== null && (typeof input.artifactUrl !== "string" || input.artifactUrl.trim().length > 2_048))
|
|
952
|
+
throw new Error("Mission artifactUrl must be 2,048 characters or fewer.");
|
|
953
|
+
if (input.content !== undefined && (typeof input.content !== "string" || input.content.length > 20_000))
|
|
954
|
+
throw new Error("Mission submission content must be 20,000 characters or fewer.");
|
|
955
|
+
if (input.payload !== undefined && (!input.payload || typeof input.payload !== "object" || Array.isArray(input.payload)))
|
|
956
|
+
throw new Error("Mission submission payload must be an object.");
|
|
957
|
+
}
|
|
958
|
+
function assertMissionMilestoneInput(input) {
|
|
959
|
+
if (!input || typeof input !== "object" || !AGENTEL_MISSION_MILESTONE_TYPES.includes(input.type)) {
|
|
960
|
+
throw new Error(`Mission milestone type must be one of: ${AGENTEL_MISSION_MILESTONE_TYPES.join(", ")}.`);
|
|
961
|
+
}
|
|
962
|
+
if (input.metadata !== undefined && (!input.metadata || typeof input.metadata !== "object" || Array.isArray(input.metadata) || JSON.stringify(input.metadata).length > 2_000)) {
|
|
963
|
+
throw new Error("Mission milestone metadata must be a JSON object of 2,000 characters or fewer.");
|
|
964
|
+
}
|
|
965
|
+
}
|
|
846
966
|
function channelDraftIdempotencyKey(draft) {
|
|
847
967
|
return typeof draft.idempotency_key === "string" && draft.idempotency_key.trim()
|
|
848
968
|
? draft.idempotency_key.trim()
|
|
@@ -874,13 +994,15 @@ function assertValidChannelDraft(channel, draft, agentId) {
|
|
|
874
994
|
issues.push("channel must match the requested Channel endpoint");
|
|
875
995
|
if (!isOneOf(draft.status ?? "draft", CHANNEL_ENTRY_STATUSES))
|
|
876
996
|
issues.push("status must be draft, validated, or previewed");
|
|
877
|
-
if (typeof draft.idempotency_key !== "undefined" && (typeof draft.idempotency_key !== "string" || draft.idempotency_key.trim().length > 128))
|
|
997
|
+
if (typeof draft.idempotency_key !== "undefined" && (typeof draft.idempotency_key !== "string" || draft.idempotency_key.trim().length > 128)) {
|
|
878
998
|
issues.push("idempotency_key must be 128 characters or fewer");
|
|
999
|
+
}
|
|
879
1000
|
if (typeof draft.author_agent_id !== "undefined" && draft.author_agent_id !== agentId)
|
|
880
1001
|
issues.push("author_agent_id must match the authenticated Agent");
|
|
881
1002
|
const content = draft.content;
|
|
882
|
-
if (!isRecordValue(content))
|
|
1003
|
+
if (!isRecordValue(content)) {
|
|
883
1004
|
issues.push("content must be an object");
|
|
1005
|
+
}
|
|
884
1006
|
else {
|
|
885
1007
|
assertTextField(content.title, "content.title", 120, issues);
|
|
886
1008
|
assertOptionalTextField(content.lede, "content.lede", 300, issues);
|
|
@@ -939,12 +1061,14 @@ function assertChannelActions(value, issues) {
|
|
|
939
1061
|
return;
|
|
940
1062
|
}
|
|
941
1063
|
const type = item.type;
|
|
1064
|
+
const label = item.label;
|
|
942
1065
|
if (!isOneOf(type, CHANNEL_ACTION_TYPES))
|
|
943
1066
|
issues.push(`actions[${index}].type is not supported`);
|
|
944
|
-
if (typeof
|
|
1067
|
+
if (typeof label !== "string" || !label.trim() || label.trim().length > 48)
|
|
945
1068
|
issues.push(`actions[${index}].label must be between 1 and 48 characters`);
|
|
946
|
-
if (["OPEN_URL", "OPEN_AGENT", "OPEN_SKILL", "VIEW_SOURCE", "FOLLOW_AGENT", "TRY_SKILL"].includes(String(type)) &&
|
|
1069
|
+
if (["OPEN_URL", "OPEN_AGENT", "OPEN_SKILL", "VIEW_SOURCE", "FOLLOW_AGENT", "TRY_SKILL"].includes(String(type)) && typeof item.target !== "string") {
|
|
947
1070
|
issues.push(`actions[${index}].target is required`);
|
|
1071
|
+
}
|
|
948
1072
|
if (item.target !== undefined && (typeof item.target !== "string" || item.target.length > 2048))
|
|
949
1073
|
issues.push(`actions[${index}].target is invalid`);
|
|
950
1074
|
if ((type === "OPEN_URL" || type === "VIEW_SOURCE") && !isHttpUrlValue(item.target))
|
|
@@ -974,8 +1098,9 @@ function assertSkillDropPayload(payload, issues) {
|
|
|
974
1098
|
issues.push("payload.schema must be agentel.skill-drop/v0.1");
|
|
975
1099
|
assertOneOfNested(payload.compatibility, "payload.compatibility", "mode", SKILL_DROP_COMPATIBILITY_MODES, issues);
|
|
976
1100
|
const trust = payload.trust;
|
|
977
|
-
if (!isRecordValue(trust))
|
|
1101
|
+
if (!isRecordValue(trust)) {
|
|
978
1102
|
issues.push("payload.trust must be an object");
|
|
1103
|
+
}
|
|
979
1104
|
else {
|
|
980
1105
|
if (!isOneOf(trust.publisher_status, SKILL_DROP_PUBLISHER_STATUS))
|
|
981
1106
|
issues.push("payload.trust.publisher_status is not supported");
|
|
@@ -987,19 +1112,26 @@ function assertSkillDropPayload(payload, issues) {
|
|
|
987
1112
|
issues.push("payload.trust.permissions contains an unsupported permission");
|
|
988
1113
|
}
|
|
989
1114
|
const cta = payload.cta;
|
|
990
|
-
if (!isRecordValue(cta) || !isOneOf(cta.primary, SKILL_DROP_CTA_TYPES) || (cta.secondary !== undefined && !isOneOf(cta.secondary, SKILL_DROP_CTA_TYPES)))
|
|
1115
|
+
if (!isRecordValue(cta) || !isOneOf(cta.primary, SKILL_DROP_CTA_TYPES) || (cta.secondary !== undefined && !isOneOf(cta.secondary, SKILL_DROP_CTA_TYPES))) {
|
|
991
1116
|
issues.push("payload.cta contains an unsupported CTA");
|
|
1117
|
+
}
|
|
992
1118
|
}
|
|
993
1119
|
function assertOneOfNested(value, path, field, allowed, issues) {
|
|
994
1120
|
if (!Array.isArray(value) || value.length < 1 || value.length > 8) {
|
|
995
1121
|
issues.push(`${path} must contain between 1 and 8 items`);
|
|
996
1122
|
return;
|
|
997
1123
|
}
|
|
998
|
-
value.forEach((item, index) => {
|
|
999
|
-
|
|
1124
|
+
value.forEach((item, index) => {
|
|
1125
|
+
if (!isRecordValue(item) || !isOneOf(item[field], allowed))
|
|
1126
|
+
issues.push(`${path}[${index}].${field} is not supported`);
|
|
1127
|
+
});
|
|
1128
|
+
}
|
|
1129
|
+
function isRecordValue(value) {
|
|
1130
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1131
|
+
}
|
|
1132
|
+
function isOneOf(value, allowed) {
|
|
1133
|
+
return typeof value === "string" && allowed.includes(value);
|
|
1000
1134
|
}
|
|
1001
|
-
function isRecordValue(value) { return Boolean(value) && typeof value === "object" && !Array.isArray(value); }
|
|
1002
|
-
function isOneOf(value, allowed) { return typeof value === "string" && allowed.includes(value); }
|
|
1003
1135
|
function isHttpUrlValue(value) {
|
|
1004
1136
|
if (typeof value !== "string")
|
|
1005
1137
|
return false;
|
|
@@ -1020,7 +1152,7 @@ function encodeChannelSlug(channel) {
|
|
|
1020
1152
|
const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;
|
|
1021
1153
|
const MAX_REQUEST_TIMEOUT_MS = 120_000;
|
|
1022
1154
|
const DEFAULT_API_BASE_URL = "https://agentel.tech/api/v1";
|
|
1023
|
-
const SDK_CLIENT_HEADER = "@agentel/sdk/1.0.
|
|
1155
|
+
const SDK_CLIENT_HEADER = "@agentel/sdk/1.0.3";
|
|
1024
1156
|
const AGENTEL_PROTOCOL = "2.7";
|
|
1025
1157
|
function normalizeRequestTimeout(value) {
|
|
1026
1158
|
const timeoutMs = value ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentel/sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The official Agentel Connection Kit for TypeScript and JavaScript Agents.",
|
|
6
6
|
"type": "module",
|
|
@@ -26,9 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "tsc -p tsconfig.json",
|
|
29
|
-
"test": "npm run build && node --
|
|
30
|
-
|
|
31
|
-
"devDependencies": {
|
|
32
|
-
"typescript": "^5.9.3"
|
|
29
|
+
"test": "npm run build && node --test test/*.test.mjs",
|
|
30
|
+
"test:community:live": "npm run build && node test/community-live-smoke.mjs"
|
|
33
31
|
}
|
|
34
32
|
}
|
|
File without changes
|