@xfxstudio/claworld 0.2.11 → 0.2.12

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.
@@ -0,0 +1,142 @@
1
+ function normalizeBoolean(value, fallback = false) {
2
+ if (typeof value === 'boolean') return value;
3
+ return fallback;
4
+ }
5
+
6
+ function normalizePositiveInteger(value, fallback = null) {
7
+ const normalized = Number(value);
8
+ if (!Number.isFinite(normalized) || normalized <= 0) return fallback;
9
+ return Math.floor(normalized);
10
+ }
11
+
12
+ async function maybeGenerateShareCard({
13
+ agentCardService,
14
+ agentId,
15
+ identityStatus,
16
+ generateShareCard = false,
17
+ expiresInSeconds = null,
18
+ forceRegenerate = true,
19
+ }) {
20
+ if (!generateShareCard) return undefined;
21
+ if (identityStatus?.ready !== true) {
22
+ return {
23
+ status: 'unavailable',
24
+ reason: 'public_identity_not_ready',
25
+ };
26
+ }
27
+
28
+ try {
29
+ return await agentCardService.renderCard({
30
+ agentId,
31
+ expiresInSeconds: normalizePositiveInteger(expiresInSeconds, null),
32
+ forceRegenerate: normalizeBoolean(forceRegenerate, true),
33
+ });
34
+ } catch (error) {
35
+ return {
36
+ status: 'unavailable',
37
+ reason: 'generation_failed',
38
+ message: error?.publicMessage || error?.message || 'share card generation failed',
39
+ };
40
+ }
41
+ }
42
+
43
+ export function createProfileService({
44
+ publicIdentityService,
45
+ agentCardService,
46
+ } = {}) {
47
+ if (!publicIdentityService) {
48
+ throw new Error('profile_service_requires_public_identity_service');
49
+ }
50
+ if (!agentCardService) {
51
+ throw new Error('profile_service_requires_agent_card_service');
52
+ }
53
+
54
+ return {
55
+ getPublicIdentityStatus(input = {}) {
56
+ return publicIdentityService.getPublicIdentityStatus(input);
57
+ },
58
+
59
+ updatePublicIdentity(input = {}) {
60
+ return publicIdentityService.updatePublicIdentity(input);
61
+ },
62
+
63
+ assertPublicIdentityReady(input = {}) {
64
+ return publicIdentityService.assertPublicIdentityReady(input);
65
+ },
66
+
67
+ async getProfile({
68
+ agentId,
69
+ generateShareCard = false,
70
+ expiresInSeconds = null,
71
+ forceRegenerate = true,
72
+ } = {}) {
73
+ const identityStatus = publicIdentityService.getPublicIdentityStatus({ agentId });
74
+ const shareCard = await maybeGenerateShareCard({
75
+ agentCardService,
76
+ agentId,
77
+ identityStatus,
78
+ generateShareCard,
79
+ expiresInSeconds,
80
+ forceRegenerate,
81
+ });
82
+ return shareCard === undefined
83
+ ? identityStatus
84
+ : {
85
+ ...identityStatus,
86
+ shareCard,
87
+ };
88
+ },
89
+
90
+ async updateProfileIdentity({
91
+ agentId,
92
+ displayName,
93
+ generateShareCard = true,
94
+ expiresInSeconds = null,
95
+ forceRegenerate = true,
96
+ } = {}) {
97
+ const identityStatus = await publicIdentityService.updatePublicIdentity({
98
+ agentId,
99
+ displayName,
100
+ });
101
+ const shareCard = await maybeGenerateShareCard({
102
+ agentCardService,
103
+ agentId,
104
+ identityStatus,
105
+ generateShareCard,
106
+ expiresInSeconds,
107
+ forceRegenerate,
108
+ });
109
+ return shareCard === undefined
110
+ ? identityStatus
111
+ : {
112
+ ...identityStatus,
113
+ shareCard,
114
+ };
115
+ },
116
+
117
+ async executeProfileAction({
118
+ action = 'view',
119
+ agentId,
120
+ displayName = null,
121
+ generateShareCard = false,
122
+ expiresInSeconds = null,
123
+ forceRegenerate = true,
124
+ } = {}) {
125
+ if (action === 'update_identity') {
126
+ return this.updateProfileIdentity({
127
+ agentId,
128
+ displayName,
129
+ generateShareCard,
130
+ expiresInSeconds,
131
+ forceRegenerate,
132
+ });
133
+ }
134
+ return this.getProfile({
135
+ agentId,
136
+ generateShareCard,
137
+ expiresInSeconds,
138
+ forceRegenerate,
139
+ });
140
+ },
141
+ };
142
+ }
@@ -1,5 +1,45 @@
1
1
  import { resolveAuthenticatedAgentId } from '../../lib/http-auth.js';
2
2
 
3
+ function normalizeBoolean(value, fallback = false) {
4
+ if (typeof value === 'boolean') return value;
5
+ if (typeof value === 'string') {
6
+ const normalized = value.trim().toLowerCase();
7
+ if (normalized === 'true') return true;
8
+ if (normalized === 'false') return false;
9
+ }
10
+ return fallback;
11
+ }
12
+
13
+ function normalizePositiveInteger(value, fallback = null) {
14
+ const normalized = Number(value);
15
+ if (!Number.isFinite(normalized) || normalized <= 0) return fallback;
16
+ return Math.floor(normalized);
17
+ }
18
+
19
+ function buildAbsoluteUrl(req, publicPath) {
20
+ return `${req.protocol}://${req.get('host')}${publicPath}`;
21
+ }
22
+
23
+ function normalizeShareCard(req, shareCard = undefined) {
24
+ if (shareCard === undefined) return undefined;
25
+ if (!shareCard || typeof shareCard !== 'object') return shareCard;
26
+
27
+ const card = shareCard.card && typeof shareCard.card === 'object' ? shareCard.card : null;
28
+ if (!card) return shareCard;
29
+
30
+ const imageUrl = card.imageUrl || (card.publicPath ? buildAbsoluteUrl(req, card.publicPath) : null);
31
+ const downloadUrl = card.downloadUrl || imageUrl;
32
+ if (!imageUrl && !downloadUrl) return shareCard;
33
+ return {
34
+ ...shareCard,
35
+ card: {
36
+ ...card,
37
+ ...(imageUrl ? { imageUrl } : {}),
38
+ ...(downloadUrl ? { downloadUrl } : {}),
39
+ },
40
+ };
41
+ }
42
+
3
43
  function sendProfileError(res, error) {
4
44
  const status = Number.isInteger(error?.status) ? error.status : 500;
5
45
  if (error?.responseBody && typeof error.responseBody === 'object') {
@@ -17,6 +57,66 @@ function sendMissingAgentIdentity(res) {
17
57
  }
18
58
 
19
59
  export function registerPublicIdentityRoutes(app, { publicIdentityService, store }) {
60
+ app.get('/v1/profile', async (req, res) => {
61
+ const authAgent = resolveAuthenticatedAgentId({
62
+ store,
63
+ req,
64
+ providedAgentId: req.query.agentId,
65
+ fieldName: 'agentId',
66
+ });
67
+ if (!authAgent.ok) return res.status(authAgent.status).json(authAgent.body);
68
+ if (!authAgent.agentId) return sendMissingAgentIdentity(res);
69
+
70
+ try {
71
+ const result = await publicIdentityService.getProfile({
72
+ agentId: authAgent.agentId,
73
+ generateShareCard: normalizeBoolean(req.query.generateShareCard, false),
74
+ expiresInSeconds: normalizePositiveInteger(req.query.expiresInSeconds, null),
75
+ forceRegenerate: normalizeBoolean(req.query.forceRegenerate, true),
76
+ });
77
+ return res.json({
78
+ ...result,
79
+ ...(Object.prototype.hasOwnProperty.call(result, 'shareCard')
80
+ ? { shareCard: normalizeShareCard(req, result.shareCard) }
81
+ : {}),
82
+ });
83
+ } catch (error) {
84
+ return sendProfileError(res, error);
85
+ }
86
+ });
87
+
88
+ app.post('/v1/profile', async (req, res) => {
89
+ const authAgent = resolveAuthenticatedAgentId({
90
+ store,
91
+ req,
92
+ providedAgentId: req.body?.agentId,
93
+ fieldName: 'agentId',
94
+ });
95
+ if (!authAgent.ok) return res.status(authAgent.status).json(authAgent.body);
96
+ if (!authAgent.agentId) return sendMissingAgentIdentity(res);
97
+
98
+ try {
99
+ const action = String(req.body?.action || '').trim() || (req.body?.displayName ? 'update_identity' : 'view');
100
+ const result = await publicIdentityService.executeProfileAction({
101
+ action,
102
+ agentId: authAgent.agentId,
103
+ displayName: req.body?.displayName,
104
+ generateShareCard: normalizeBoolean(req.body?.generateShareCard, action === 'update_identity'),
105
+ expiresInSeconds: normalizePositiveInteger(req.body?.expiresInSeconds, null),
106
+ forceRegenerate: normalizeBoolean(req.body?.forceRegenerate, true),
107
+ });
108
+ return res.json({
109
+ action,
110
+ ...result,
111
+ ...(Object.prototype.hasOwnProperty.call(result, 'shareCard')
112
+ ? { shareCard: normalizeShareCard(req, result.shareCard) }
113
+ : {}),
114
+ });
115
+ } catch (error) {
116
+ return sendProfileError(res, error);
117
+ }
118
+ });
119
+
20
120
  app.get('/v1/profile/public-identity', (req, res) => {
21
121
  const authAgent = resolveAuthenticatedAgentId({
22
122
  store,
@@ -49,9 +49,11 @@ function createInvalidPublicIdentityRequest(fieldId, message, code = 'invalid_pu
49
49
  return error;
50
50
  }
51
51
 
52
+ const DEFAULT_PUBLIC_IDENTITY_NEXT_TOOL = 'claworld_profile';
53
+
52
54
  function createPublicIdentityIncompleteError(agent, {
53
55
  capability = null,
54
- nextTool = 'claworld_update_public_identity',
56
+ nextTool = DEFAULT_PUBLIC_IDENTITY_NEXT_TOOL,
55
57
  } = {}) {
56
58
  const projected = projectPublicIdentityStatus(agent, { nextTool });
57
59
  const capabilityLabel = normalizeText(capability, 'this Claworld capability');
@@ -73,7 +75,7 @@ function createPublicIdentityIncompleteError(agent, {
73
75
  }
74
76
 
75
77
  function projectPublicIdentityStatus(agent, {
76
- nextTool = 'claworld_update_public_identity',
78
+ nextTool = DEFAULT_PUBLIC_IDENTITY_NEXT_TOOL,
77
79
  conversationFeedbackService = null,
78
80
  } = {}) {
79
81
  const publicIdentity = resolvePublicIdentity(agent);