@dominusnode/openai-functions 1.0.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/README.md ADDED
@@ -0,0 +1,272 @@
1
+ # DomiNode OpenAI-Compatible Function Calling Schemas
2
+
3
+ OpenAI function-calling schemas and handler implementations for the DomiNode rotating proxy-as-a-service platform. These schemas allow any LLM with function/tool calling support to interact with DomiNode's proxy network, wallet, and agentic wallet APIs.
4
+
5
+ ## What This Is
6
+
7
+ This directory contains:
8
+
9
+ | File | Description |
10
+ |------|-------------|
11
+ | `functions.json` | Array of 8 OpenAI function definitions (JSON Schema format) |
12
+ | `handler.ts` | TypeScript handler that dispatches function calls to the DomiNode API |
13
+ | `handler.py` | Python handler that dispatches function calls to the DomiNode API |
14
+
15
+ The function schemas follow the [OpenAI function calling specification](https://platform.openai.com/docs/guides/function-calling), which has become a de facto standard adopted by Claude (tool_use), Gemini, Mistral, Llama, and others.
16
+
17
+ ## Available Functions
18
+
19
+ | Function | Description | Auth Required |
20
+ |----------|-------------|---------------|
21
+ | `dominusnode_proxied_fetch` | Make an HTTP request through DomiNode's rotating proxy network | Yes |
22
+ | `dominusnode_check_balance` | Check wallet balance (cents, USD, currency) | Yes |
23
+ | `dominusnode_check_usage` | Check usage stats for a time period (day/week/month) | Yes |
24
+ | `dominusnode_get_proxy_config` | Get proxy endpoints, supported countries, geo-targeting info | Yes |
25
+ | `dominusnode_list_sessions` | List currently active proxy sessions | Yes |
26
+ | `dominusnode_create_agentic_wallet` | Create a sub-wallet for an AI agent with spending limits | Yes |
27
+ | `dominusnode_fund_agentic_wallet` | Transfer funds from main wallet to an agentic wallet | Yes |
28
+ | `dominusnode_agentic_wallet_balance` | Check an agentic wallet's balance and status | Yes |
29
+
30
+ ## Usage with OpenAI GPT (Function Calling)
31
+
32
+ ```python
33
+ import json
34
+ import openai
35
+ from handler import create_dominusnode_function_handler
36
+
37
+ # Load function definitions
38
+ with open("functions.json") as f:
39
+ functions = json.load(f)
40
+
41
+ # Create the DomiNode handler
42
+ dominusnode = create_dominusnode_function_handler(
43
+ api_key="dn_live_your_api_key_here",
44
+ base_url="https://api.dominusnode.com",
45
+ )
46
+
47
+ # Create a chat completion with function calling
48
+ client = openai.OpenAI()
49
+ response = client.chat.completions.create(
50
+ model="gpt-4o",
51
+ messages=[
52
+ {"role": "system", "content": "You have access to DomiNode proxy tools."},
53
+ {"role": "user", "content": "What is my current proxy balance?"},
54
+ ],
55
+ functions=functions,
56
+ function_call="auto",
57
+ )
58
+
59
+ # Handle function calls from the LLM
60
+ message = response.choices[0].message
61
+ if message.function_call:
62
+ name = message.function_call.name
63
+ args = json.loads(message.function_call.arguments)
64
+
65
+ # Dispatch to DomiNode handler
66
+ result = await dominusnode(name, args)
67
+
68
+ # Send the result back to the LLM
69
+ response = client.chat.completions.create(
70
+ model="gpt-4o",
71
+ messages=[
72
+ {"role": "system", "content": "You have access to DomiNode proxy tools."},
73
+ {"role": "user", "content": "What is my current proxy balance?"},
74
+ message,
75
+ {"role": "function", "name": name, "content": result},
76
+ ],
77
+ )
78
+ print(response.choices[0].message.content)
79
+ ```
80
+
81
+ ## Usage with Claude (tool_use)
82
+
83
+ Claude uses a `tools` parameter with a slightly different schema format. Convert the OpenAI functions to Claude tool format:
84
+
85
+ ```python
86
+ import json
87
+ import anthropic
88
+ from handler import create_dominusnode_function_handler
89
+
90
+ # Load and convert function definitions to Claude tool format
91
+ with open("functions.json") as f:
92
+ functions = json.load(f)
93
+
94
+ tools = [
95
+ {
96
+ "name": fn["name"],
97
+ "description": fn["description"],
98
+ "input_schema": fn["parameters"],
99
+ }
100
+ for fn in functions
101
+ ]
102
+
103
+ # Create the DomiNode handler
104
+ dominusnode = create_dominusnode_function_handler(
105
+ api_key="dn_live_your_api_key_here",
106
+ )
107
+
108
+ # Create a message with tool use
109
+ client = anthropic.Anthropic()
110
+ response = client.messages.create(
111
+ model="claude-sonnet-4-20250514",
112
+ max_tokens=1024,
113
+ tools=tools,
114
+ messages=[
115
+ {"role": "user", "content": "Check my DomiNode proxy balance and usage this week."},
116
+ ],
117
+ )
118
+
119
+ # Handle tool use blocks
120
+ for block in response.content:
121
+ if block.type == "tool_use":
122
+ result = await dominusnode(block.name, block.input)
123
+
124
+ # Send result back
125
+ response = client.messages.create(
126
+ model="claude-sonnet-4-20250514",
127
+ max_tokens=1024,
128
+ tools=tools,
129
+ messages=[
130
+ {"role": "user", "content": "Check my DomiNode proxy balance and usage this week."},
131
+ {"role": "assistant", "content": response.content},
132
+ {
133
+ "role": "user",
134
+ "content": [
135
+ {
136
+ "type": "tool_result",
137
+ "tool_use_id": block.id,
138
+ "content": result,
139
+ }
140
+ ],
141
+ },
142
+ ],
143
+ )
144
+ print(response.content[0].text)
145
+ ```
146
+
147
+ ## Usage with TypeScript / Node.js
148
+
149
+ ```typescript
150
+ import { readFileSync } from "fs";
151
+ import { createDominusNodeFunctionHandler } from "./handler";
152
+
153
+ // Load function definitions
154
+ const functions = JSON.parse(readFileSync("functions.json", "utf-8"));
155
+
156
+ // Create the handler
157
+ const handler = createDominusNodeFunctionHandler({
158
+ apiKey: "dn_live_your_api_key_here",
159
+ baseUrl: "https://api.dominusnode.com",
160
+ });
161
+
162
+ // Example: direct function call
163
+ const balance = await handler("dominusnode_check_balance", {});
164
+ console.log(JSON.parse(balance));
165
+ // { balanceCents: 5000, balanceUsd: 50.00, currency: "USD", lastToppedUp: "..." }
166
+
167
+ // Example: proxied fetch with geo-targeting
168
+ const fetchResult = await handler("dominusnode_proxied_fetch", {
169
+ url: "https://httpbin.org/ip",
170
+ method: "GET",
171
+ country: "US",
172
+ proxy_type: "residential",
173
+ });
174
+ console.log(JSON.parse(fetchResult));
175
+
176
+ // Example: create and fund an agentic wallet for an AI agent
177
+ const wallet = await handler("dominusnode_create_agentic_wallet", {
178
+ label: "research-agent-1",
179
+ spending_limit_cents: 500, // $5.00 per-transaction limit
180
+ });
181
+ const walletData = JSON.parse(wallet);
182
+
183
+ await handler("dominusnode_fund_agentic_wallet", {
184
+ wallet_id: walletData.id,
185
+ amount_cents: 2000, // Fund with $20.00
186
+ });
187
+ ```
188
+
189
+ ## Usage with Any Function-Calling LLM
190
+
191
+ The `functions.json` file follows the standard OpenAI function definition schema. Most LLM frameworks accept this format directly or with minor adaptation:
192
+
193
+ ### Generic Pattern
194
+
195
+ 1. Load `functions.json` and pass to your LLM as available functions/tools.
196
+ 2. When the LLM returns a function call, extract the function name and arguments.
197
+ 3. Pass them to the handler: `result = await handler(name, args)`.
198
+ 4. Return the result string to the LLM as the function result.
199
+
200
+ ### Framework-Specific Notes
201
+
202
+ | Framework | How to Use |
203
+ |-----------|-----------|
204
+ | **OpenAI SDK** | Pass `functions` directly to `chat.completions.create()` |
205
+ | **Anthropic SDK** | Convert to `tools` format (rename `parameters` to `input_schema`) |
206
+ | **Google Gemini** | Convert to `FunctionDeclaration` objects |
207
+ | **LangChain** | Use `StructuredTool.from_function()` or the DomiNode LangChain integration |
208
+ | **Vercel AI SDK** | See the `integrations/vercel-ai/` package |
209
+ | **LlamaIndex** | Use `FunctionTool.from_defaults()` with the handler |
210
+ | **Ollama** | Pass as `tools` parameter in chat API |
211
+
212
+ ## Security
213
+
214
+ ### SSRF Prevention
215
+
216
+ Both handlers (TypeScript and Python) include comprehensive SSRF prevention that blocks:
217
+
218
+ - **Private IP ranges**: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, 0.0.0.0/8, 169.254.0.0/16, 100.64.0.0/10 (CGNAT)
219
+ - **Non-standard IP representations**: Hex (0x7f000001), octal (0177.0.0.1), decimal integer (2130706433)
220
+ - **IPv6 private ranges**: ::1, fc00::/7, fe80::/10, ::ffff:-mapped private IPs
221
+ - **Internal hostnames**: .localhost, .local, .internal, .arpa TLDs
222
+ - **Protocol restriction**: Only http:// and https:// are allowed
223
+
224
+ ### Header Injection Prevention
225
+
226
+ User-supplied HTTP headers are filtered to block:
227
+ - Security-sensitive headers (Host, Authorization, Proxy-Authorization, etc.)
228
+ - CRLF injection attempts (headers containing \r or \n)
229
+ - Null byte injection
230
+
231
+ ### Sanctioned Countries
232
+
233
+ Requests targeting OFAC-sanctioned countries (CU, IR, KP, RU, SY) are blocked at the handler level before reaching the proxy.
234
+
235
+ ### Input Validation
236
+
237
+ - Integer overflow protection: amount/limit values capped at 2,147,483,647
238
+ - Label length validation: max 100 characters
239
+ - URL-encoding of path parameters to prevent path traversal
240
+ - Prototype pollution prevention in JSON parsing (TypeScript handler)
241
+ - Response body size limit: 10 MB max to prevent OOM
242
+
243
+ ### API Key Security
244
+
245
+ - API keys are never included in function call results returned to the LLM
246
+ - Authentication tokens are stored in handler closure scope (not exported)
247
+ - The handler authenticates lazily on first call and caches the JWT token
248
+
249
+ ## Proxy Pricing
250
+
251
+ | Proxy Type | Price | Best For |
252
+ |------------|-------|----------|
253
+ | Datacenter (`dc`) | $3.00/GB | General scraping, speed-critical tasks |
254
+ | Residential | $5.00/GB | Anti-detection, geo-restricted content |
255
+
256
+ ## Dependencies
257
+
258
+ ### TypeScript Handler
259
+ - Node.js 18+ (uses native `fetch` and `AbortSignal.timeout`)
260
+ - No external dependencies
261
+
262
+ ### Python Handler
263
+ - Python 3.8+
264
+ - `httpx` (`pip install httpx`)
265
+
266
+ ## Related Integrations
267
+
268
+ - `integrations/langchain/` -- LangChain tools integration
269
+ - `integrations/vercel-ai/` -- Vercel AI SDK provider
270
+ - `packages/mcp-server/` -- Model Context Protocol server (34 tools)
271
+ - `sdks/node/` -- Full Node.js SDK
272
+ - `sdks/python/` -- Full Python SDK
@@ -0,0 +1,80 @@
1
+ /**
2
+ * DomiNode OpenAI-compatible function calling handler (TypeScript).
3
+ *
4
+ * Provides a factory function that creates a handler for dispatching
5
+ * OpenAI function calls to the DomiNode REST API. Works with any
6
+ * function-calling LLM system: OpenAI GPT, Anthropic Claude tool_use,
7
+ * Google Gemini, or custom implementations.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { createDominusNodeFunctionHandler } from "./handler";
12
+ *
13
+ * const handler = createDominusNodeFunctionHandler({
14
+ * apiKey: "dn_live_...",
15
+ * baseUrl: "https://api.dominusnode.com",
16
+ * });
17
+ *
18
+ * // Dispatch a function call from an LLM response
19
+ * const result = await handler("dominusnode_check_balance", {});
20
+ * console.log(result); // JSON string with balance info
21
+ * ```
22
+ *
23
+ * @module
24
+ */
25
+ /**
26
+ * Normalize non-standard IPv4 representations (hex, octal, decimal integer)
27
+ * to standard dotted-decimal to prevent SSRF bypasses like 0x7f000001,
28
+ * 2130706433, or 0177.0.0.1.
29
+ */
30
+ declare function normalizeIpv4(hostname: string): string | null;
31
+ declare function isPrivateIp(hostname: string): boolean;
32
+ /**
33
+ * Validate a URL for safety before sending through the proxy.
34
+ * Blocks private IPs, localhost, internal hostnames, and non-HTTP(S) protocols.
35
+ *
36
+ * @throws {Error} If the URL is invalid or targets a private/blocked address.
37
+ */
38
+ declare function validateUrl(url: string): URL;
39
+ declare function stripDangerousKeys(obj: unknown, depth?: number): void;
40
+ declare function safeJsonParse<T>(text: string): T;
41
+ declare function sanitizeError(message: string): string;
42
+ export interface DominusNodeFunctionConfig {
43
+ /** DomiNode API key (starts with dn_live_ or dn_test_). */
44
+ apiKey: string;
45
+ /** Base URL of the DomiNode REST API. Defaults to https://api.dominusnode.com */
46
+ baseUrl?: string;
47
+ /** Request timeout in milliseconds. Defaults to 30000. */
48
+ timeoutMs?: number;
49
+ }
50
+ /**
51
+ * Handler function type returned by createDominusNodeFunctionHandler.
52
+ * Dispatches function calls to the DomiNode API and returns JSON string results.
53
+ */
54
+ export type FunctionHandler = (name: string, args: Record<string, unknown>) => Promise<string>;
55
+ /**
56
+ * Create a DomiNode function handler for OpenAI-compatible function calling.
57
+ *
58
+ * Authenticates using the provided API key, then returns a handler function
59
+ * that dispatches function calls to the appropriate DomiNode REST API endpoint.
60
+ *
61
+ * @param config - API key and optional base URL / timeout.
62
+ * @returns A handler function: (name, args) => Promise<string>
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * import { createDominusNodeFunctionHandler } from "./handler";
67
+ *
68
+ * const handler = createDominusNodeFunctionHandler({
69
+ * apiKey: "dn_live_abc123",
70
+ * baseUrl: "https://api.dominusnode.com",
71
+ * });
72
+ *
73
+ * // Handle a function call from an LLM
74
+ * const result = await handler("dominusnode_check_balance", {});
75
+ * console.log(JSON.parse(result));
76
+ * // { balanceCents: 5000, balanceUsd: 50.00, currency: "USD", lastToppedUp: "..." }
77
+ * ```
78
+ */
79
+ export { isPrivateIp, validateUrl, normalizeIpv4, sanitizeError, stripDangerousKeys, safeJsonParse, };
80
+ export declare function createDominusNodeFunctionHandler(config: DominusNodeFunctionConfig): FunctionHandler;