@anuma/sdk 6.22.0 → 6.23.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/tools/index.cjs +347 -1
- package/dist/tools/index.d.mts +167 -1
- package/dist/tools/index.d.ts +167 -1
- package/dist/tools/index.mjs +343 -1
- package/package.json +1 -1
package/dist/tools/index.cjs
CHANGED
|
@@ -32,6 +32,7 @@ __export(index_exports, {
|
|
|
32
32
|
APP_FILE_TOOL_NAMES: () => APP_FILE_TOOL_NAMES,
|
|
33
33
|
APP_PREVIEW_BASELINE_CSS: () => APP_PREVIEW_BASELINE_CSS,
|
|
34
34
|
AUDIT_DESIGN_SCHEMA: () => AUDIT_DESIGN_SCHEMA,
|
|
35
|
+
AgentresError: () => AgentresError,
|
|
35
36
|
AnumaJsxError: () => AnumaJsxError,
|
|
36
37
|
CONNECTOR_ERROR_MARKER: () => CONNECTOR_ERROR_MARKER,
|
|
37
38
|
CREATE_DOCUMENT_SCHEMA: () => CREATE_DOCUMENT_SCHEMA,
|
|
@@ -61,6 +62,8 @@ __export(index_exports, {
|
|
|
61
62
|
SLIDES_FILE_PATH: () => SLIDES_FILE_PATH,
|
|
62
63
|
SLIDE_CANVAS_HEIGHT: () => SLIDE_CANVAS_HEIGHT,
|
|
63
64
|
SLIDE_CANVAS_WIDTH: () => SLIDE_CANVAS_WIDTH,
|
|
65
|
+
SiwxChallengeError: () => SiwxChallengeError,
|
|
66
|
+
SiwxUnsupportedError: () => SiwxUnsupportedError,
|
|
64
67
|
THEME_ATTRS: () => THEME_ATTRS,
|
|
65
68
|
VERIFY_APP_SCHEMA: () => VERIFY_APP_SCHEMA,
|
|
66
69
|
applyPatches: () => applyPatches,
|
|
@@ -74,6 +77,7 @@ __export(index_exports, {
|
|
|
74
77
|
callNotionMCPTool: () => callNotionMCPTool,
|
|
75
78
|
connectorMintErrorToToolResult: () => connectorMintErrorToToolResult,
|
|
76
79
|
convertLegacyDeckJson: () => convertLegacyDeckJson,
|
|
80
|
+
createAgentresClient: () => createAgentresClient,
|
|
77
81
|
createAppCompleteBridge: () => createAppCompleteBridge,
|
|
78
82
|
createAppGenerationTools: () => createAppGenerationTools,
|
|
79
83
|
createChartTool: () => createChartTool,
|
|
@@ -735,7 +739,7 @@ function createPhoneCallOfferTool(options) {
|
|
|
735
739
|
function createConnectorOfferTool(options) {
|
|
736
740
|
return createDisplayTool(options, {
|
|
737
741
|
name: "display_connector",
|
|
738
|
-
description: "Display an inline card that prompts the user to connect an app or service (for example Notion, Gmail, Google Drive, Google Calendar, GitHub, Dropbox). Call this when the user asks to connect, link, enable, or authorize one of these apps, or when answering their request requires access the user has not yet granted. The card renders the connect prompt visually; do NOT repeat the connection instructions in your text response.",
|
|
742
|
+
description: "Display an inline card that prompts the user to connect an app or service (for example Notion, Gmail, Google Drive, Google Calendar, GitHub, Dropbox, or Agentic Reservations for restaurant bookings, id 'agentres'). Call this when the user asks to connect, link, enable, or authorize one of these apps, or when answering their request requires access the user has not yet granted. The card renders the connect prompt visually; do NOT repeat the connection instructions in your text response.",
|
|
739
743
|
parameters: {
|
|
740
744
|
type: "object",
|
|
741
745
|
properties: {
|
|
@@ -2550,6 +2554,344 @@ function createGitHubTools(getAccessToken, requestGitHubAccess) {
|
|
|
2550
2554
|
];
|
|
2551
2555
|
}
|
|
2552
2556
|
|
|
2557
|
+
// src/lib/connectors/agentres/errors.ts
|
|
2558
|
+
var AgentresError = class extends Error {
|
|
2559
|
+
constructor(status, code, message, retryable, nextStep) {
|
|
2560
|
+
super(message);
|
|
2561
|
+
this.name = "AgentresError";
|
|
2562
|
+
this.status = status;
|
|
2563
|
+
this.code = code;
|
|
2564
|
+
this.retryable = retryable;
|
|
2565
|
+
this.nextStep = nextStep;
|
|
2566
|
+
}
|
|
2567
|
+
};
|
|
2568
|
+
var SiwxUnsupportedError = class extends Error {
|
|
2569
|
+
constructor(message) {
|
|
2570
|
+
super(message);
|
|
2571
|
+
this.name = "SiwxUnsupportedError";
|
|
2572
|
+
}
|
|
2573
|
+
};
|
|
2574
|
+
var SiwxChallengeError = class extends Error {
|
|
2575
|
+
constructor(message, options) {
|
|
2576
|
+
super(message);
|
|
2577
|
+
this.name = "SiwxChallengeError";
|
|
2578
|
+
this.cause = options?.cause;
|
|
2579
|
+
}
|
|
2580
|
+
};
|
|
2581
|
+
function parseAgentresError(status, body) {
|
|
2582
|
+
const stated = statedError(body);
|
|
2583
|
+
if (!stated) {
|
|
2584
|
+
return new AgentresError(
|
|
2585
|
+
status,
|
|
2586
|
+
`HTTP_${status}`,
|
|
2587
|
+
body.trim() || `HTTP ${status}`,
|
|
2588
|
+
status >= 500
|
|
2589
|
+
);
|
|
2590
|
+
}
|
|
2591
|
+
const code = typeof stated.code === "string" ? stated.code : `HTTP_${status}`;
|
|
2592
|
+
const message = typeof stated.message === "string" ? stated.message : `HTTP ${status}`;
|
|
2593
|
+
const retryable = typeof stated.retryable === "boolean" ? stated.retryable : status >= 500;
|
|
2594
|
+
const nextStep = typeof stated.next_step === "string" ? stated.next_step : void 0;
|
|
2595
|
+
return new AgentresError(status, code, message, retryable, nextStep);
|
|
2596
|
+
}
|
|
2597
|
+
function statedError(body) {
|
|
2598
|
+
let parsed;
|
|
2599
|
+
try {
|
|
2600
|
+
parsed = JSON.parse(body);
|
|
2601
|
+
} catch {
|
|
2602
|
+
return null;
|
|
2603
|
+
}
|
|
2604
|
+
const envelope = parsed;
|
|
2605
|
+
const stated = typeof envelope?.error === "object" && envelope.error !== null ? envelope.error : null;
|
|
2606
|
+
if (!stated) {
|
|
2607
|
+
return null;
|
|
2608
|
+
}
|
|
2609
|
+
const fields = stated;
|
|
2610
|
+
if (typeof fields.code !== "string" && typeof fields.message !== "string") {
|
|
2611
|
+
return null;
|
|
2612
|
+
}
|
|
2613
|
+
return fields;
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
// src/lib/processors/encoding.ts
|
|
2617
|
+
var B64_ENCODE_CHUNK = 32768 * 3;
|
|
2618
|
+
function uint8ArrayToBase64(data) {
|
|
2619
|
+
if (typeof Buffer !== "undefined") {
|
|
2620
|
+
return Buffer.from(data).toString("base64");
|
|
2621
|
+
}
|
|
2622
|
+
let base64 = "";
|
|
2623
|
+
for (let i = 0; i < data.length; i += B64_ENCODE_CHUNK) {
|
|
2624
|
+
const slice = data.subarray(i, i + B64_ENCODE_CHUNK);
|
|
2625
|
+
let binary = "";
|
|
2626
|
+
for (let j = 0; j < slice.length; j++) {
|
|
2627
|
+
binary += String.fromCharCode(slice[j]);
|
|
2628
|
+
}
|
|
2629
|
+
base64 += btoa(binary);
|
|
2630
|
+
}
|
|
2631
|
+
return base64;
|
|
2632
|
+
}
|
|
2633
|
+
function base64ToUint8Array(base64) {
|
|
2634
|
+
if (typeof Buffer !== "undefined") {
|
|
2635
|
+
const buf = Buffer.from(base64, "base64");
|
|
2636
|
+
return new Uint8Array(buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength));
|
|
2637
|
+
}
|
|
2638
|
+
const binary = atob(base64);
|
|
2639
|
+
const bytes = new Uint8Array(binary.length);
|
|
2640
|
+
for (let i = 0; i < binary.length; i++) {
|
|
2641
|
+
bytes[i] = binary.charCodeAt(i);
|
|
2642
|
+
}
|
|
2643
|
+
return bytes;
|
|
2644
|
+
}
|
|
2645
|
+
|
|
2646
|
+
// src/lib/connectors/agentres/siwx.ts
|
|
2647
|
+
var PAYMENT_REQUIRED_HEADER = "PAYMENT-REQUIRED";
|
|
2648
|
+
var SIWX_HEADER = "SIGN-IN-WITH-X";
|
|
2649
|
+
var SIWX_EXTENSION = "sign-in-with-x";
|
|
2650
|
+
var SOLANA_NAMESPACE = "solana:";
|
|
2651
|
+
function parseChallenge(paymentRequiredHeader, expectedOrigin) {
|
|
2652
|
+
const decoded = decodeHeader(paymentRequiredHeader);
|
|
2653
|
+
const extensions = asRecord(decoded.extensions);
|
|
2654
|
+
const extension = extensions ? asRecord(extensions[SIWX_EXTENSION]) : null;
|
|
2655
|
+
if (!extension) {
|
|
2656
|
+
throw new SiwxUnsupportedError(
|
|
2657
|
+
"the 402 carries no sign-in-with-x extension, so this endpoint is paid rather than identity-only"
|
|
2658
|
+
);
|
|
2659
|
+
}
|
|
2660
|
+
const info = asRecord(extension.info);
|
|
2661
|
+
if (!info) {
|
|
2662
|
+
throw new SiwxChallengeError("the sign-in-with-x extension has no info block");
|
|
2663
|
+
}
|
|
2664
|
+
const chain = solanaChain(extension.supportedChains);
|
|
2665
|
+
const challenge = {
|
|
2666
|
+
domain: requireString(info, "domain"),
|
|
2667
|
+
uri: requireString(info, "uri"),
|
|
2668
|
+
version: requireString(info, "version"),
|
|
2669
|
+
statement: requireString(info, "statement"),
|
|
2670
|
+
nonce: requireString(info, "nonce"),
|
|
2671
|
+
issuedAt: requireString(info, "issuedAt"),
|
|
2672
|
+
resources: requireResources(info),
|
|
2673
|
+
chainId: chain.chainId,
|
|
2674
|
+
signingType: chain.signingType
|
|
2675
|
+
};
|
|
2676
|
+
assertScopedTo(challenge, expectedOrigin);
|
|
2677
|
+
return challenge;
|
|
2678
|
+
}
|
|
2679
|
+
function assertScopedTo(challenge, expectedOrigin) {
|
|
2680
|
+
const expected = parseUrl(expectedOrigin, `the agentres base URL "${expectedOrigin}"`);
|
|
2681
|
+
if (challenge.domain !== expected.host) {
|
|
2682
|
+
throw new SiwxChallengeError(
|
|
2683
|
+
`the challenge is scoped to "${challenge.domain}" but this client talks to "${expected.host}" \u2014 refusing to sign it`
|
|
2684
|
+
);
|
|
2685
|
+
}
|
|
2686
|
+
const uri = parseUrl(challenge.uri, `the sign-in-with-x uri "${challenge.uri}"`);
|
|
2687
|
+
if (uri.origin !== expected.origin) {
|
|
2688
|
+
throw new SiwxChallengeError(
|
|
2689
|
+
`the challenge addresses "${uri.origin}" but this client talks to "${expected.origin}" \u2014 refusing to sign it`
|
|
2690
|
+
);
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
function parseUrl(value, description) {
|
|
2694
|
+
try {
|
|
2695
|
+
return new URL(value);
|
|
2696
|
+
} catch (cause) {
|
|
2697
|
+
throw new SiwxChallengeError(`${description} is not a URL`, { cause });
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
function buildMessage(challenge, address) {
|
|
2701
|
+
if (!challenge.chainId.startsWith(SOLANA_NAMESPACE)) {
|
|
2702
|
+
throw new SiwxChallengeError(
|
|
2703
|
+
`expected a solana: chain id for the message, got "${challenge.chainId}"`
|
|
2704
|
+
);
|
|
2705
|
+
}
|
|
2706
|
+
const reference = challenge.chainId.slice(SOLANA_NAMESPACE.length);
|
|
2707
|
+
const resources = challenge.resources.map((resource) => `- ${resource}`).join("\n");
|
|
2708
|
+
return `${challenge.domain} wants you to sign in with your Solana account:
|
|
2709
|
+
${address}
|
|
2710
|
+
|
|
2711
|
+
${challenge.statement}
|
|
2712
|
+
|
|
2713
|
+
URI: ${challenge.uri}
|
|
2714
|
+
Version: ${challenge.version}
|
|
2715
|
+
Chain ID: ${reference}
|
|
2716
|
+
Nonce: ${challenge.nonce}
|
|
2717
|
+
Issued At: ${challenge.issuedAt}
|
|
2718
|
+
Resources:
|
|
2719
|
+
${resources}`;
|
|
2720
|
+
}
|
|
2721
|
+
function buildPayload(challenge, address, signature) {
|
|
2722
|
+
const payload = {
|
|
2723
|
+
domain: challenge.domain,
|
|
2724
|
+
address,
|
|
2725
|
+
statement: challenge.statement,
|
|
2726
|
+
uri: challenge.uri,
|
|
2727
|
+
version: challenge.version,
|
|
2728
|
+
// Full CAIP-2 here, unlike the bare reference the message carries.
|
|
2729
|
+
chainId: challenge.chainId,
|
|
2730
|
+
type: challenge.signingType,
|
|
2731
|
+
nonce: challenge.nonce,
|
|
2732
|
+
issuedAt: challenge.issuedAt,
|
|
2733
|
+
resources: challenge.resources,
|
|
2734
|
+
signature: base58Encode(signature)
|
|
2735
|
+
};
|
|
2736
|
+
return uint8ArrayToBase64(new TextEncoder().encode(JSON.stringify(payload)));
|
|
2737
|
+
}
|
|
2738
|
+
var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
2739
|
+
function base58Encode(bytes) {
|
|
2740
|
+
let zeros = 0;
|
|
2741
|
+
while (zeros < bytes.length && bytes[zeros] === 0) {
|
|
2742
|
+
zeros++;
|
|
2743
|
+
}
|
|
2744
|
+
const digits = [];
|
|
2745
|
+
for (let i = zeros; i < bytes.length; i++) {
|
|
2746
|
+
let carry = bytes[i];
|
|
2747
|
+
for (let j = 0; j < digits.length; j++) {
|
|
2748
|
+
carry += digits[j] * 256;
|
|
2749
|
+
digits[j] = carry % 58;
|
|
2750
|
+
carry = Math.floor(carry / 58);
|
|
2751
|
+
}
|
|
2752
|
+
while (carry > 0) {
|
|
2753
|
+
digits.push(carry % 58);
|
|
2754
|
+
carry = Math.floor(carry / 58);
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
let encoded = "1".repeat(zeros);
|
|
2758
|
+
for (let i = digits.length - 1; i >= 0; i--) {
|
|
2759
|
+
encoded += BASE58_ALPHABET[digits[i]];
|
|
2760
|
+
}
|
|
2761
|
+
return encoded;
|
|
2762
|
+
}
|
|
2763
|
+
function decodeHeader(paymentRequiredHeader) {
|
|
2764
|
+
let parsed;
|
|
2765
|
+
try {
|
|
2766
|
+
parsed = JSON.parse(new TextDecoder().decode(base64ToUint8Array(paymentRequiredHeader)));
|
|
2767
|
+
} catch (cause) {
|
|
2768
|
+
throw new SiwxChallengeError("the PAYMENT-REQUIRED header is not base64-encoded JSON", {
|
|
2769
|
+
cause
|
|
2770
|
+
});
|
|
2771
|
+
}
|
|
2772
|
+
const decoded = asRecord(parsed);
|
|
2773
|
+
if (!decoded) {
|
|
2774
|
+
throw new SiwxChallengeError("the PAYMENT-REQUIRED header did not decode to an object");
|
|
2775
|
+
}
|
|
2776
|
+
return decoded;
|
|
2777
|
+
}
|
|
2778
|
+
function solanaChain(supportedChains) {
|
|
2779
|
+
if (!Array.isArray(supportedChains)) {
|
|
2780
|
+
throw new SiwxChallengeError("the sign-in-with-x extension lists no supportedChains");
|
|
2781
|
+
}
|
|
2782
|
+
for (const entry of supportedChains) {
|
|
2783
|
+
const chain = asRecord(entry);
|
|
2784
|
+
const chainId = chain?.chainId;
|
|
2785
|
+
if (typeof chainId !== "string" || !chainId.startsWith(SOLANA_NAMESPACE)) {
|
|
2786
|
+
continue;
|
|
2787
|
+
}
|
|
2788
|
+
const signingType = chain?.type;
|
|
2789
|
+
if (typeof signingType !== "string" || signingType === "") {
|
|
2790
|
+
throw new SiwxChallengeError(`the ${chainId} entry declares no signing type`);
|
|
2791
|
+
}
|
|
2792
|
+
return { chainId, signingType };
|
|
2793
|
+
}
|
|
2794
|
+
throw new SiwxChallengeError("the sign-in-with-x extension offers no solana: chain");
|
|
2795
|
+
}
|
|
2796
|
+
function asRecord(value) {
|
|
2797
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
2798
|
+
}
|
|
2799
|
+
function requireString(info, key) {
|
|
2800
|
+
const value = info[key];
|
|
2801
|
+
if (typeof value !== "string" || value === "") {
|
|
2802
|
+
throw new SiwxChallengeError(`the sign-in-with-x info block has no ${key}`);
|
|
2803
|
+
}
|
|
2804
|
+
return value;
|
|
2805
|
+
}
|
|
2806
|
+
function requireResources(info) {
|
|
2807
|
+
const resources = info.resources;
|
|
2808
|
+
if (!Array.isArray(resources) || resources.length === 0) {
|
|
2809
|
+
throw new SiwxChallengeError("the sign-in-with-x info block has no resources");
|
|
2810
|
+
}
|
|
2811
|
+
if (!resources.every((resource) => typeof resource === "string" && resource !== "")) {
|
|
2812
|
+
throw new SiwxChallengeError("the sign-in-with-x resources are not all strings");
|
|
2813
|
+
}
|
|
2814
|
+
return resources;
|
|
2815
|
+
}
|
|
2816
|
+
|
|
2817
|
+
// src/lib/connectors/agentres/client.ts
|
|
2818
|
+
var DEFAULT_BASE_URL = "https://agentres.dev";
|
|
2819
|
+
function createAgentresClient(options) {
|
|
2820
|
+
const baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
2821
|
+
const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
2822
|
+
const { address, signMessage } = options;
|
|
2823
|
+
async function withSiwx(request) {
|
|
2824
|
+
const url = `${baseUrl}${request.path}`;
|
|
2825
|
+
const init = requestInit(request);
|
|
2826
|
+
const challenged = await fetchImpl(url, init);
|
|
2827
|
+
if (challenged.status !== 402) {
|
|
2828
|
+
return readBody(challenged);
|
|
2829
|
+
}
|
|
2830
|
+
await challenged.body?.cancel().catch(() => {
|
|
2831
|
+
});
|
|
2832
|
+
const header = challenged.headers.get(PAYMENT_REQUIRED_HEADER);
|
|
2833
|
+
if (!header) {
|
|
2834
|
+
throw new SiwxChallengeError(
|
|
2835
|
+
`the 402 from ${request.path} carried no ${PAYMENT_REQUIRED_HEADER} header`
|
|
2836
|
+
);
|
|
2837
|
+
}
|
|
2838
|
+
const challenge = parseChallenge(header, baseUrl);
|
|
2839
|
+
const signature = await signMessage(new TextEncoder().encode(buildMessage(challenge, address)));
|
|
2840
|
+
const authorized = await fetchImpl(url, {
|
|
2841
|
+
...init,
|
|
2842
|
+
headers: { ...init.headers, [SIWX_HEADER]: buildPayload(challenge, address, signature) }
|
|
2843
|
+
});
|
|
2844
|
+
return readBody(authorized);
|
|
2845
|
+
}
|
|
2846
|
+
async function linkResy(body) {
|
|
2847
|
+
const response = await withSiwx({ method: "POST", path: "/api/link-resy", body });
|
|
2848
|
+
return { step: response.step, message: response.message, resyUserId: response.resy_user_id };
|
|
2849
|
+
}
|
|
2850
|
+
return {
|
|
2851
|
+
withSiwx,
|
|
2852
|
+
async ensureAccount(email) {
|
|
2853
|
+
const body = await withSiwx({ method: "POST", path: "/api/account", body: { email } });
|
|
2854
|
+
return {
|
|
2855
|
+
accountId: body.account_id,
|
|
2856
|
+
email: body.email,
|
|
2857
|
+
credentialKind: body.credential_kind,
|
|
2858
|
+
walletLinked: body.wallet_linked
|
|
2859
|
+
};
|
|
2860
|
+
},
|
|
2861
|
+
requestCode(email) {
|
|
2862
|
+
return linkResy({ em_address: email });
|
|
2863
|
+
},
|
|
2864
|
+
verifyCode(email, code) {
|
|
2865
|
+
return linkResy({ em_address: email, code });
|
|
2866
|
+
},
|
|
2867
|
+
async getLinkStatus() {
|
|
2868
|
+
const body = await withSiwx({ method: "GET", path: "/api/me" });
|
|
2869
|
+
return {
|
|
2870
|
+
accountId: body.account_id,
|
|
2871
|
+
email: body.email,
|
|
2872
|
+
resyLinked: body.resy_linked,
|
|
2873
|
+
walletAddress: body.wallet_address,
|
|
2874
|
+
resyLinkedAt: body.resy_linked_at ?? null
|
|
2875
|
+
};
|
|
2876
|
+
}
|
|
2877
|
+
};
|
|
2878
|
+
}
|
|
2879
|
+
function requestInit(request) {
|
|
2880
|
+
const headers = { Accept: "application/json" };
|
|
2881
|
+
if (request.body === void 0) {
|
|
2882
|
+
return { method: request.method, headers };
|
|
2883
|
+
}
|
|
2884
|
+
headers["Content-Type"] = "application/json";
|
|
2885
|
+
return { method: request.method, headers, body: JSON.stringify(request.body) };
|
|
2886
|
+
}
|
|
2887
|
+
async function readBody(response) {
|
|
2888
|
+
const body = await response.text();
|
|
2889
|
+
if (!response.ok) {
|
|
2890
|
+
throw parseAgentresError(response.status, body);
|
|
2891
|
+
}
|
|
2892
|
+
return JSON.parse(body);
|
|
2893
|
+
}
|
|
2894
|
+
|
|
2553
2895
|
// src/lib/connectors/client.ts
|
|
2554
2896
|
var DEFAULT_REFRESH_BEFORE_MS = 3e4;
|
|
2555
2897
|
function createConnectorTokenGetter(client, provider, opts = {}) {
|
|
@@ -13676,6 +14018,7 @@ function createDocumentTools({
|
|
|
13676
14018
|
APP_FILE_TOOL_NAMES,
|
|
13677
14019
|
APP_PREVIEW_BASELINE_CSS,
|
|
13678
14020
|
AUDIT_DESIGN_SCHEMA,
|
|
14021
|
+
AgentresError,
|
|
13679
14022
|
AnumaJsxError,
|
|
13680
14023
|
CONNECTOR_ERROR_MARKER,
|
|
13681
14024
|
CREATE_DOCUMENT_SCHEMA,
|
|
@@ -13705,6 +14048,8 @@ function createDocumentTools({
|
|
|
13705
14048
|
SLIDES_FILE_PATH,
|
|
13706
14049
|
SLIDE_CANVAS_HEIGHT,
|
|
13707
14050
|
SLIDE_CANVAS_WIDTH,
|
|
14051
|
+
SiwxChallengeError,
|
|
14052
|
+
SiwxUnsupportedError,
|
|
13708
14053
|
THEME_ATTRS,
|
|
13709
14054
|
VERIFY_APP_SCHEMA,
|
|
13710
14055
|
applyPatches,
|
|
@@ -13718,6 +14063,7 @@ function createDocumentTools({
|
|
|
13718
14063
|
callNotionMCPTool,
|
|
13719
14064
|
connectorMintErrorToToolResult,
|
|
13720
14065
|
convertLegacyDeckJson,
|
|
14066
|
+
createAgentresClient,
|
|
13721
14067
|
createAppCompleteBridge,
|
|
13722
14068
|
createAppGenerationTools,
|
|
13723
14069
|
createChartTool,
|
package/dist/tools/index.d.mts
CHANGED
|
@@ -706,6 +706,172 @@ declare function callNotionMCPTool<T>(accessToken: string, toolName: string, arg
|
|
|
706
706
|
*/
|
|
707
707
|
declare function createGitHubTools(getAccessToken: () => string | null, requestGitHubAccess: () => Promise<string>): ToolConfig[];
|
|
708
708
|
|
|
709
|
+
/**
|
|
710
|
+
* Client for the agentres.dev registration flow.
|
|
711
|
+
*
|
|
712
|
+
* Signer-agnostic on purpose: it takes a `signMessage` closure, a base58
|
|
713
|
+
* address and a `fetch`, and imports nothing app-specific. The browser app
|
|
714
|
+
* bridges Privy's embedded Solana wallet to {@link SolanaSignMessageFn} the
|
|
715
|
+
* same way `usePrivySigningAdapters` already bridges the EVM one for
|
|
716
|
+
* encryption, and this module never learns that Privy exists.
|
|
717
|
+
*
|
|
718
|
+
* Registration is four calls plus a status read, and the user is step three:
|
|
719
|
+
*
|
|
720
|
+
* 1. {@link AgentresClient.ensureAccount} — creates the wallet-bound account.
|
|
721
|
+
* 2. {@link AgentresClient.requestCode} — agentres asks Resy to email a code.
|
|
722
|
+
* 3. The user reads the 6-digit code out of their own inbox.
|
|
723
|
+
* 4. {@link AgentresClient.verifyCode} — agentres verifies it and stores the
|
|
724
|
+
* Resy credential.
|
|
725
|
+
* 5. {@link AgentresClient.getLinkStatus} — confirms `resyLinked`.
|
|
726
|
+
*
|
|
727
|
+
* The same email goes to all of them, and its field name is `em_address` on
|
|
728
|
+
* `/api/link-resy` but `email` on `/api/account`. They are the provider's
|
|
729
|
+
* spellings, not a typo.
|
|
730
|
+
*
|
|
731
|
+
* Whichever key signs IS the account, permanently — agentres derives identity
|
|
732
|
+
* from the signature and has no unlink endpoint. So this client must be given
|
|
733
|
+
* the end user's own wallet, never a shared or treasury one.
|
|
734
|
+
*
|
|
735
|
+
* @module lib/connectors/agentres/client
|
|
736
|
+
*/
|
|
737
|
+
/**
|
|
738
|
+
* Signs arbitrary bytes with the user's Solana key.
|
|
739
|
+
*
|
|
740
|
+
* Bytes in, bytes out — the SDK base58-encodes the result. Keep it byte-typed
|
|
741
|
+
* end to end: a `Uint8Array` that reaches a string API stringifies to a
|
|
742
|
+
* comma-separated digit list, which signs and encodes cleanly and verifies as
|
|
743
|
+
* garbage with no error anywhere (ai-memoryless-client#7217).
|
|
744
|
+
*/
|
|
745
|
+
type SolanaSignMessageFn = (message: Uint8Array) => Promise<Uint8Array>;
|
|
746
|
+
/** The `fetch` surface this client uses. Injected so tests make no network call. */
|
|
747
|
+
type FetchLike = (url: string, init?: RequestInit) => Promise<Response>;
|
|
748
|
+
interface AgentresClientOptions {
|
|
749
|
+
/** The user's own Solana address, base58. The identity the proof asserts. */
|
|
750
|
+
address: string;
|
|
751
|
+
signMessage: SolanaSignMessageFn;
|
|
752
|
+
/** @default "https://agentres.dev" */
|
|
753
|
+
baseUrl?: string;
|
|
754
|
+
/** @default globalThis.fetch */
|
|
755
|
+
fetch?: FetchLike;
|
|
756
|
+
}
|
|
757
|
+
/** One call to make through {@link AgentresClient.withSiwx}. */
|
|
758
|
+
interface AgentresRequest {
|
|
759
|
+
method: "GET" | "POST";
|
|
760
|
+
/** Path on the agentres host, e.g. `/api/me`. */
|
|
761
|
+
path: string;
|
|
762
|
+
/** JSON body, for POSTs. */
|
|
763
|
+
body?: unknown;
|
|
764
|
+
}
|
|
765
|
+
/** `POST /api/account` — the wallet-bound account, resolved or created. */
|
|
766
|
+
interface AgentresAccount {
|
|
767
|
+
accountId: string;
|
|
768
|
+
email: string | null;
|
|
769
|
+
/** `wallet` for this flow; `api_key` is the other auth path agentres offers. */
|
|
770
|
+
credentialKind: string;
|
|
771
|
+
walletLinked: boolean;
|
|
772
|
+
}
|
|
773
|
+
/** `POST /api/link-resy` — which half of the OTP exchange just completed. */
|
|
774
|
+
interface AgentresLinkStep {
|
|
775
|
+
step: "code_sent" | "linked";
|
|
776
|
+
message?: string;
|
|
777
|
+
/** Present once linked. */
|
|
778
|
+
resyUserId?: number;
|
|
779
|
+
}
|
|
780
|
+
/** `GET /api/me` — what the tile renders from. */
|
|
781
|
+
interface AgentresLinkStatus {
|
|
782
|
+
accountId: string;
|
|
783
|
+
email: string | null;
|
|
784
|
+
resyLinked: boolean;
|
|
785
|
+
/** The address agentres resolved from the proof. Base58, despite the OpenAPI's 0x pattern. */
|
|
786
|
+
walletAddress: string | null;
|
|
787
|
+
resyLinkedAt: string | null;
|
|
788
|
+
}
|
|
789
|
+
interface AgentresClient {
|
|
790
|
+
/**
|
|
791
|
+
* Make one call, satisfying its 402 with a fresh SIWX proof.
|
|
792
|
+
*
|
|
793
|
+
* Always two requests: the first is unauthenticated and expected to answer
|
|
794
|
+
* 402, the second carries the proof. Nonces are single-use and expire minutes
|
|
795
|
+
* after they are issued, so nothing here is cached — a reused challenge works
|
|
796
|
+
* in a fast dev loop and fails in real use.
|
|
797
|
+
*/
|
|
798
|
+
withSiwx<T>(request: AgentresRequest): Promise<T>;
|
|
799
|
+
ensureAccount(email: string): Promise<AgentresAccount>;
|
|
800
|
+
requestCode(email: string): Promise<AgentresLinkStep>;
|
|
801
|
+
verifyCode(email: string, code: string): Promise<AgentresLinkStep>;
|
|
802
|
+
getLinkStatus(): Promise<AgentresLinkStatus>;
|
|
803
|
+
}
|
|
804
|
+
/**
|
|
805
|
+
* Build a client bound to one wallet.
|
|
806
|
+
*
|
|
807
|
+
* The client holds no state between calls, deliberately. The pending code lives
|
|
808
|
+
* at agentres, keyed by email, and step three of the flow sends the user out to
|
|
809
|
+
* their inbox — on a phone that can unmount the page, so the instance that
|
|
810
|
+
* requested the code is often not the instance that verifies it. A client that
|
|
811
|
+
* remembered would refuse a code that is still perfectly valid upstream.
|
|
812
|
+
*/
|
|
813
|
+
declare function createAgentresClient(options: AgentresClientOptions): AgentresClient;
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
* Typed errors for the agentres connector.
|
|
817
|
+
*
|
|
818
|
+
* agentres states every refusal in one envelope, on every route:
|
|
819
|
+
*
|
|
820
|
+
* ```json
|
|
821
|
+
* { "error": { "code": "NO_LINKED_ACCOUNT", "message": "…", "retryable": false,
|
|
822
|
+
* "next_step": "Call POST /api/link-resy with the account email." } }
|
|
823
|
+
* ```
|
|
824
|
+
*
|
|
825
|
+
* `next_step` is often the only actionable part — it is the provider's own
|
|
826
|
+
* sentence about what to do next — so it is carried through to the caller
|
|
827
|
+
* rather than folded into the message. The registration UI shows the raw code
|
|
828
|
+
* and message, which is deliberate: a refusal here is usually the user's Resy
|
|
829
|
+
* account state, not a bug, and paraphrasing it hides what to fix.
|
|
830
|
+
*
|
|
831
|
+
* The SIWX errors are separate because they are ours, not the provider's: they
|
|
832
|
+
* mean the challenge never became a usable proof, so no request was authorized.
|
|
833
|
+
*
|
|
834
|
+
* @module lib/connectors/agentres/errors
|
|
835
|
+
*/
|
|
836
|
+
/**
|
|
837
|
+
* Provider codes the registration flow can return.
|
|
838
|
+
*
|
|
839
|
+
* `AgentresError.code` stays a plain `string` — agentres documents two dozen
|
|
840
|
+
* more for the booking routes, and new ones appear without a version bump —
|
|
841
|
+
* but these four are the ones a registration surface has to handle by name.
|
|
842
|
+
*/
|
|
843
|
+
type AgentresErrorCode = "NO_LINKED_ACCOUNT" | "RESY_VERIFICATION_FAILED" | "RESY_NO_PAYMENT_METHOD" | "UNAUTHORIZED";
|
|
844
|
+
/** A refusal agentres stated, decoded from its error envelope. */
|
|
845
|
+
declare class AgentresError extends Error {
|
|
846
|
+
/** HTTP status the refusal arrived with. */
|
|
847
|
+
readonly status: number;
|
|
848
|
+
/** Provider's stable machine-readable code, e.g. `NO_LINKED_ACCOUNT`. */
|
|
849
|
+
readonly code: string;
|
|
850
|
+
/** Whether the provider says the same call could work later. */
|
|
851
|
+
readonly retryable: boolean;
|
|
852
|
+
/** What the provider says to do about it, when it says anything. */
|
|
853
|
+
readonly nextStep?: string;
|
|
854
|
+
constructor(status: number, code: string, message: string, retryable: boolean, nextStep?: string);
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* The 402 carried no `sign-in-with-x` extension.
|
|
858
|
+
*
|
|
859
|
+
* That marks a paid endpoint, which SIWX cannot satisfy. Signing anyway would
|
|
860
|
+
* produce a well-formed proof the server answers with a bare 401, so the cause
|
|
861
|
+
* has to be named here or it surfaces as an authentication mystery later.
|
|
862
|
+
*/
|
|
863
|
+
declare class SiwxUnsupportedError extends Error {
|
|
864
|
+
constructor(message: string);
|
|
865
|
+
}
|
|
866
|
+
/** The challenge could not be read, or is missing something the proof needs. */
|
|
867
|
+
declare class SiwxChallengeError extends Error {
|
|
868
|
+
/** The underlying decode failure, when there was one. */
|
|
869
|
+
readonly cause?: unknown;
|
|
870
|
+
constructor(message: string, options?: {
|
|
871
|
+
cause?: unknown;
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
|
|
709
875
|
/**
|
|
710
876
|
* Token-getter factory shared by every connector tool factory.
|
|
711
877
|
*
|
|
@@ -2849,4 +3015,4 @@ declare const DEFAULT_MAX_DOCUMENT_CONVERSATIONS = 1000;
|
|
|
2849
3015
|
*/
|
|
2850
3016
|
declare function createDocumentTools({ getConversationId, storage, logError, displayDocument, maxConversations, }: CreateDocumentToolsOptions): ToolConfig[];
|
|
2851
3017
|
|
|
2852
|
-
export { ADD_SLIDE_SCHEMA, APP_BUILDER_PROMPT, APP_COMPLETE_CONNECT_ACK_TYPE, APP_COMPLETE_CONNECT_TYPE, APP_COMPLETE_DEFAULT_TIMEOUT_MS, APP_COMPLETE_IFRAME_SHIM_SCRIPT, APP_COMPLETE_REQUEST_TYPE, APP_COMPLETE_RESPONSE_TYPE, APP_COMPLETE_STUB_SCRIPT, APP_FILE_TOOL_NAMES, APP_PREVIEW_BASELINE_CSS, AUDIT_DESIGN_SCHEMA, type AnchorMatch, type AnumaChild, AnumaJsxError, type AnumaNode, type AppCompleteBridge, type AppCompleteBridgeOptions, type AppFileRecord, type AppFileStorage, type AttrValue, type AuditIssue, type AuditIssueType, type AuditResult, type AuditSeverity, type AuditTokens, type BuildSlideSystemPromptOptions, CONNECTOR_ERROR_MARKER, CREATE_DOCUMENT_SCHEMA, CREATE_FILE_SCHEMA, CRITIQUE_DESIGN_SCHEMA, type CalendarEvent, type ChartDataPoint, type ChoiceOption, type ConnectorErrorCode, type ConnectorMintError, type ConnectorMintResult, type ConnectorTokenGetterOpts, type ConnectorTokenSource, type CreateAppGenerationToolsOptions, type CreateDocumentToolsOptions, type CreateEventArgs, type CreateFileArgs, type CreateSlideToolsOptions, type CreateUIToolsOptions, type CreateWeatherToolOptions, DEFAULT_DESIGN_CRITIQUE_RUBRIC, DEFAULT_DOCUMENT_ID, DEFAULT_MAX_CONVERSATIONS, DEFAULT_MAX_DOCUMENT_CONVERSATIONS, DELETE_FILE_SCHEMA, DOCUMENT_BUILDER_PROMPT, DOCUMENT_TOOL_NAMES, type DisplayChartResult, type DisplayConnectorResult, type DisplayPhoneCallOfferResult, type DisplayToolConfig, type DisplayToolMigrations, type DisplayWeatherResult, type DocAttrValue, type DocChild, DocDslError, type DocNode, type DriveFile, type DropboxRequestAccess, type DropboxTokenGetter, type ExportAppOptions, FONT_LIBRARY, FONT_PRESETS, type FileChangeEvent, type FileSnippet, type FontCategory, type FontPreset, type FontSpec, type ForecastDay, type FormField, type FormFieldOption, type FormFieldType, type GetFileContentArgs, type GmailGetMessageArgs, type GmailMessageDetail, type GmailMessageSummary, type GmailRequestAccess, type GmailSearchArgs, type GmailSendMessageArgs, type GmailTokenGetter, type InteractiveToolConfig, type KnownTag, LAYOUT_MODES, LIST_FILES_SCHEMA, type LayoutMode, type LegacyDeckJson, type ListEventsArgs, type ListRecentFilesArgs, MapFileStorage, type NotionCreatePagesArgs, type NotionFetchArgs, type NotionMovePagesArgs, type NotionSearchArgs, type NotionUpdatePageArgs, PATCH_DOCUMENT_SCHEMA, PATCH_FILE_SCHEMA, PATCH_SLIDES_SCHEMA, PLAN_DECK_SCHEMA, type PatchFailure, type PatchFailureReason, type PdfTag, READ_DOCUMENT_SCHEMA, READ_FILE_SCHEMA, READ_SLIDES_SCHEMA, RUNTIME_ERROR_OVERLAY_SCRIPT, SLIDES_FILE_PATH, SLIDE_CANVAS_HEIGHT, SLIDE_CANVAS_WIDTH, type SearchFilesArgs, type SlackGetChannelHistoryArgs, type SlackGetThreadRepliesArgs, type SlackListChannelsArgs, type SlackListDmsArgs, type SlackListUsersArgs, type SlackPostMessageArgs, type SlackProxyCaller, type SlackSearchMessagesArgs, type SlideToolSet, THEME_ATTRS, type ThemeAttr, type ToolConfig, type ToolExecutionErrorType, type ToolExecutionResult, type UIInteractionContext, type UpdateEventArgs, type UpdateFileArgs, VERIFY_APP_SCHEMA, type VerifyAppResult, type XGetMeArgs, type XGetMyPostsArgs, type XProxyCaller, applyPatches, auditDesign, buildAppFileManifest, buildAppSystemPrompt, buildConnectorErrorResult, buildDocumentSystemPrompt, buildFontsUrl, buildSlideSystemPrompt, callNotionMCPTool, connectorMintErrorToToolResult, convertLegacyDeckJson, createAppCompleteBridge, createAppGenerationTools, createChartTool, createChatTools, createChoiceTool, createConnectorOfferTool, createConnectorTokenGetter, createDisplayTool, createDocumentTools, createDriveTools, createDropboxTools, createFormTool, createGitHubTools, createGmailTools, createGoogleCalendarCreateEventTool, createGoogleCalendarTool, createGoogleCalendarUpdateEventTool, createGoogleDriveCreateFileTool, createGoogleDriveGetContentTool, createGoogleDriveListRecentTool, createGoogleDriveSearchTool, createGoogleDriveUpdateFileTool, createInteractiveTool, createNotionCreateCommentTool, createNotionCreateDatabaseTool, createNotionCreatePagesTool, createNotionDuplicatePageTool, createNotionFetchTool, createNotionGetCommentsTool, createNotionGetTeamsTool, createNotionGetUsersTool, createNotionMovePagesTool, createNotionSearchTool, createNotionTools, createNotionUpdateDataSourceTool, createNotionUpdatePageTool, createPhoneCallOfferTool, createSlackTools, createSlideTools, createWeatherTool, createXTools, documentPath, exportAppToHtml, findById, findParentOfId, getFontByName, getId, getMCPEndpoints, getNumberAttr, getStringAttr, insertAfterId, insertChild, installAppCompleteIframeShim, isAnumaTag, isHtmlTag, isKnownFont, isLegacyDeckJson, isPdfTag, migrateDisplayResult, normalizePath, parseDocumentDsl, parseJsx, pdfStyleKeys, pdfTags, removeById, replaceById, serializeJsx, truncateContent, updateAttrs, walk };
|
|
3018
|
+
export { ADD_SLIDE_SCHEMA, APP_BUILDER_PROMPT, APP_COMPLETE_CONNECT_ACK_TYPE, APP_COMPLETE_CONNECT_TYPE, APP_COMPLETE_DEFAULT_TIMEOUT_MS, APP_COMPLETE_IFRAME_SHIM_SCRIPT, APP_COMPLETE_REQUEST_TYPE, APP_COMPLETE_RESPONSE_TYPE, APP_COMPLETE_STUB_SCRIPT, APP_FILE_TOOL_NAMES, APP_PREVIEW_BASELINE_CSS, AUDIT_DESIGN_SCHEMA, type AgentresAccount, type AgentresClient, type AgentresClientOptions, AgentresError, type AgentresErrorCode, type AgentresLinkStatus, type AgentresLinkStep, type AnchorMatch, type AnumaChild, AnumaJsxError, type AnumaNode, type AppCompleteBridge, type AppCompleteBridgeOptions, type AppFileRecord, type AppFileStorage, type AttrValue, type AuditIssue, type AuditIssueType, type AuditResult, type AuditSeverity, type AuditTokens, type BuildSlideSystemPromptOptions, CONNECTOR_ERROR_MARKER, CREATE_DOCUMENT_SCHEMA, CREATE_FILE_SCHEMA, CRITIQUE_DESIGN_SCHEMA, type CalendarEvent, type ChartDataPoint, type ChoiceOption, type ConnectorErrorCode, type ConnectorMintError, type ConnectorMintResult, type ConnectorTokenGetterOpts, type ConnectorTokenSource, type CreateAppGenerationToolsOptions, type CreateDocumentToolsOptions, type CreateEventArgs, type CreateFileArgs, type CreateSlideToolsOptions, type CreateUIToolsOptions, type CreateWeatherToolOptions, DEFAULT_DESIGN_CRITIQUE_RUBRIC, DEFAULT_DOCUMENT_ID, DEFAULT_MAX_CONVERSATIONS, DEFAULT_MAX_DOCUMENT_CONVERSATIONS, DELETE_FILE_SCHEMA, DOCUMENT_BUILDER_PROMPT, DOCUMENT_TOOL_NAMES, type DisplayChartResult, type DisplayConnectorResult, type DisplayPhoneCallOfferResult, type DisplayToolConfig, type DisplayToolMigrations, type DisplayWeatherResult, type DocAttrValue, type DocChild, DocDslError, type DocNode, type DriveFile, type DropboxRequestAccess, type DropboxTokenGetter, type ExportAppOptions, FONT_LIBRARY, FONT_PRESETS, type FileChangeEvent, type FileSnippet, type FontCategory, type FontPreset, type FontSpec, type ForecastDay, type FormField, type FormFieldOption, type FormFieldType, type GetFileContentArgs, type GmailGetMessageArgs, type GmailMessageDetail, type GmailMessageSummary, type GmailRequestAccess, type GmailSearchArgs, type GmailSendMessageArgs, type GmailTokenGetter, type InteractiveToolConfig, type KnownTag, LAYOUT_MODES, LIST_FILES_SCHEMA, type LayoutMode, type LegacyDeckJson, type ListEventsArgs, type ListRecentFilesArgs, MapFileStorage, type NotionCreatePagesArgs, type NotionFetchArgs, type NotionMovePagesArgs, type NotionSearchArgs, type NotionUpdatePageArgs, PATCH_DOCUMENT_SCHEMA, PATCH_FILE_SCHEMA, PATCH_SLIDES_SCHEMA, PLAN_DECK_SCHEMA, type PatchFailure, type PatchFailureReason, type PdfTag, READ_DOCUMENT_SCHEMA, READ_FILE_SCHEMA, READ_SLIDES_SCHEMA, RUNTIME_ERROR_OVERLAY_SCRIPT, SLIDES_FILE_PATH, SLIDE_CANVAS_HEIGHT, SLIDE_CANVAS_WIDTH, type SearchFilesArgs, SiwxChallengeError, SiwxUnsupportedError, type SlackGetChannelHistoryArgs, type SlackGetThreadRepliesArgs, type SlackListChannelsArgs, type SlackListDmsArgs, type SlackListUsersArgs, type SlackPostMessageArgs, type SlackProxyCaller, type SlackSearchMessagesArgs, type SlideToolSet, type SolanaSignMessageFn, THEME_ATTRS, type ThemeAttr, type ToolConfig, type ToolExecutionErrorType, type ToolExecutionResult, type UIInteractionContext, type UpdateEventArgs, type UpdateFileArgs, VERIFY_APP_SCHEMA, type VerifyAppResult, type XGetMeArgs, type XGetMyPostsArgs, type XProxyCaller, applyPatches, auditDesign, buildAppFileManifest, buildAppSystemPrompt, buildConnectorErrorResult, buildDocumentSystemPrompt, buildFontsUrl, buildSlideSystemPrompt, callNotionMCPTool, connectorMintErrorToToolResult, convertLegacyDeckJson, createAgentresClient, createAppCompleteBridge, createAppGenerationTools, createChartTool, createChatTools, createChoiceTool, createConnectorOfferTool, createConnectorTokenGetter, createDisplayTool, createDocumentTools, createDriveTools, createDropboxTools, createFormTool, createGitHubTools, createGmailTools, createGoogleCalendarCreateEventTool, createGoogleCalendarTool, createGoogleCalendarUpdateEventTool, createGoogleDriveCreateFileTool, createGoogleDriveGetContentTool, createGoogleDriveListRecentTool, createGoogleDriveSearchTool, createGoogleDriveUpdateFileTool, createInteractiveTool, createNotionCreateCommentTool, createNotionCreateDatabaseTool, createNotionCreatePagesTool, createNotionDuplicatePageTool, createNotionFetchTool, createNotionGetCommentsTool, createNotionGetTeamsTool, createNotionGetUsersTool, createNotionMovePagesTool, createNotionSearchTool, createNotionTools, createNotionUpdateDataSourceTool, createNotionUpdatePageTool, createPhoneCallOfferTool, createSlackTools, createSlideTools, createWeatherTool, createXTools, documentPath, exportAppToHtml, findById, findParentOfId, getFontByName, getId, getMCPEndpoints, getNumberAttr, getStringAttr, insertAfterId, insertChild, installAppCompleteIframeShim, isAnumaTag, isHtmlTag, isKnownFont, isLegacyDeckJson, isPdfTag, migrateDisplayResult, normalizePath, parseDocumentDsl, parseJsx, pdfStyleKeys, pdfTags, removeById, replaceById, serializeJsx, truncateContent, updateAttrs, walk };
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -706,6 +706,172 @@ declare function callNotionMCPTool<T>(accessToken: string, toolName: string, arg
|
|
|
706
706
|
*/
|
|
707
707
|
declare function createGitHubTools(getAccessToken: () => string | null, requestGitHubAccess: () => Promise<string>): ToolConfig[];
|
|
708
708
|
|
|
709
|
+
/**
|
|
710
|
+
* Client for the agentres.dev registration flow.
|
|
711
|
+
*
|
|
712
|
+
* Signer-agnostic on purpose: it takes a `signMessage` closure, a base58
|
|
713
|
+
* address and a `fetch`, and imports nothing app-specific. The browser app
|
|
714
|
+
* bridges Privy's embedded Solana wallet to {@link SolanaSignMessageFn} the
|
|
715
|
+
* same way `usePrivySigningAdapters` already bridges the EVM one for
|
|
716
|
+
* encryption, and this module never learns that Privy exists.
|
|
717
|
+
*
|
|
718
|
+
* Registration is four calls plus a status read, and the user is step three:
|
|
719
|
+
*
|
|
720
|
+
* 1. {@link AgentresClient.ensureAccount} — creates the wallet-bound account.
|
|
721
|
+
* 2. {@link AgentresClient.requestCode} — agentres asks Resy to email a code.
|
|
722
|
+
* 3. The user reads the 6-digit code out of their own inbox.
|
|
723
|
+
* 4. {@link AgentresClient.verifyCode} — agentres verifies it and stores the
|
|
724
|
+
* Resy credential.
|
|
725
|
+
* 5. {@link AgentresClient.getLinkStatus} — confirms `resyLinked`.
|
|
726
|
+
*
|
|
727
|
+
* The same email goes to all of them, and its field name is `em_address` on
|
|
728
|
+
* `/api/link-resy` but `email` on `/api/account`. They are the provider's
|
|
729
|
+
* spellings, not a typo.
|
|
730
|
+
*
|
|
731
|
+
* Whichever key signs IS the account, permanently — agentres derives identity
|
|
732
|
+
* from the signature and has no unlink endpoint. So this client must be given
|
|
733
|
+
* the end user's own wallet, never a shared or treasury one.
|
|
734
|
+
*
|
|
735
|
+
* @module lib/connectors/agentres/client
|
|
736
|
+
*/
|
|
737
|
+
/**
|
|
738
|
+
* Signs arbitrary bytes with the user's Solana key.
|
|
739
|
+
*
|
|
740
|
+
* Bytes in, bytes out — the SDK base58-encodes the result. Keep it byte-typed
|
|
741
|
+
* end to end: a `Uint8Array` that reaches a string API stringifies to a
|
|
742
|
+
* comma-separated digit list, which signs and encodes cleanly and verifies as
|
|
743
|
+
* garbage with no error anywhere (ai-memoryless-client#7217).
|
|
744
|
+
*/
|
|
745
|
+
type SolanaSignMessageFn = (message: Uint8Array) => Promise<Uint8Array>;
|
|
746
|
+
/** The `fetch` surface this client uses. Injected so tests make no network call. */
|
|
747
|
+
type FetchLike = (url: string, init?: RequestInit) => Promise<Response>;
|
|
748
|
+
interface AgentresClientOptions {
|
|
749
|
+
/** The user's own Solana address, base58. The identity the proof asserts. */
|
|
750
|
+
address: string;
|
|
751
|
+
signMessage: SolanaSignMessageFn;
|
|
752
|
+
/** @default "https://agentres.dev" */
|
|
753
|
+
baseUrl?: string;
|
|
754
|
+
/** @default globalThis.fetch */
|
|
755
|
+
fetch?: FetchLike;
|
|
756
|
+
}
|
|
757
|
+
/** One call to make through {@link AgentresClient.withSiwx}. */
|
|
758
|
+
interface AgentresRequest {
|
|
759
|
+
method: "GET" | "POST";
|
|
760
|
+
/** Path on the agentres host, e.g. `/api/me`. */
|
|
761
|
+
path: string;
|
|
762
|
+
/** JSON body, for POSTs. */
|
|
763
|
+
body?: unknown;
|
|
764
|
+
}
|
|
765
|
+
/** `POST /api/account` — the wallet-bound account, resolved or created. */
|
|
766
|
+
interface AgentresAccount {
|
|
767
|
+
accountId: string;
|
|
768
|
+
email: string | null;
|
|
769
|
+
/** `wallet` for this flow; `api_key` is the other auth path agentres offers. */
|
|
770
|
+
credentialKind: string;
|
|
771
|
+
walletLinked: boolean;
|
|
772
|
+
}
|
|
773
|
+
/** `POST /api/link-resy` — which half of the OTP exchange just completed. */
|
|
774
|
+
interface AgentresLinkStep {
|
|
775
|
+
step: "code_sent" | "linked";
|
|
776
|
+
message?: string;
|
|
777
|
+
/** Present once linked. */
|
|
778
|
+
resyUserId?: number;
|
|
779
|
+
}
|
|
780
|
+
/** `GET /api/me` — what the tile renders from. */
|
|
781
|
+
interface AgentresLinkStatus {
|
|
782
|
+
accountId: string;
|
|
783
|
+
email: string | null;
|
|
784
|
+
resyLinked: boolean;
|
|
785
|
+
/** The address agentres resolved from the proof. Base58, despite the OpenAPI's 0x pattern. */
|
|
786
|
+
walletAddress: string | null;
|
|
787
|
+
resyLinkedAt: string | null;
|
|
788
|
+
}
|
|
789
|
+
interface AgentresClient {
|
|
790
|
+
/**
|
|
791
|
+
* Make one call, satisfying its 402 with a fresh SIWX proof.
|
|
792
|
+
*
|
|
793
|
+
* Always two requests: the first is unauthenticated and expected to answer
|
|
794
|
+
* 402, the second carries the proof. Nonces are single-use and expire minutes
|
|
795
|
+
* after they are issued, so nothing here is cached — a reused challenge works
|
|
796
|
+
* in a fast dev loop and fails in real use.
|
|
797
|
+
*/
|
|
798
|
+
withSiwx<T>(request: AgentresRequest): Promise<T>;
|
|
799
|
+
ensureAccount(email: string): Promise<AgentresAccount>;
|
|
800
|
+
requestCode(email: string): Promise<AgentresLinkStep>;
|
|
801
|
+
verifyCode(email: string, code: string): Promise<AgentresLinkStep>;
|
|
802
|
+
getLinkStatus(): Promise<AgentresLinkStatus>;
|
|
803
|
+
}
|
|
804
|
+
/**
|
|
805
|
+
* Build a client bound to one wallet.
|
|
806
|
+
*
|
|
807
|
+
* The client holds no state between calls, deliberately. The pending code lives
|
|
808
|
+
* at agentres, keyed by email, and step three of the flow sends the user out to
|
|
809
|
+
* their inbox — on a phone that can unmount the page, so the instance that
|
|
810
|
+
* requested the code is often not the instance that verifies it. A client that
|
|
811
|
+
* remembered would refuse a code that is still perfectly valid upstream.
|
|
812
|
+
*/
|
|
813
|
+
declare function createAgentresClient(options: AgentresClientOptions): AgentresClient;
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
* Typed errors for the agentres connector.
|
|
817
|
+
*
|
|
818
|
+
* agentres states every refusal in one envelope, on every route:
|
|
819
|
+
*
|
|
820
|
+
* ```json
|
|
821
|
+
* { "error": { "code": "NO_LINKED_ACCOUNT", "message": "…", "retryable": false,
|
|
822
|
+
* "next_step": "Call POST /api/link-resy with the account email." } }
|
|
823
|
+
* ```
|
|
824
|
+
*
|
|
825
|
+
* `next_step` is often the only actionable part — it is the provider's own
|
|
826
|
+
* sentence about what to do next — so it is carried through to the caller
|
|
827
|
+
* rather than folded into the message. The registration UI shows the raw code
|
|
828
|
+
* and message, which is deliberate: a refusal here is usually the user's Resy
|
|
829
|
+
* account state, not a bug, and paraphrasing it hides what to fix.
|
|
830
|
+
*
|
|
831
|
+
* The SIWX errors are separate because they are ours, not the provider's: they
|
|
832
|
+
* mean the challenge never became a usable proof, so no request was authorized.
|
|
833
|
+
*
|
|
834
|
+
* @module lib/connectors/agentres/errors
|
|
835
|
+
*/
|
|
836
|
+
/**
|
|
837
|
+
* Provider codes the registration flow can return.
|
|
838
|
+
*
|
|
839
|
+
* `AgentresError.code` stays a plain `string` — agentres documents two dozen
|
|
840
|
+
* more for the booking routes, and new ones appear without a version bump —
|
|
841
|
+
* but these four are the ones a registration surface has to handle by name.
|
|
842
|
+
*/
|
|
843
|
+
type AgentresErrorCode = "NO_LINKED_ACCOUNT" | "RESY_VERIFICATION_FAILED" | "RESY_NO_PAYMENT_METHOD" | "UNAUTHORIZED";
|
|
844
|
+
/** A refusal agentres stated, decoded from its error envelope. */
|
|
845
|
+
declare class AgentresError extends Error {
|
|
846
|
+
/** HTTP status the refusal arrived with. */
|
|
847
|
+
readonly status: number;
|
|
848
|
+
/** Provider's stable machine-readable code, e.g. `NO_LINKED_ACCOUNT`. */
|
|
849
|
+
readonly code: string;
|
|
850
|
+
/** Whether the provider says the same call could work later. */
|
|
851
|
+
readonly retryable: boolean;
|
|
852
|
+
/** What the provider says to do about it, when it says anything. */
|
|
853
|
+
readonly nextStep?: string;
|
|
854
|
+
constructor(status: number, code: string, message: string, retryable: boolean, nextStep?: string);
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* The 402 carried no `sign-in-with-x` extension.
|
|
858
|
+
*
|
|
859
|
+
* That marks a paid endpoint, which SIWX cannot satisfy. Signing anyway would
|
|
860
|
+
* produce a well-formed proof the server answers with a bare 401, so the cause
|
|
861
|
+
* has to be named here or it surfaces as an authentication mystery later.
|
|
862
|
+
*/
|
|
863
|
+
declare class SiwxUnsupportedError extends Error {
|
|
864
|
+
constructor(message: string);
|
|
865
|
+
}
|
|
866
|
+
/** The challenge could not be read, or is missing something the proof needs. */
|
|
867
|
+
declare class SiwxChallengeError extends Error {
|
|
868
|
+
/** The underlying decode failure, when there was one. */
|
|
869
|
+
readonly cause?: unknown;
|
|
870
|
+
constructor(message: string, options?: {
|
|
871
|
+
cause?: unknown;
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
|
|
709
875
|
/**
|
|
710
876
|
* Token-getter factory shared by every connector tool factory.
|
|
711
877
|
*
|
|
@@ -2849,4 +3015,4 @@ declare const DEFAULT_MAX_DOCUMENT_CONVERSATIONS = 1000;
|
|
|
2849
3015
|
*/
|
|
2850
3016
|
declare function createDocumentTools({ getConversationId, storage, logError, displayDocument, maxConversations, }: CreateDocumentToolsOptions): ToolConfig[];
|
|
2851
3017
|
|
|
2852
|
-
export { ADD_SLIDE_SCHEMA, APP_BUILDER_PROMPT, APP_COMPLETE_CONNECT_ACK_TYPE, APP_COMPLETE_CONNECT_TYPE, APP_COMPLETE_DEFAULT_TIMEOUT_MS, APP_COMPLETE_IFRAME_SHIM_SCRIPT, APP_COMPLETE_REQUEST_TYPE, APP_COMPLETE_RESPONSE_TYPE, APP_COMPLETE_STUB_SCRIPT, APP_FILE_TOOL_NAMES, APP_PREVIEW_BASELINE_CSS, AUDIT_DESIGN_SCHEMA, type AnchorMatch, type AnumaChild, AnumaJsxError, type AnumaNode, type AppCompleteBridge, type AppCompleteBridgeOptions, type AppFileRecord, type AppFileStorage, type AttrValue, type AuditIssue, type AuditIssueType, type AuditResult, type AuditSeverity, type AuditTokens, type BuildSlideSystemPromptOptions, CONNECTOR_ERROR_MARKER, CREATE_DOCUMENT_SCHEMA, CREATE_FILE_SCHEMA, CRITIQUE_DESIGN_SCHEMA, type CalendarEvent, type ChartDataPoint, type ChoiceOption, type ConnectorErrorCode, type ConnectorMintError, type ConnectorMintResult, type ConnectorTokenGetterOpts, type ConnectorTokenSource, type CreateAppGenerationToolsOptions, type CreateDocumentToolsOptions, type CreateEventArgs, type CreateFileArgs, type CreateSlideToolsOptions, type CreateUIToolsOptions, type CreateWeatherToolOptions, DEFAULT_DESIGN_CRITIQUE_RUBRIC, DEFAULT_DOCUMENT_ID, DEFAULT_MAX_CONVERSATIONS, DEFAULT_MAX_DOCUMENT_CONVERSATIONS, DELETE_FILE_SCHEMA, DOCUMENT_BUILDER_PROMPT, DOCUMENT_TOOL_NAMES, type DisplayChartResult, type DisplayConnectorResult, type DisplayPhoneCallOfferResult, type DisplayToolConfig, type DisplayToolMigrations, type DisplayWeatherResult, type DocAttrValue, type DocChild, DocDslError, type DocNode, type DriveFile, type DropboxRequestAccess, type DropboxTokenGetter, type ExportAppOptions, FONT_LIBRARY, FONT_PRESETS, type FileChangeEvent, type FileSnippet, type FontCategory, type FontPreset, type FontSpec, type ForecastDay, type FormField, type FormFieldOption, type FormFieldType, type GetFileContentArgs, type GmailGetMessageArgs, type GmailMessageDetail, type GmailMessageSummary, type GmailRequestAccess, type GmailSearchArgs, type GmailSendMessageArgs, type GmailTokenGetter, type InteractiveToolConfig, type KnownTag, LAYOUT_MODES, LIST_FILES_SCHEMA, type LayoutMode, type LegacyDeckJson, type ListEventsArgs, type ListRecentFilesArgs, MapFileStorage, type NotionCreatePagesArgs, type NotionFetchArgs, type NotionMovePagesArgs, type NotionSearchArgs, type NotionUpdatePageArgs, PATCH_DOCUMENT_SCHEMA, PATCH_FILE_SCHEMA, PATCH_SLIDES_SCHEMA, PLAN_DECK_SCHEMA, type PatchFailure, type PatchFailureReason, type PdfTag, READ_DOCUMENT_SCHEMA, READ_FILE_SCHEMA, READ_SLIDES_SCHEMA, RUNTIME_ERROR_OVERLAY_SCRIPT, SLIDES_FILE_PATH, SLIDE_CANVAS_HEIGHT, SLIDE_CANVAS_WIDTH, type SearchFilesArgs, type SlackGetChannelHistoryArgs, type SlackGetThreadRepliesArgs, type SlackListChannelsArgs, type SlackListDmsArgs, type SlackListUsersArgs, type SlackPostMessageArgs, type SlackProxyCaller, type SlackSearchMessagesArgs, type SlideToolSet, THEME_ATTRS, type ThemeAttr, type ToolConfig, type ToolExecutionErrorType, type ToolExecutionResult, type UIInteractionContext, type UpdateEventArgs, type UpdateFileArgs, VERIFY_APP_SCHEMA, type VerifyAppResult, type XGetMeArgs, type XGetMyPostsArgs, type XProxyCaller, applyPatches, auditDesign, buildAppFileManifest, buildAppSystemPrompt, buildConnectorErrorResult, buildDocumentSystemPrompt, buildFontsUrl, buildSlideSystemPrompt, callNotionMCPTool, connectorMintErrorToToolResult, convertLegacyDeckJson, createAppCompleteBridge, createAppGenerationTools, createChartTool, createChatTools, createChoiceTool, createConnectorOfferTool, createConnectorTokenGetter, createDisplayTool, createDocumentTools, createDriveTools, createDropboxTools, createFormTool, createGitHubTools, createGmailTools, createGoogleCalendarCreateEventTool, createGoogleCalendarTool, createGoogleCalendarUpdateEventTool, createGoogleDriveCreateFileTool, createGoogleDriveGetContentTool, createGoogleDriveListRecentTool, createGoogleDriveSearchTool, createGoogleDriveUpdateFileTool, createInteractiveTool, createNotionCreateCommentTool, createNotionCreateDatabaseTool, createNotionCreatePagesTool, createNotionDuplicatePageTool, createNotionFetchTool, createNotionGetCommentsTool, createNotionGetTeamsTool, createNotionGetUsersTool, createNotionMovePagesTool, createNotionSearchTool, createNotionTools, createNotionUpdateDataSourceTool, createNotionUpdatePageTool, createPhoneCallOfferTool, createSlackTools, createSlideTools, createWeatherTool, createXTools, documentPath, exportAppToHtml, findById, findParentOfId, getFontByName, getId, getMCPEndpoints, getNumberAttr, getStringAttr, insertAfterId, insertChild, installAppCompleteIframeShim, isAnumaTag, isHtmlTag, isKnownFont, isLegacyDeckJson, isPdfTag, migrateDisplayResult, normalizePath, parseDocumentDsl, parseJsx, pdfStyleKeys, pdfTags, removeById, replaceById, serializeJsx, truncateContent, updateAttrs, walk };
|
|
3018
|
+
export { ADD_SLIDE_SCHEMA, APP_BUILDER_PROMPT, APP_COMPLETE_CONNECT_ACK_TYPE, APP_COMPLETE_CONNECT_TYPE, APP_COMPLETE_DEFAULT_TIMEOUT_MS, APP_COMPLETE_IFRAME_SHIM_SCRIPT, APP_COMPLETE_REQUEST_TYPE, APP_COMPLETE_RESPONSE_TYPE, APP_COMPLETE_STUB_SCRIPT, APP_FILE_TOOL_NAMES, APP_PREVIEW_BASELINE_CSS, AUDIT_DESIGN_SCHEMA, type AgentresAccount, type AgentresClient, type AgentresClientOptions, AgentresError, type AgentresErrorCode, type AgentresLinkStatus, type AgentresLinkStep, type AnchorMatch, type AnumaChild, AnumaJsxError, type AnumaNode, type AppCompleteBridge, type AppCompleteBridgeOptions, type AppFileRecord, type AppFileStorage, type AttrValue, type AuditIssue, type AuditIssueType, type AuditResult, type AuditSeverity, type AuditTokens, type BuildSlideSystemPromptOptions, CONNECTOR_ERROR_MARKER, CREATE_DOCUMENT_SCHEMA, CREATE_FILE_SCHEMA, CRITIQUE_DESIGN_SCHEMA, type CalendarEvent, type ChartDataPoint, type ChoiceOption, type ConnectorErrorCode, type ConnectorMintError, type ConnectorMintResult, type ConnectorTokenGetterOpts, type ConnectorTokenSource, type CreateAppGenerationToolsOptions, type CreateDocumentToolsOptions, type CreateEventArgs, type CreateFileArgs, type CreateSlideToolsOptions, type CreateUIToolsOptions, type CreateWeatherToolOptions, DEFAULT_DESIGN_CRITIQUE_RUBRIC, DEFAULT_DOCUMENT_ID, DEFAULT_MAX_CONVERSATIONS, DEFAULT_MAX_DOCUMENT_CONVERSATIONS, DELETE_FILE_SCHEMA, DOCUMENT_BUILDER_PROMPT, DOCUMENT_TOOL_NAMES, type DisplayChartResult, type DisplayConnectorResult, type DisplayPhoneCallOfferResult, type DisplayToolConfig, type DisplayToolMigrations, type DisplayWeatherResult, type DocAttrValue, type DocChild, DocDslError, type DocNode, type DriveFile, type DropboxRequestAccess, type DropboxTokenGetter, type ExportAppOptions, FONT_LIBRARY, FONT_PRESETS, type FileChangeEvent, type FileSnippet, type FontCategory, type FontPreset, type FontSpec, type ForecastDay, type FormField, type FormFieldOption, type FormFieldType, type GetFileContentArgs, type GmailGetMessageArgs, type GmailMessageDetail, type GmailMessageSummary, type GmailRequestAccess, type GmailSearchArgs, type GmailSendMessageArgs, type GmailTokenGetter, type InteractiveToolConfig, type KnownTag, LAYOUT_MODES, LIST_FILES_SCHEMA, type LayoutMode, type LegacyDeckJson, type ListEventsArgs, type ListRecentFilesArgs, MapFileStorage, type NotionCreatePagesArgs, type NotionFetchArgs, type NotionMovePagesArgs, type NotionSearchArgs, type NotionUpdatePageArgs, PATCH_DOCUMENT_SCHEMA, PATCH_FILE_SCHEMA, PATCH_SLIDES_SCHEMA, PLAN_DECK_SCHEMA, type PatchFailure, type PatchFailureReason, type PdfTag, READ_DOCUMENT_SCHEMA, READ_FILE_SCHEMA, READ_SLIDES_SCHEMA, RUNTIME_ERROR_OVERLAY_SCRIPT, SLIDES_FILE_PATH, SLIDE_CANVAS_HEIGHT, SLIDE_CANVAS_WIDTH, type SearchFilesArgs, SiwxChallengeError, SiwxUnsupportedError, type SlackGetChannelHistoryArgs, type SlackGetThreadRepliesArgs, type SlackListChannelsArgs, type SlackListDmsArgs, type SlackListUsersArgs, type SlackPostMessageArgs, type SlackProxyCaller, type SlackSearchMessagesArgs, type SlideToolSet, type SolanaSignMessageFn, THEME_ATTRS, type ThemeAttr, type ToolConfig, type ToolExecutionErrorType, type ToolExecutionResult, type UIInteractionContext, type UpdateEventArgs, type UpdateFileArgs, VERIFY_APP_SCHEMA, type VerifyAppResult, type XGetMeArgs, type XGetMyPostsArgs, type XProxyCaller, applyPatches, auditDesign, buildAppFileManifest, buildAppSystemPrompt, buildConnectorErrorResult, buildDocumentSystemPrompt, buildFontsUrl, buildSlideSystemPrompt, callNotionMCPTool, connectorMintErrorToToolResult, convertLegacyDeckJson, createAgentresClient, createAppCompleteBridge, createAppGenerationTools, createChartTool, createChatTools, createChoiceTool, createConnectorOfferTool, createConnectorTokenGetter, createDisplayTool, createDocumentTools, createDriveTools, createDropboxTools, createFormTool, createGitHubTools, createGmailTools, createGoogleCalendarCreateEventTool, createGoogleCalendarTool, createGoogleCalendarUpdateEventTool, createGoogleDriveCreateFileTool, createGoogleDriveGetContentTool, createGoogleDriveListRecentTool, createGoogleDriveSearchTool, createGoogleDriveUpdateFileTool, createInteractiveTool, createNotionCreateCommentTool, createNotionCreateDatabaseTool, createNotionCreatePagesTool, createNotionDuplicatePageTool, createNotionFetchTool, createNotionGetCommentsTool, createNotionGetTeamsTool, createNotionGetUsersTool, createNotionMovePagesTool, createNotionSearchTool, createNotionTools, createNotionUpdateDataSourceTool, createNotionUpdatePageTool, createPhoneCallOfferTool, createSlackTools, createSlideTools, createWeatherTool, createXTools, documentPath, exportAppToHtml, findById, findParentOfId, getFontByName, getId, getMCPEndpoints, getNumberAttr, getStringAttr, insertAfterId, insertChild, installAppCompleteIframeShim, isAnumaTag, isHtmlTag, isKnownFont, isLegacyDeckJson, isPdfTag, migrateDisplayResult, normalizePath, parseDocumentDsl, parseJsx, pdfStyleKeys, pdfTags, removeById, replaceById, serializeJsx, truncateContent, updateAttrs, walk };
|
package/dist/tools/index.mjs
CHANGED
|
@@ -586,7 +586,7 @@ function createPhoneCallOfferTool(options) {
|
|
|
586
586
|
function createConnectorOfferTool(options) {
|
|
587
587
|
return createDisplayTool(options, {
|
|
588
588
|
name: "display_connector",
|
|
589
|
-
description: "Display an inline card that prompts the user to connect an app or service (for example Notion, Gmail, Google Drive, Google Calendar, GitHub, Dropbox). Call this when the user asks to connect, link, enable, or authorize one of these apps, or when answering their request requires access the user has not yet granted. The card renders the connect prompt visually; do NOT repeat the connection instructions in your text response.",
|
|
589
|
+
description: "Display an inline card that prompts the user to connect an app or service (for example Notion, Gmail, Google Drive, Google Calendar, GitHub, Dropbox, or Agentic Reservations for restaurant bookings, id 'agentres'). Call this when the user asks to connect, link, enable, or authorize one of these apps, or when answering their request requires access the user has not yet granted. The card renders the connect prompt visually; do NOT repeat the connection instructions in your text response.",
|
|
590
590
|
parameters: {
|
|
591
591
|
type: "object",
|
|
592
592
|
properties: {
|
|
@@ -2401,6 +2401,344 @@ function createGitHubTools(getAccessToken, requestGitHubAccess) {
|
|
|
2401
2401
|
];
|
|
2402
2402
|
}
|
|
2403
2403
|
|
|
2404
|
+
// src/lib/connectors/agentres/errors.ts
|
|
2405
|
+
var AgentresError = class extends Error {
|
|
2406
|
+
constructor(status, code, message, retryable, nextStep) {
|
|
2407
|
+
super(message);
|
|
2408
|
+
this.name = "AgentresError";
|
|
2409
|
+
this.status = status;
|
|
2410
|
+
this.code = code;
|
|
2411
|
+
this.retryable = retryable;
|
|
2412
|
+
this.nextStep = nextStep;
|
|
2413
|
+
}
|
|
2414
|
+
};
|
|
2415
|
+
var SiwxUnsupportedError = class extends Error {
|
|
2416
|
+
constructor(message) {
|
|
2417
|
+
super(message);
|
|
2418
|
+
this.name = "SiwxUnsupportedError";
|
|
2419
|
+
}
|
|
2420
|
+
};
|
|
2421
|
+
var SiwxChallengeError = class extends Error {
|
|
2422
|
+
constructor(message, options) {
|
|
2423
|
+
super(message);
|
|
2424
|
+
this.name = "SiwxChallengeError";
|
|
2425
|
+
this.cause = options?.cause;
|
|
2426
|
+
}
|
|
2427
|
+
};
|
|
2428
|
+
function parseAgentresError(status, body) {
|
|
2429
|
+
const stated = statedError(body);
|
|
2430
|
+
if (!stated) {
|
|
2431
|
+
return new AgentresError(
|
|
2432
|
+
status,
|
|
2433
|
+
`HTTP_${status}`,
|
|
2434
|
+
body.trim() || `HTTP ${status}`,
|
|
2435
|
+
status >= 500
|
|
2436
|
+
);
|
|
2437
|
+
}
|
|
2438
|
+
const code = typeof stated.code === "string" ? stated.code : `HTTP_${status}`;
|
|
2439
|
+
const message = typeof stated.message === "string" ? stated.message : `HTTP ${status}`;
|
|
2440
|
+
const retryable = typeof stated.retryable === "boolean" ? stated.retryable : status >= 500;
|
|
2441
|
+
const nextStep = typeof stated.next_step === "string" ? stated.next_step : void 0;
|
|
2442
|
+
return new AgentresError(status, code, message, retryable, nextStep);
|
|
2443
|
+
}
|
|
2444
|
+
function statedError(body) {
|
|
2445
|
+
let parsed;
|
|
2446
|
+
try {
|
|
2447
|
+
parsed = JSON.parse(body);
|
|
2448
|
+
} catch {
|
|
2449
|
+
return null;
|
|
2450
|
+
}
|
|
2451
|
+
const envelope = parsed;
|
|
2452
|
+
const stated = typeof envelope?.error === "object" && envelope.error !== null ? envelope.error : null;
|
|
2453
|
+
if (!stated) {
|
|
2454
|
+
return null;
|
|
2455
|
+
}
|
|
2456
|
+
const fields = stated;
|
|
2457
|
+
if (typeof fields.code !== "string" && typeof fields.message !== "string") {
|
|
2458
|
+
return null;
|
|
2459
|
+
}
|
|
2460
|
+
return fields;
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
// src/lib/processors/encoding.ts
|
|
2464
|
+
var B64_ENCODE_CHUNK = 32768 * 3;
|
|
2465
|
+
function uint8ArrayToBase64(data) {
|
|
2466
|
+
if (typeof Buffer !== "undefined") {
|
|
2467
|
+
return Buffer.from(data).toString("base64");
|
|
2468
|
+
}
|
|
2469
|
+
let base64 = "";
|
|
2470
|
+
for (let i = 0; i < data.length; i += B64_ENCODE_CHUNK) {
|
|
2471
|
+
const slice = data.subarray(i, i + B64_ENCODE_CHUNK);
|
|
2472
|
+
let binary = "";
|
|
2473
|
+
for (let j = 0; j < slice.length; j++) {
|
|
2474
|
+
binary += String.fromCharCode(slice[j]);
|
|
2475
|
+
}
|
|
2476
|
+
base64 += btoa(binary);
|
|
2477
|
+
}
|
|
2478
|
+
return base64;
|
|
2479
|
+
}
|
|
2480
|
+
function base64ToUint8Array(base64) {
|
|
2481
|
+
if (typeof Buffer !== "undefined") {
|
|
2482
|
+
const buf = Buffer.from(base64, "base64");
|
|
2483
|
+
return new Uint8Array(buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength));
|
|
2484
|
+
}
|
|
2485
|
+
const binary = atob(base64);
|
|
2486
|
+
const bytes = new Uint8Array(binary.length);
|
|
2487
|
+
for (let i = 0; i < binary.length; i++) {
|
|
2488
|
+
bytes[i] = binary.charCodeAt(i);
|
|
2489
|
+
}
|
|
2490
|
+
return bytes;
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2493
|
+
// src/lib/connectors/agentres/siwx.ts
|
|
2494
|
+
var PAYMENT_REQUIRED_HEADER = "PAYMENT-REQUIRED";
|
|
2495
|
+
var SIWX_HEADER = "SIGN-IN-WITH-X";
|
|
2496
|
+
var SIWX_EXTENSION = "sign-in-with-x";
|
|
2497
|
+
var SOLANA_NAMESPACE = "solana:";
|
|
2498
|
+
function parseChallenge(paymentRequiredHeader, expectedOrigin) {
|
|
2499
|
+
const decoded = decodeHeader(paymentRequiredHeader);
|
|
2500
|
+
const extensions = asRecord(decoded.extensions);
|
|
2501
|
+
const extension = extensions ? asRecord(extensions[SIWX_EXTENSION]) : null;
|
|
2502
|
+
if (!extension) {
|
|
2503
|
+
throw new SiwxUnsupportedError(
|
|
2504
|
+
"the 402 carries no sign-in-with-x extension, so this endpoint is paid rather than identity-only"
|
|
2505
|
+
);
|
|
2506
|
+
}
|
|
2507
|
+
const info = asRecord(extension.info);
|
|
2508
|
+
if (!info) {
|
|
2509
|
+
throw new SiwxChallengeError("the sign-in-with-x extension has no info block");
|
|
2510
|
+
}
|
|
2511
|
+
const chain = solanaChain(extension.supportedChains);
|
|
2512
|
+
const challenge = {
|
|
2513
|
+
domain: requireString(info, "domain"),
|
|
2514
|
+
uri: requireString(info, "uri"),
|
|
2515
|
+
version: requireString(info, "version"),
|
|
2516
|
+
statement: requireString(info, "statement"),
|
|
2517
|
+
nonce: requireString(info, "nonce"),
|
|
2518
|
+
issuedAt: requireString(info, "issuedAt"),
|
|
2519
|
+
resources: requireResources(info),
|
|
2520
|
+
chainId: chain.chainId,
|
|
2521
|
+
signingType: chain.signingType
|
|
2522
|
+
};
|
|
2523
|
+
assertScopedTo(challenge, expectedOrigin);
|
|
2524
|
+
return challenge;
|
|
2525
|
+
}
|
|
2526
|
+
function assertScopedTo(challenge, expectedOrigin) {
|
|
2527
|
+
const expected = parseUrl(expectedOrigin, `the agentres base URL "${expectedOrigin}"`);
|
|
2528
|
+
if (challenge.domain !== expected.host) {
|
|
2529
|
+
throw new SiwxChallengeError(
|
|
2530
|
+
`the challenge is scoped to "${challenge.domain}" but this client talks to "${expected.host}" \u2014 refusing to sign it`
|
|
2531
|
+
);
|
|
2532
|
+
}
|
|
2533
|
+
const uri = parseUrl(challenge.uri, `the sign-in-with-x uri "${challenge.uri}"`);
|
|
2534
|
+
if (uri.origin !== expected.origin) {
|
|
2535
|
+
throw new SiwxChallengeError(
|
|
2536
|
+
`the challenge addresses "${uri.origin}" but this client talks to "${expected.origin}" \u2014 refusing to sign it`
|
|
2537
|
+
);
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
function parseUrl(value, description) {
|
|
2541
|
+
try {
|
|
2542
|
+
return new URL(value);
|
|
2543
|
+
} catch (cause) {
|
|
2544
|
+
throw new SiwxChallengeError(`${description} is not a URL`, { cause });
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
function buildMessage(challenge, address) {
|
|
2548
|
+
if (!challenge.chainId.startsWith(SOLANA_NAMESPACE)) {
|
|
2549
|
+
throw new SiwxChallengeError(
|
|
2550
|
+
`expected a solana: chain id for the message, got "${challenge.chainId}"`
|
|
2551
|
+
);
|
|
2552
|
+
}
|
|
2553
|
+
const reference = challenge.chainId.slice(SOLANA_NAMESPACE.length);
|
|
2554
|
+
const resources = challenge.resources.map((resource) => `- ${resource}`).join("\n");
|
|
2555
|
+
return `${challenge.domain} wants you to sign in with your Solana account:
|
|
2556
|
+
${address}
|
|
2557
|
+
|
|
2558
|
+
${challenge.statement}
|
|
2559
|
+
|
|
2560
|
+
URI: ${challenge.uri}
|
|
2561
|
+
Version: ${challenge.version}
|
|
2562
|
+
Chain ID: ${reference}
|
|
2563
|
+
Nonce: ${challenge.nonce}
|
|
2564
|
+
Issued At: ${challenge.issuedAt}
|
|
2565
|
+
Resources:
|
|
2566
|
+
${resources}`;
|
|
2567
|
+
}
|
|
2568
|
+
function buildPayload(challenge, address, signature) {
|
|
2569
|
+
const payload = {
|
|
2570
|
+
domain: challenge.domain,
|
|
2571
|
+
address,
|
|
2572
|
+
statement: challenge.statement,
|
|
2573
|
+
uri: challenge.uri,
|
|
2574
|
+
version: challenge.version,
|
|
2575
|
+
// Full CAIP-2 here, unlike the bare reference the message carries.
|
|
2576
|
+
chainId: challenge.chainId,
|
|
2577
|
+
type: challenge.signingType,
|
|
2578
|
+
nonce: challenge.nonce,
|
|
2579
|
+
issuedAt: challenge.issuedAt,
|
|
2580
|
+
resources: challenge.resources,
|
|
2581
|
+
signature: base58Encode(signature)
|
|
2582
|
+
};
|
|
2583
|
+
return uint8ArrayToBase64(new TextEncoder().encode(JSON.stringify(payload)));
|
|
2584
|
+
}
|
|
2585
|
+
var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
2586
|
+
function base58Encode(bytes) {
|
|
2587
|
+
let zeros = 0;
|
|
2588
|
+
while (zeros < bytes.length && bytes[zeros] === 0) {
|
|
2589
|
+
zeros++;
|
|
2590
|
+
}
|
|
2591
|
+
const digits = [];
|
|
2592
|
+
for (let i = zeros; i < bytes.length; i++) {
|
|
2593
|
+
let carry = bytes[i];
|
|
2594
|
+
for (let j = 0; j < digits.length; j++) {
|
|
2595
|
+
carry += digits[j] * 256;
|
|
2596
|
+
digits[j] = carry % 58;
|
|
2597
|
+
carry = Math.floor(carry / 58);
|
|
2598
|
+
}
|
|
2599
|
+
while (carry > 0) {
|
|
2600
|
+
digits.push(carry % 58);
|
|
2601
|
+
carry = Math.floor(carry / 58);
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
let encoded = "1".repeat(zeros);
|
|
2605
|
+
for (let i = digits.length - 1; i >= 0; i--) {
|
|
2606
|
+
encoded += BASE58_ALPHABET[digits[i]];
|
|
2607
|
+
}
|
|
2608
|
+
return encoded;
|
|
2609
|
+
}
|
|
2610
|
+
function decodeHeader(paymentRequiredHeader) {
|
|
2611
|
+
let parsed;
|
|
2612
|
+
try {
|
|
2613
|
+
parsed = JSON.parse(new TextDecoder().decode(base64ToUint8Array(paymentRequiredHeader)));
|
|
2614
|
+
} catch (cause) {
|
|
2615
|
+
throw new SiwxChallengeError("the PAYMENT-REQUIRED header is not base64-encoded JSON", {
|
|
2616
|
+
cause
|
|
2617
|
+
});
|
|
2618
|
+
}
|
|
2619
|
+
const decoded = asRecord(parsed);
|
|
2620
|
+
if (!decoded) {
|
|
2621
|
+
throw new SiwxChallengeError("the PAYMENT-REQUIRED header did not decode to an object");
|
|
2622
|
+
}
|
|
2623
|
+
return decoded;
|
|
2624
|
+
}
|
|
2625
|
+
function solanaChain(supportedChains) {
|
|
2626
|
+
if (!Array.isArray(supportedChains)) {
|
|
2627
|
+
throw new SiwxChallengeError("the sign-in-with-x extension lists no supportedChains");
|
|
2628
|
+
}
|
|
2629
|
+
for (const entry of supportedChains) {
|
|
2630
|
+
const chain = asRecord(entry);
|
|
2631
|
+
const chainId = chain?.chainId;
|
|
2632
|
+
if (typeof chainId !== "string" || !chainId.startsWith(SOLANA_NAMESPACE)) {
|
|
2633
|
+
continue;
|
|
2634
|
+
}
|
|
2635
|
+
const signingType = chain?.type;
|
|
2636
|
+
if (typeof signingType !== "string" || signingType === "") {
|
|
2637
|
+
throw new SiwxChallengeError(`the ${chainId} entry declares no signing type`);
|
|
2638
|
+
}
|
|
2639
|
+
return { chainId, signingType };
|
|
2640
|
+
}
|
|
2641
|
+
throw new SiwxChallengeError("the sign-in-with-x extension offers no solana: chain");
|
|
2642
|
+
}
|
|
2643
|
+
function asRecord(value) {
|
|
2644
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
2645
|
+
}
|
|
2646
|
+
function requireString(info, key) {
|
|
2647
|
+
const value = info[key];
|
|
2648
|
+
if (typeof value !== "string" || value === "") {
|
|
2649
|
+
throw new SiwxChallengeError(`the sign-in-with-x info block has no ${key}`);
|
|
2650
|
+
}
|
|
2651
|
+
return value;
|
|
2652
|
+
}
|
|
2653
|
+
function requireResources(info) {
|
|
2654
|
+
const resources = info.resources;
|
|
2655
|
+
if (!Array.isArray(resources) || resources.length === 0) {
|
|
2656
|
+
throw new SiwxChallengeError("the sign-in-with-x info block has no resources");
|
|
2657
|
+
}
|
|
2658
|
+
if (!resources.every((resource) => typeof resource === "string" && resource !== "")) {
|
|
2659
|
+
throw new SiwxChallengeError("the sign-in-with-x resources are not all strings");
|
|
2660
|
+
}
|
|
2661
|
+
return resources;
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2664
|
+
// src/lib/connectors/agentres/client.ts
|
|
2665
|
+
var DEFAULT_BASE_URL = "https://agentres.dev";
|
|
2666
|
+
function createAgentresClient(options) {
|
|
2667
|
+
const baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
2668
|
+
const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
2669
|
+
const { address, signMessage } = options;
|
|
2670
|
+
async function withSiwx(request) {
|
|
2671
|
+
const url = `${baseUrl}${request.path}`;
|
|
2672
|
+
const init = requestInit(request);
|
|
2673
|
+
const challenged = await fetchImpl(url, init);
|
|
2674
|
+
if (challenged.status !== 402) {
|
|
2675
|
+
return readBody(challenged);
|
|
2676
|
+
}
|
|
2677
|
+
await challenged.body?.cancel().catch(() => {
|
|
2678
|
+
});
|
|
2679
|
+
const header = challenged.headers.get(PAYMENT_REQUIRED_HEADER);
|
|
2680
|
+
if (!header) {
|
|
2681
|
+
throw new SiwxChallengeError(
|
|
2682
|
+
`the 402 from ${request.path} carried no ${PAYMENT_REQUIRED_HEADER} header`
|
|
2683
|
+
);
|
|
2684
|
+
}
|
|
2685
|
+
const challenge = parseChallenge(header, baseUrl);
|
|
2686
|
+
const signature = await signMessage(new TextEncoder().encode(buildMessage(challenge, address)));
|
|
2687
|
+
const authorized = await fetchImpl(url, {
|
|
2688
|
+
...init,
|
|
2689
|
+
headers: { ...init.headers, [SIWX_HEADER]: buildPayload(challenge, address, signature) }
|
|
2690
|
+
});
|
|
2691
|
+
return readBody(authorized);
|
|
2692
|
+
}
|
|
2693
|
+
async function linkResy(body) {
|
|
2694
|
+
const response = await withSiwx({ method: "POST", path: "/api/link-resy", body });
|
|
2695
|
+
return { step: response.step, message: response.message, resyUserId: response.resy_user_id };
|
|
2696
|
+
}
|
|
2697
|
+
return {
|
|
2698
|
+
withSiwx,
|
|
2699
|
+
async ensureAccount(email) {
|
|
2700
|
+
const body = await withSiwx({ method: "POST", path: "/api/account", body: { email } });
|
|
2701
|
+
return {
|
|
2702
|
+
accountId: body.account_id,
|
|
2703
|
+
email: body.email,
|
|
2704
|
+
credentialKind: body.credential_kind,
|
|
2705
|
+
walletLinked: body.wallet_linked
|
|
2706
|
+
};
|
|
2707
|
+
},
|
|
2708
|
+
requestCode(email) {
|
|
2709
|
+
return linkResy({ em_address: email });
|
|
2710
|
+
},
|
|
2711
|
+
verifyCode(email, code) {
|
|
2712
|
+
return linkResy({ em_address: email, code });
|
|
2713
|
+
},
|
|
2714
|
+
async getLinkStatus() {
|
|
2715
|
+
const body = await withSiwx({ method: "GET", path: "/api/me" });
|
|
2716
|
+
return {
|
|
2717
|
+
accountId: body.account_id,
|
|
2718
|
+
email: body.email,
|
|
2719
|
+
resyLinked: body.resy_linked,
|
|
2720
|
+
walletAddress: body.wallet_address,
|
|
2721
|
+
resyLinkedAt: body.resy_linked_at ?? null
|
|
2722
|
+
};
|
|
2723
|
+
}
|
|
2724
|
+
};
|
|
2725
|
+
}
|
|
2726
|
+
function requestInit(request) {
|
|
2727
|
+
const headers = { Accept: "application/json" };
|
|
2728
|
+
if (request.body === void 0) {
|
|
2729
|
+
return { method: request.method, headers };
|
|
2730
|
+
}
|
|
2731
|
+
headers["Content-Type"] = "application/json";
|
|
2732
|
+
return { method: request.method, headers, body: JSON.stringify(request.body) };
|
|
2733
|
+
}
|
|
2734
|
+
async function readBody(response) {
|
|
2735
|
+
const body = await response.text();
|
|
2736
|
+
if (!response.ok) {
|
|
2737
|
+
throw parseAgentresError(response.status, body);
|
|
2738
|
+
}
|
|
2739
|
+
return JSON.parse(body);
|
|
2740
|
+
}
|
|
2741
|
+
|
|
2404
2742
|
// src/lib/connectors/client.ts
|
|
2405
2743
|
var DEFAULT_REFRESH_BEFORE_MS = 3e4;
|
|
2406
2744
|
function createConnectorTokenGetter(client, provider, opts = {}) {
|
|
@@ -13526,6 +13864,7 @@ export {
|
|
|
13526
13864
|
APP_FILE_TOOL_NAMES,
|
|
13527
13865
|
APP_PREVIEW_BASELINE_CSS,
|
|
13528
13866
|
AUDIT_DESIGN_SCHEMA,
|
|
13867
|
+
AgentresError,
|
|
13529
13868
|
AnumaJsxError,
|
|
13530
13869
|
CONNECTOR_ERROR_MARKER,
|
|
13531
13870
|
CREATE_DOCUMENT_SCHEMA,
|
|
@@ -13555,6 +13894,8 @@ export {
|
|
|
13555
13894
|
SLIDES_FILE_PATH,
|
|
13556
13895
|
SLIDE_CANVAS_HEIGHT,
|
|
13557
13896
|
SLIDE_CANVAS_WIDTH,
|
|
13897
|
+
SiwxChallengeError,
|
|
13898
|
+
SiwxUnsupportedError,
|
|
13558
13899
|
THEME_ATTRS,
|
|
13559
13900
|
VERIFY_APP_SCHEMA,
|
|
13560
13901
|
applyPatches,
|
|
@@ -13568,6 +13909,7 @@ export {
|
|
|
13568
13909
|
callNotionMCPTool,
|
|
13569
13910
|
connectorMintErrorToToolResult,
|
|
13570
13911
|
convertLegacyDeckJson,
|
|
13912
|
+
createAgentresClient,
|
|
13571
13913
|
createAppCompleteBridge,
|
|
13572
13914
|
createAppGenerationTools,
|
|
13573
13915
|
createChartTool,
|