@alfe.ai/openclaw-identity 0.0.19 → 0.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.
- package/dist/plugin2.cjs +96 -17
- package/dist/plugin2.js +96 -17
- package/package.json +3 -3
package/dist/plugin2.cjs
CHANGED
|
@@ -147,6 +147,75 @@ function setCachedResolve(key, value) {
|
|
|
147
147
|
expiresAt: Date.now() + RESOLVE_CACHE_TTL_MS
|
|
148
148
|
});
|
|
149
149
|
}
|
|
150
|
+
function resolveCachedSession(params) {
|
|
151
|
+
const conversationId = params.conversationId;
|
|
152
|
+
const explicitClaimed = params.claimedIdentityId;
|
|
153
|
+
if (!conversationId) return {
|
|
154
|
+
hit: false,
|
|
155
|
+
conversationId: null
|
|
156
|
+
};
|
|
157
|
+
const cached = getCachedResolve(conversationId);
|
|
158
|
+
if (cached?.identityId == null) return {
|
|
159
|
+
hit: false,
|
|
160
|
+
conversationId,
|
|
161
|
+
error: "session_identity_unavailable: inbound identity cache miss for this conversationId. Pass claimedIdentityId explicitly, or wait for the next inbound message."
|
|
162
|
+
};
|
|
163
|
+
if (explicitClaimed && explicitClaimed !== cached.identityId) return {
|
|
164
|
+
hit: false,
|
|
165
|
+
conversationId,
|
|
166
|
+
error: "claimedIdentityId conflicts with the inbound session identity. Either omit claimedIdentityId (recommended) or remove conversationId."
|
|
167
|
+
};
|
|
168
|
+
return {
|
|
169
|
+
hit: true,
|
|
170
|
+
cached: {
|
|
171
|
+
...cached,
|
|
172
|
+
identityId: cached.identityId
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Resolution order for the request flow (needs the full requester tuple):
|
|
178
|
+
* 1. conversationId hits cache → derive all four from cached entry.
|
|
179
|
+
* 2. conversationId set but cache miss → reject session_identity_unavailable.
|
|
180
|
+
* 3. No conversationId AND no claimedIdentityId → reject missing_identity.
|
|
181
|
+
* 4. claimedIdentityId + full requester tuple supplied → legacy explicit
|
|
182
|
+
* flow. Layer 1's server-side `no_op_already_verified` guard catches
|
|
183
|
+
* the common misuse case (looking up an existing identity by name).
|
|
184
|
+
*/
|
|
185
|
+
function resolveRequesterContext(params) {
|
|
186
|
+
const session = resolveCachedSession(params);
|
|
187
|
+
if (session.hit) return {
|
|
188
|
+
claimedIdentityId: session.cached.identityId,
|
|
189
|
+
requestingIdentityId: session.cached.identityId,
|
|
190
|
+
requestingProvider: session.cached.senderProvider,
|
|
191
|
+
requestingPlatformId: session.cached.senderPlatformId
|
|
192
|
+
};
|
|
193
|
+
if (session.conversationId) return { error: session.error };
|
|
194
|
+
const claimedIdentityId = params.claimedIdentityId;
|
|
195
|
+
const requestingIdentityId = params.requestingIdentityId;
|
|
196
|
+
const requestingProvider = params.requestingProvider;
|
|
197
|
+
const requestingPlatformId = params.requestingPlatformId;
|
|
198
|
+
if (!claimedIdentityId) return { error: "missing_identity: pass conversationId (recommended — auto-binds to the inbound sender) or claimedIdentityId + requestingIdentityId + requestingProvider + requestingPlatformId explicitly." };
|
|
199
|
+
if (!requestingIdentityId || !requestingProvider || !requestingPlatformId) return { error: "missing_identity: when claimedIdentityId is supplied without conversationId, requestingIdentityId / requestingProvider / requestingPlatformId are also required. Prefer passing conversationId so all four are auto-derived." };
|
|
200
|
+
return {
|
|
201
|
+
claimedIdentityId,
|
|
202
|
+
requestingIdentityId,
|
|
203
|
+
requestingProvider,
|
|
204
|
+
requestingPlatformId
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Confirm flow only needs `claimedIdentityId` — same conflict / cache-miss
|
|
209
|
+
* branches as the requester resolver, but no requester tuple.
|
|
210
|
+
*/
|
|
211
|
+
function resolveClaimedIdentity(params) {
|
|
212
|
+
const session = resolveCachedSession(params);
|
|
213
|
+
if (session.hit) return { claimedIdentityId: session.cached.identityId };
|
|
214
|
+
if (session.conversationId) return { error: session.error };
|
|
215
|
+
const claimedIdentityId = params.claimedIdentityId;
|
|
216
|
+
if (!claimedIdentityId) return { error: "missing_identity: pass conversationId (recommended — auto-binds to the inbound sender) or claimedIdentityId explicitly." };
|
|
217
|
+
return { claimedIdentityId };
|
|
218
|
+
}
|
|
150
219
|
function ok(data) {
|
|
151
220
|
return {
|
|
152
221
|
content: [{
|
|
@@ -330,12 +399,13 @@ const plugin = {
|
|
|
330
399
|
}),
|
|
331
400
|
defineTool({
|
|
332
401
|
name: "request_identity_verification",
|
|
333
|
-
description: "Send a verification phrase to
|
|
402
|
+
description: "Send a verification phrase to the inbound user's email or mobile to prove they own that contact endpoint. Use when the user has just told you their email or mobile number and you want them to confirm it. PASS conversationId (from the inbound message metadata) — that auto-binds the verification to the inbound sender's identity (the WhatsApp / SMS / Discord / Google Chat user who just spoke). Any merge into a pre-existing account with the same contact happens automatically. Do NOT pass claimedIdentityId yourself unless you have a specific reason to verify a different identity than the inbound sender; looking up an identity by name and passing it here is a footgun and the server will reject with no_op_already_verified.",
|
|
334
403
|
parameters: _sinclair_typebox.Type.Object({
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
404
|
+
conversationId: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.String({ description: "Conversation ID from the inbound message — the daemon attaches this to every message. Pass it to auto-bind the verification to the inbound sender's identity. When set you should NOT also pass claimedIdentityId / requestingIdentityId / requestingProvider / requestingPlatformId." })),
|
|
405
|
+
claimedIdentityId: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.String({ description: "Override for the inbound sender's identity. NEVER set this from a lookup_identity result — that's a footgun (the verification will no-op). Leave unset and pass conversationId so the inbound identity is used automatically. Only set this for explicit non-inbound verification flows (rare — dashboard / admin only)." })),
|
|
406
|
+
requestingIdentityId: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.String({ description: "Identity of the person making the claim. Auto-derived from conversationId; only set explicitly when conversationId is omitted." })),
|
|
407
|
+
requestingProvider: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.String({ description: "Provider the requester is on (discord, slack, whatsapp, etc.). Auto-derived from conversationId; only set explicitly when conversationId is omitted." })),
|
|
408
|
+
requestingPlatformId: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.String({ description: "Requester's provider-specific user ID. Auto-derived from conversationId; only set explicitly when conversationId is omitted." })),
|
|
339
409
|
contactEmail: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.String({ description: "Email to verify (mutually exclusive with contactMobile)" })),
|
|
340
410
|
contactMobile: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.String({ description: "E.164 mobile to verify (mutually exclusive with contactEmail)" })),
|
|
341
411
|
preferredChannel: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.String({ description: "When neither contactEmail nor contactMobile is provided, pick which existing verified contact to deliver to: 'mobile' or 'email'" }))
|
|
@@ -351,11 +421,13 @@ const plugin = {
|
|
|
351
421
|
channel: "mobile",
|
|
352
422
|
value: contactMobile
|
|
353
423
|
} : void 0;
|
|
424
|
+
const resolved = resolveRequesterContext(params);
|
|
425
|
+
if ("error" in resolved) return Promise.resolve({ error: resolved.error });
|
|
354
426
|
return client.requestIdentityVerification({
|
|
355
|
-
claimedIdentityId:
|
|
356
|
-
requestingIdentityId:
|
|
357
|
-
requestingProvider:
|
|
358
|
-
requestingPlatformId:
|
|
427
|
+
claimedIdentityId: resolved.claimedIdentityId,
|
|
428
|
+
requestingIdentityId: resolved.requestingIdentityId,
|
|
429
|
+
requestingProvider: resolved.requestingProvider,
|
|
430
|
+
requestingPlatformId: resolved.requestingPlatformId,
|
|
359
431
|
preferredChannel: params.preferredChannel,
|
|
360
432
|
contact
|
|
361
433
|
});
|
|
@@ -363,17 +435,22 @@ const plugin = {
|
|
|
363
435
|
}),
|
|
364
436
|
defineTool({
|
|
365
437
|
name: "confirm_identity_verification",
|
|
366
|
-
description: "Confirm a verification by submitting the phrase the user received. Returns `{ verified, identityId, action }` where `action` is 'merged' (the verified contact already lived on another identity, which is now the survivor) or 'contact_verified' (the contact was attached to the claimed identity).",
|
|
438
|
+
description: "Confirm a verification by submitting the phrase the user received. Returns `{ verified, identityId, action }` where `action` is 'merged' (the verified contact already lived on another identity, which is now the survivor) or 'contact_verified' (the contact was attached to the claimed identity). PASS the same conversationId you used on request_identity_verification — claimedIdentityId is auto-derived from it.",
|
|
367
439
|
parameters: _sinclair_typebox.Type.Object({
|
|
368
|
-
|
|
440
|
+
conversationId: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.String({ description: "Conversation ID from the inbound message — same one passed to request_identity_verification. Auto-binds claimedIdentityId to the inbound sender." })),
|
|
441
|
+
claimedIdentityId: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.String({ description: "Override for the inbound sender's identity. Must match the value used on the request. Leave unset and pass conversationId." })),
|
|
369
442
|
verificationId: _sinclair_typebox.Type.String({ description: "Verification ID returned from request_identity_verification" }),
|
|
370
443
|
phrase: _sinclair_typebox.Type.String({ description: "Three-word phrase the person received via mobile or email" })
|
|
371
444
|
}),
|
|
372
|
-
handler: (params) =>
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
445
|
+
handler: (params) => {
|
|
446
|
+
const resolved = resolveClaimedIdentity(params);
|
|
447
|
+
if ("error" in resolved) return Promise.resolve({ error: resolved.error });
|
|
448
|
+
return client.confirmIdentityVerification({
|
|
449
|
+
claimedIdentityId: resolved.claimedIdentityId,
|
|
450
|
+
verificationId: params.verificationId,
|
|
451
|
+
phrase: params.phrase
|
|
452
|
+
});
|
|
453
|
+
}
|
|
377
454
|
})
|
|
378
455
|
];
|
|
379
456
|
for (const tool of tools) api.registerTool(tool);
|
|
@@ -414,7 +491,9 @@ const plugin = {
|
|
|
414
491
|
setCachedResolve(cacheKey, {
|
|
415
492
|
identityId: r.identityId,
|
|
416
493
|
status: r.status,
|
|
417
|
-
permissions: [...r.permissions, ...forwarded]
|
|
494
|
+
permissions: [...r.permissions, ...forwarded],
|
|
495
|
+
senderProvider: provider,
|
|
496
|
+
senderPlatformId: senderId
|
|
418
497
|
});
|
|
419
498
|
if (r.identityId == null) {
|
|
420
499
|
log.warn(`Identity not provisioned for ${provider}:${senderId} — blocking inbound message`);
|
package/dist/plugin2.js
CHANGED
|
@@ -147,6 +147,75 @@ function setCachedResolve(key, value) {
|
|
|
147
147
|
expiresAt: Date.now() + RESOLVE_CACHE_TTL_MS
|
|
148
148
|
});
|
|
149
149
|
}
|
|
150
|
+
function resolveCachedSession(params) {
|
|
151
|
+
const conversationId = params.conversationId;
|
|
152
|
+
const explicitClaimed = params.claimedIdentityId;
|
|
153
|
+
if (!conversationId) return {
|
|
154
|
+
hit: false,
|
|
155
|
+
conversationId: null
|
|
156
|
+
};
|
|
157
|
+
const cached = getCachedResolve(conversationId);
|
|
158
|
+
if (cached?.identityId == null) return {
|
|
159
|
+
hit: false,
|
|
160
|
+
conversationId,
|
|
161
|
+
error: "session_identity_unavailable: inbound identity cache miss for this conversationId. Pass claimedIdentityId explicitly, or wait for the next inbound message."
|
|
162
|
+
};
|
|
163
|
+
if (explicitClaimed && explicitClaimed !== cached.identityId) return {
|
|
164
|
+
hit: false,
|
|
165
|
+
conversationId,
|
|
166
|
+
error: "claimedIdentityId conflicts with the inbound session identity. Either omit claimedIdentityId (recommended) or remove conversationId."
|
|
167
|
+
};
|
|
168
|
+
return {
|
|
169
|
+
hit: true,
|
|
170
|
+
cached: {
|
|
171
|
+
...cached,
|
|
172
|
+
identityId: cached.identityId
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Resolution order for the request flow (needs the full requester tuple):
|
|
178
|
+
* 1. conversationId hits cache → derive all four from cached entry.
|
|
179
|
+
* 2. conversationId set but cache miss → reject session_identity_unavailable.
|
|
180
|
+
* 3. No conversationId AND no claimedIdentityId → reject missing_identity.
|
|
181
|
+
* 4. claimedIdentityId + full requester tuple supplied → legacy explicit
|
|
182
|
+
* flow. Layer 1's server-side `no_op_already_verified` guard catches
|
|
183
|
+
* the common misuse case (looking up an existing identity by name).
|
|
184
|
+
*/
|
|
185
|
+
function resolveRequesterContext(params) {
|
|
186
|
+
const session = resolveCachedSession(params);
|
|
187
|
+
if (session.hit) return {
|
|
188
|
+
claimedIdentityId: session.cached.identityId,
|
|
189
|
+
requestingIdentityId: session.cached.identityId,
|
|
190
|
+
requestingProvider: session.cached.senderProvider,
|
|
191
|
+
requestingPlatformId: session.cached.senderPlatformId
|
|
192
|
+
};
|
|
193
|
+
if (session.conversationId) return { error: session.error };
|
|
194
|
+
const claimedIdentityId = params.claimedIdentityId;
|
|
195
|
+
const requestingIdentityId = params.requestingIdentityId;
|
|
196
|
+
const requestingProvider = params.requestingProvider;
|
|
197
|
+
const requestingPlatformId = params.requestingPlatformId;
|
|
198
|
+
if (!claimedIdentityId) return { error: "missing_identity: pass conversationId (recommended — auto-binds to the inbound sender) or claimedIdentityId + requestingIdentityId + requestingProvider + requestingPlatformId explicitly." };
|
|
199
|
+
if (!requestingIdentityId || !requestingProvider || !requestingPlatformId) return { error: "missing_identity: when claimedIdentityId is supplied without conversationId, requestingIdentityId / requestingProvider / requestingPlatformId are also required. Prefer passing conversationId so all four are auto-derived." };
|
|
200
|
+
return {
|
|
201
|
+
claimedIdentityId,
|
|
202
|
+
requestingIdentityId,
|
|
203
|
+
requestingProvider,
|
|
204
|
+
requestingPlatformId
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Confirm flow only needs `claimedIdentityId` — same conflict / cache-miss
|
|
209
|
+
* branches as the requester resolver, but no requester tuple.
|
|
210
|
+
*/
|
|
211
|
+
function resolveClaimedIdentity(params) {
|
|
212
|
+
const session = resolveCachedSession(params);
|
|
213
|
+
if (session.hit) return { claimedIdentityId: session.cached.identityId };
|
|
214
|
+
if (session.conversationId) return { error: session.error };
|
|
215
|
+
const claimedIdentityId = params.claimedIdentityId;
|
|
216
|
+
if (!claimedIdentityId) return { error: "missing_identity: pass conversationId (recommended — auto-binds to the inbound sender) or claimedIdentityId explicitly." };
|
|
217
|
+
return { claimedIdentityId };
|
|
218
|
+
}
|
|
150
219
|
function ok(data) {
|
|
151
220
|
return {
|
|
152
221
|
content: [{
|
|
@@ -330,12 +399,13 @@ const plugin = {
|
|
|
330
399
|
}),
|
|
331
400
|
defineTool({
|
|
332
401
|
name: "request_identity_verification",
|
|
333
|
-
description: "Send a verification phrase to
|
|
402
|
+
description: "Send a verification phrase to the inbound user's email or mobile to prove they own that contact endpoint. Use when the user has just told you their email or mobile number and you want them to confirm it. PASS conversationId (from the inbound message metadata) — that auto-binds the verification to the inbound sender's identity (the WhatsApp / SMS / Discord / Google Chat user who just spoke). Any merge into a pre-existing account with the same contact happens automatically. Do NOT pass claimedIdentityId yourself unless you have a specific reason to verify a different identity than the inbound sender; looking up an identity by name and passing it here is a footgun and the server will reject with no_op_already_verified.",
|
|
334
403
|
parameters: Type.Object({
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
404
|
+
conversationId: Type.Optional(Type.String({ description: "Conversation ID from the inbound message — the daemon attaches this to every message. Pass it to auto-bind the verification to the inbound sender's identity. When set you should NOT also pass claimedIdentityId / requestingIdentityId / requestingProvider / requestingPlatformId." })),
|
|
405
|
+
claimedIdentityId: Type.Optional(Type.String({ description: "Override for the inbound sender's identity. NEVER set this from a lookup_identity result — that's a footgun (the verification will no-op). Leave unset and pass conversationId so the inbound identity is used automatically. Only set this for explicit non-inbound verification flows (rare — dashboard / admin only)." })),
|
|
406
|
+
requestingIdentityId: Type.Optional(Type.String({ description: "Identity of the person making the claim. Auto-derived from conversationId; only set explicitly when conversationId is omitted." })),
|
|
407
|
+
requestingProvider: Type.Optional(Type.String({ description: "Provider the requester is on (discord, slack, whatsapp, etc.). Auto-derived from conversationId; only set explicitly when conversationId is omitted." })),
|
|
408
|
+
requestingPlatformId: Type.Optional(Type.String({ description: "Requester's provider-specific user ID. Auto-derived from conversationId; only set explicitly when conversationId is omitted." })),
|
|
339
409
|
contactEmail: Type.Optional(Type.String({ description: "Email to verify (mutually exclusive with contactMobile)" })),
|
|
340
410
|
contactMobile: Type.Optional(Type.String({ description: "E.164 mobile to verify (mutually exclusive with contactEmail)" })),
|
|
341
411
|
preferredChannel: Type.Optional(Type.String({ description: "When neither contactEmail nor contactMobile is provided, pick which existing verified contact to deliver to: 'mobile' or 'email'" }))
|
|
@@ -351,11 +421,13 @@ const plugin = {
|
|
|
351
421
|
channel: "mobile",
|
|
352
422
|
value: contactMobile
|
|
353
423
|
} : void 0;
|
|
424
|
+
const resolved = resolveRequesterContext(params);
|
|
425
|
+
if ("error" in resolved) return Promise.resolve({ error: resolved.error });
|
|
354
426
|
return client.requestIdentityVerification({
|
|
355
|
-
claimedIdentityId:
|
|
356
|
-
requestingIdentityId:
|
|
357
|
-
requestingProvider:
|
|
358
|
-
requestingPlatformId:
|
|
427
|
+
claimedIdentityId: resolved.claimedIdentityId,
|
|
428
|
+
requestingIdentityId: resolved.requestingIdentityId,
|
|
429
|
+
requestingProvider: resolved.requestingProvider,
|
|
430
|
+
requestingPlatformId: resolved.requestingPlatformId,
|
|
359
431
|
preferredChannel: params.preferredChannel,
|
|
360
432
|
contact
|
|
361
433
|
});
|
|
@@ -363,17 +435,22 @@ const plugin = {
|
|
|
363
435
|
}),
|
|
364
436
|
defineTool({
|
|
365
437
|
name: "confirm_identity_verification",
|
|
366
|
-
description: "Confirm a verification by submitting the phrase the user received. Returns `{ verified, identityId, action }` where `action` is 'merged' (the verified contact already lived on another identity, which is now the survivor) or 'contact_verified' (the contact was attached to the claimed identity).",
|
|
438
|
+
description: "Confirm a verification by submitting the phrase the user received. Returns `{ verified, identityId, action }` where `action` is 'merged' (the verified contact already lived on another identity, which is now the survivor) or 'contact_verified' (the contact was attached to the claimed identity). PASS the same conversationId you used on request_identity_verification — claimedIdentityId is auto-derived from it.",
|
|
367
439
|
parameters: Type.Object({
|
|
368
|
-
|
|
440
|
+
conversationId: Type.Optional(Type.String({ description: "Conversation ID from the inbound message — same one passed to request_identity_verification. Auto-binds claimedIdentityId to the inbound sender." })),
|
|
441
|
+
claimedIdentityId: Type.Optional(Type.String({ description: "Override for the inbound sender's identity. Must match the value used on the request. Leave unset and pass conversationId." })),
|
|
369
442
|
verificationId: Type.String({ description: "Verification ID returned from request_identity_verification" }),
|
|
370
443
|
phrase: Type.String({ description: "Three-word phrase the person received via mobile or email" })
|
|
371
444
|
}),
|
|
372
|
-
handler: (params) =>
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
445
|
+
handler: (params) => {
|
|
446
|
+
const resolved = resolveClaimedIdentity(params);
|
|
447
|
+
if ("error" in resolved) return Promise.resolve({ error: resolved.error });
|
|
448
|
+
return client.confirmIdentityVerification({
|
|
449
|
+
claimedIdentityId: resolved.claimedIdentityId,
|
|
450
|
+
verificationId: params.verificationId,
|
|
451
|
+
phrase: params.phrase
|
|
452
|
+
});
|
|
453
|
+
}
|
|
377
454
|
})
|
|
378
455
|
];
|
|
379
456
|
for (const tool of tools) api.registerTool(tool);
|
|
@@ -414,7 +491,9 @@ const plugin = {
|
|
|
414
491
|
setCachedResolve(cacheKey, {
|
|
415
492
|
identityId: r.identityId,
|
|
416
493
|
status: r.status,
|
|
417
|
-
permissions: [...r.permissions, ...forwarded]
|
|
494
|
+
permissions: [...r.permissions, ...forwarded],
|
|
495
|
+
senderProvider: provider,
|
|
496
|
+
senderPlatformId: senderId
|
|
418
497
|
});
|
|
419
498
|
if (r.identityId == null) {
|
|
420
499
|
log.warn(`Identity not provisioned for ${provider}:${senderId} — blocking inbound message`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfe.ai/openclaw-identity",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "OpenClaw identity plugin — identity resolution, access gating, permission enforcement",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/plugin.js",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@auriclabs/roles": "0.1.1",
|
|
31
31
|
"@sinclair/typebox": "^0.34.48",
|
|
32
|
-
"@alfe.ai/
|
|
33
|
-
"@alfe.ai/
|
|
32
|
+
"@alfe.ai/config": "0.0.8",
|
|
33
|
+
"@alfe.ai/agent-api-client": "0.1.2"
|
|
34
34
|
},
|
|
35
35
|
"license": "UNLICENSED",
|
|
36
36
|
"scripts": {
|