@ottocode/ai-sdk 0.1.4 → 0.1.6
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/package.json +2 -2
- package/src/auth.ts +62 -27
- package/src/balance.ts +104 -90
- package/src/cache.ts +154 -132
- package/src/catalog.ts +1242 -1487
- package/src/fetch.ts +275 -254
- package/src/index.ts +18 -17
- package/src/payment.ts +199 -136
- package/src/providers/factory.ts +53 -53
- package/src/providers/registry.ts +59 -94
- package/src/setu.ts +119 -75
- package/src/types.ts +93 -79
- package/src/wallet.ts +20 -20
package/src/setu.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type {
|
|
2
|
+
SetuConfig,
|
|
3
|
+
ProviderId,
|
|
4
|
+
ProviderApiFormat,
|
|
5
|
+
FetchFunction,
|
|
6
|
+
BalanceResponse,
|
|
7
|
+
WalletUsdcBalance,
|
|
8
|
+
SetuAuth,
|
|
9
|
+
} from './types.ts';
|
|
10
|
+
import { createWalletContext } from './auth.ts';
|
|
11
|
+
import type { WalletContext } from './auth.ts';
|
|
3
12
|
import { createSetuFetch } from './fetch.ts';
|
|
4
13
|
import { ProviderRegistry } from './providers/registry.ts';
|
|
5
14
|
import { createModel } from './providers/factory.ts';
|
|
@@ -8,86 +17,121 @@ import { fetchBalance, fetchWalletUsdcBalance } from './balance.ts';
|
|
|
8
17
|
const DEFAULT_BASE_URL = 'https://api.setu.ottocode.io';
|
|
9
18
|
|
|
10
19
|
function trimTrailingSlash(url: string) {
|
|
11
|
-
|
|
20
|
+
return url.endsWith('/') ? url.slice(0, -1) : url;
|
|
12
21
|
}
|
|
13
22
|
|
|
14
23
|
export interface SetuProvider {
|
|
15
|
-
|
|
24
|
+
model(modelId: string): ReturnType<typeof createModel>;
|
|
16
25
|
}
|
|
17
26
|
|
|
18
27
|
export interface SetuInstance {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
model(modelId: string): ReturnType<typeof createModel>;
|
|
29
|
+
provider(providerId: ProviderId, apiFormat?: ProviderApiFormat): SetuProvider;
|
|
30
|
+
fetch(): FetchFunction;
|
|
31
|
+
balance(): Promise<BalanceResponse | null>;
|
|
32
|
+
walletBalance(
|
|
33
|
+
network?: 'mainnet' | 'devnet',
|
|
34
|
+
): Promise<WalletUsdcBalance | null>;
|
|
35
|
+
walletAddress: string | null;
|
|
36
|
+
registry: ProviderRegistry;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function resolveAuth(auth: SetuAuth): {
|
|
40
|
+
auth: SetuAuth;
|
|
41
|
+
wallet: WalletContext;
|
|
42
|
+
} {
|
|
43
|
+
if (auth.signer) {
|
|
44
|
+
return { auth, wallet: createWalletContext(auth) };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const privateKey = auth.privateKey || process.env.SETU_PRIVATE_KEY;
|
|
48
|
+
if (!privateKey) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
'Setu: either privateKey (or SETU_PRIVATE_KEY env) or signer is required.',
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
const resolvedAuth = { ...auth, privateKey };
|
|
54
|
+
return { auth: resolvedAuth, wallet: createWalletContext(resolvedAuth) };
|
|
26
55
|
}
|
|
27
56
|
|
|
28
57
|
export function createSetu(config: SetuConfig): SetuInstance {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
58
|
+
const baseURL = trimTrailingSlash(config.baseURL ?? DEFAULT_BASE_URL);
|
|
59
|
+
const { auth: resolvedAuth, wallet } = resolveAuth(config.auth);
|
|
60
|
+
const registry = new ProviderRegistry(config.providers, config.modelMap);
|
|
61
|
+
|
|
62
|
+
const setuFetch = createSetuFetch({
|
|
63
|
+
wallet,
|
|
64
|
+
baseURL,
|
|
65
|
+
rpcURL: config.rpcURL,
|
|
66
|
+
callbacks: config.callbacks,
|
|
67
|
+
cache: config.cache,
|
|
68
|
+
payment: config.payment,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const modelBaseURL = `${baseURL}/v1`;
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
model(modelId: string) {
|
|
75
|
+
const resolved = registry.resolve(modelId);
|
|
76
|
+
if (!resolved) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
`Setu: unknown model "${modelId}". Register it via providers or modelMap config.`,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
return createModel(
|
|
82
|
+
modelId,
|
|
83
|
+
resolved.apiFormat,
|
|
84
|
+
resolved.providerId,
|
|
85
|
+
modelBaseURL,
|
|
86
|
+
setuFetch,
|
|
87
|
+
config.middleware,
|
|
88
|
+
);
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
provider(
|
|
92
|
+
providerId: ProviderId,
|
|
93
|
+
apiFormat?: ProviderApiFormat,
|
|
94
|
+
): SetuProvider {
|
|
95
|
+
return {
|
|
96
|
+
model(modelId: string) {
|
|
97
|
+
const resolved = registry.resolve(modelId);
|
|
98
|
+
const format = apiFormat ?? resolved?.apiFormat ?? 'openai-chat';
|
|
99
|
+
return createModel(
|
|
100
|
+
modelId,
|
|
101
|
+
format,
|
|
102
|
+
providerId,
|
|
103
|
+
modelBaseURL,
|
|
104
|
+
setuFetch,
|
|
105
|
+
config.middleware,
|
|
106
|
+
);
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
fetch(): FetchFunction {
|
|
112
|
+
return setuFetch;
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
async balance() {
|
|
116
|
+
return fetchBalance(wallet, baseURL);
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
async walletBalance(network?: 'mainnet' | 'devnet') {
|
|
120
|
+
const walletAddr = wallet.walletAddress;
|
|
121
|
+
if (!resolvedAuth.privateKey && !walletAddr) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
if (resolvedAuth.privateKey) {
|
|
125
|
+
return fetchWalletUsdcBalance(
|
|
126
|
+
resolvedAuth as Required<Pick<SetuAuth, 'privateKey'>>,
|
|
127
|
+
network,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
return fetchWalletUsdcBalance({ walletAddress: walletAddr }, network);
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
walletAddress: wallet.walletAddress,
|
|
134
|
+
|
|
135
|
+
registry,
|
|
136
|
+
};
|
|
93
137
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,50 +1,64 @@
|
|
|
1
1
|
import type { LanguageModelV3Middleware } from '@ai-sdk/provider';
|
|
2
2
|
|
|
3
3
|
export type ProviderId =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export type ProviderApiFormat =
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
| 'openai'
|
|
5
|
+
| 'anthropic'
|
|
6
|
+
| 'google'
|
|
7
|
+
| 'moonshot'
|
|
8
|
+
| 'zai'
|
|
9
|
+
| 'minimax'
|
|
10
|
+
| (string & {});
|
|
11
|
+
|
|
12
|
+
export type ProviderApiFormat =
|
|
13
|
+
| 'openai-responses'
|
|
14
|
+
| 'anthropic-messages'
|
|
15
|
+
| 'openai-chat'
|
|
16
|
+
| 'google-native';
|
|
17
|
+
|
|
18
|
+
export type FetchFunction = (
|
|
19
|
+
input: string | URL | Request,
|
|
20
|
+
init?: RequestInit,
|
|
21
|
+
) => Promise<Response>;
|
|
15
22
|
|
|
16
23
|
export interface ProviderConfig {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
id: ProviderId;
|
|
25
|
+
apiFormat: ProviderApiFormat;
|
|
26
|
+
models?: string[];
|
|
27
|
+
modelPrefix?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface ExternalSigner {
|
|
31
|
+
walletAddress: string;
|
|
32
|
+
signNonce: (nonce: string) => Promise<string> | string;
|
|
33
|
+
signTransaction?: (transaction: Uint8Array) => Promise<Uint8Array>;
|
|
21
34
|
}
|
|
22
35
|
|
|
23
36
|
export interface SetuAuth {
|
|
24
|
-
|
|
37
|
+
privateKey?: string;
|
|
38
|
+
signer?: ExternalSigner;
|
|
25
39
|
}
|
|
26
40
|
|
|
27
41
|
export interface BalanceUpdate {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
costUsd: number;
|
|
43
|
+
balanceRemaining: number;
|
|
44
|
+
inputTokens?: number;
|
|
45
|
+
outputTokens?: number;
|
|
32
46
|
}
|
|
33
47
|
|
|
34
48
|
export interface PaymentCallbacks {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
onPaymentRequired?: (amountUsd: number, currentBalance?: number) => void;
|
|
50
|
+
onPaymentSigning?: () => void;
|
|
51
|
+
onPaymentComplete?: (data: {
|
|
52
|
+
amountUsd: number;
|
|
53
|
+
newBalance: number;
|
|
54
|
+
transactionId?: string;
|
|
55
|
+
}) => void;
|
|
56
|
+
onPaymentError?: (error: string) => void;
|
|
57
|
+
onPaymentApproval?: (info: {
|
|
58
|
+
amountUsd: number;
|
|
59
|
+
currentBalance: number;
|
|
60
|
+
}) => Promise<'crypto' | 'fiat' | 'cancel'>;
|
|
61
|
+
onBalanceUpdate?: (update: BalanceUpdate) => void;
|
|
48
62
|
}
|
|
49
63
|
|
|
50
64
|
export type AnthropicCacheStrategy = 'auto' | 'manual' | 'custom' | false;
|
|
@@ -52,71 +66,71 @@ export type AnthropicCacheStrategy = 'auto' | 'manual' | 'custom' | false;
|
|
|
52
66
|
export type AnthropicCachePlacement = 'first' | 'last' | 'all';
|
|
53
67
|
|
|
54
68
|
export interface AnthropicCacheConfig {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
69
|
+
strategy?: AnthropicCacheStrategy;
|
|
70
|
+
systemBreakpoints?: number;
|
|
71
|
+
messageBreakpoints?: number;
|
|
72
|
+
systemPlacement?: AnthropicCachePlacement;
|
|
73
|
+
messagePlacement?: AnthropicCachePlacement;
|
|
74
|
+
cacheType?: 'ephemeral';
|
|
75
|
+
transform?: (body: Record<string, unknown>) => Record<string, unknown>;
|
|
62
76
|
}
|
|
63
77
|
|
|
64
78
|
export interface CacheOptions {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
79
|
+
promptCacheKey?: string;
|
|
80
|
+
promptCacheRetention?: 'in_memory' | '24h';
|
|
81
|
+
anthropicCaching?: boolean | AnthropicCacheConfig;
|
|
68
82
|
}
|
|
69
83
|
|
|
70
84
|
export interface PaymentOptions {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
85
|
+
topupApprovalMode?: 'auto' | 'approval';
|
|
86
|
+
autoPayThresholdUsd?: number;
|
|
87
|
+
maxRequestAttempts?: number;
|
|
88
|
+
maxPaymentAttempts?: number;
|
|
75
89
|
}
|
|
76
90
|
|
|
77
91
|
export interface SetuConfig {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
92
|
+
auth: SetuAuth;
|
|
93
|
+
baseURL?: string;
|
|
94
|
+
rpcURL?: string;
|
|
95
|
+
providers?: ProviderConfig[];
|
|
96
|
+
modelMap?: Record<string, ProviderId>;
|
|
97
|
+
callbacks?: PaymentCallbacks;
|
|
98
|
+
cache?: CacheOptions;
|
|
99
|
+
payment?: PaymentOptions;
|
|
100
|
+
middleware?: LanguageModelV3Middleware | LanguageModelV3Middleware[];
|
|
87
101
|
}
|
|
88
102
|
|
|
89
103
|
export interface ExactPaymentRequirement {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
104
|
+
scheme: 'exact';
|
|
105
|
+
network: string;
|
|
106
|
+
maxAmountRequired: string;
|
|
107
|
+
asset: string;
|
|
108
|
+
payTo: string;
|
|
109
|
+
description?: string;
|
|
110
|
+
resource?: string;
|
|
111
|
+
extra?: Record<string, unknown>;
|
|
112
|
+
maxTimeoutSeconds?: number;
|
|
99
113
|
}
|
|
100
114
|
|
|
101
115
|
export interface PaymentPayload {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
116
|
+
x402Version: 1;
|
|
117
|
+
scheme: 'exact';
|
|
118
|
+
network: string;
|
|
119
|
+
payload: { transaction: string };
|
|
106
120
|
}
|
|
107
121
|
|
|
108
122
|
export interface BalanceResponse {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
walletAddress: string;
|
|
124
|
+
balance: number;
|
|
125
|
+
totalSpent: number;
|
|
126
|
+
totalTopups: number;
|
|
127
|
+
requestCount: number;
|
|
128
|
+
createdAt?: string;
|
|
129
|
+
lastRequest?: string;
|
|
116
130
|
}
|
|
117
131
|
|
|
118
132
|
export interface WalletUsdcBalance {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
133
|
+
walletAddress: string;
|
|
134
|
+
usdcBalance: number;
|
|
135
|
+
network: 'mainnet' | 'devnet';
|
|
122
136
|
}
|
package/src/wallet.ts
CHANGED
|
@@ -2,33 +2,33 @@ import { Keypair } from '@solana/web3.js';
|
|
|
2
2
|
import bs58 from 'bs58';
|
|
3
3
|
|
|
4
4
|
export interface WalletInfo {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
publicKey: string;
|
|
6
|
+
privateKey: string;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export function generateWallet(): WalletInfo {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
const keypair = Keypair.generate();
|
|
11
|
+
return {
|
|
12
|
+
privateKey: bs58.encode(keypair.secretKey),
|
|
13
|
+
publicKey: keypair.publicKey.toBase58(),
|
|
14
|
+
};
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export function importWallet(privateKey: string): WalletInfo {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
const privateKeyBytes = bs58.decode(privateKey);
|
|
19
|
+
const keypair = Keypair.fromSecretKey(privateKeyBytes);
|
|
20
|
+
return {
|
|
21
|
+
privateKey,
|
|
22
|
+
publicKey: keypair.publicKey.toBase58(),
|
|
23
|
+
};
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export function isValidPrivateKey(privateKey: string): boolean {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
try {
|
|
28
|
+
const bytes = bs58.decode(privateKey);
|
|
29
|
+
Keypair.fromSecretKey(bytes);
|
|
30
|
+
return true;
|
|
31
|
+
} catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
34
|
}
|