@hasna/connectors 0.4.2 → 0.5.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/bin/index.js +113 -1
- package/bin/mcp.js +113 -1
- package/bin/serve.js +112 -0
- package/connectors/connect-assemblyai/.env.example +11 -0
- package/connectors/connect-assemblyai/CLAUDE.md +128 -0
- package/connectors/connect-assemblyai/README.md +193 -0
- package/connectors/connect-assemblyai/package.json +50 -0
- package/connectors/connect-assemblyai/src/api/client.ts +192 -0
- package/connectors/connect-assemblyai/src/api/index.ts +71 -0
- package/connectors/connect-assemblyai/src/cli/index.ts +384 -0
- package/connectors/connect-assemblyai/src/index.ts +19 -0
- package/connectors/connect-assemblyai/src/types/index.ts +277 -0
- package/connectors/connect-assemblyai/src/utils/config.ts +103 -0
- package/connectors/connect-assemblyai/src/utils/output.ts +119 -0
- package/connectors/connect-assemblyai/tsconfig.json +16 -0
- package/connectors/connect-baseten/.env.example +11 -0
- package/connectors/connect-baseten/CLAUDE.md +128 -0
- package/connectors/connect-baseten/README.md +193 -0
- package/connectors/connect-baseten/package.json +51 -0
- package/connectors/connect-baseten/src/api/client.ts +71 -0
- package/connectors/connect-baseten/src/api/index.ts +40 -0
- package/connectors/connect-baseten/src/cli/index.ts +244 -0
- package/connectors/connect-baseten/src/index.ts +19 -0
- package/connectors/connect-baseten/src/types/index.ts +55 -0
- package/connectors/connect-baseten/src/utils/config.ts +103 -0
- package/connectors/connect-baseten/src/utils/output.ts +119 -0
- package/connectors/connect-baseten/tsconfig.json +16 -0
- package/connectors/connect-cerebras/.env.example +11 -0
- package/connectors/connect-cerebras/CLAUDE.md +128 -0
- package/connectors/connect-cerebras/README.md +193 -0
- package/connectors/connect-cerebras/package.json +51 -0
- package/connectors/connect-cerebras/src/api/client.ts +64 -0
- package/connectors/connect-cerebras/src/api/index.ts +32 -0
- package/connectors/connect-cerebras/src/cli/index.ts +244 -0
- package/connectors/connect-cerebras/src/index.ts +19 -0
- package/connectors/connect-cerebras/src/types/index.ts +65 -0
- package/connectors/connect-cerebras/src/utils/config.ts +103 -0
- package/connectors/connect-cerebras/src/utils/output.ts +119 -0
- package/connectors/connect-cerebras/tsconfig.json +16 -0
- package/connectors/connect-cohere/.env.example +11 -0
- package/connectors/connect-cohere/CLAUDE.md +128 -0
- package/connectors/connect-cohere/README.md +193 -0
- package/connectors/connect-cohere/package.json +53 -0
- package/connectors/connect-cohere/src/api/client.ts +109 -0
- package/connectors/connect-cohere/src/api/index.ts +59 -0
- package/connectors/connect-cohere/src/cli/index.ts +255 -0
- package/connectors/connect-cohere/src/index.ts +19 -0
- package/connectors/connect-cohere/src/types/index.ts +132 -0
- package/connectors/connect-cohere/src/utils/config.ts +197 -0
- package/connectors/connect-cohere/src/utils/output.ts +119 -0
- package/connectors/connect-cohere/tsconfig.json +16 -0
- package/connectors/connect-deepgram/.env.example +11 -0
- package/connectors/connect-deepgram/CLAUDE.md +128 -0
- package/connectors/connect-deepgram/README.md +193 -0
- package/connectors/connect-deepgram/package.json +51 -0
- package/connectors/connect-deepgram/src/api/client.ts +235 -0
- package/connectors/connect-deepgram/src/api/index.ts +57 -0
- package/connectors/connect-deepgram/src/cli/index.ts +339 -0
- package/connectors/connect-deepgram/src/index.ts +19 -0
- package/connectors/connect-deepgram/src/types/index.ts +232 -0
- package/connectors/connect-deepgram/src/utils/config.ts +103 -0
- package/connectors/connect-deepgram/src/utils/output.ts +119 -0
- package/connectors/connect-deepgram/tsconfig.json +16 -0
- package/connectors/connect-deepseek/.env.example +11 -0
- package/connectors/connect-deepseek/CLAUDE.md +128 -0
- package/connectors/connect-deepseek/README.md +193 -0
- package/connectors/connect-deepseek/package.json +51 -0
- package/connectors/connect-deepseek/src/api/client.ts +108 -0
- package/connectors/connect-deepseek/src/api/index.ts +36 -0
- package/connectors/connect-deepseek/src/cli/index.ts +167 -0
- package/connectors/connect-deepseek/src/index.ts +19 -0
- package/connectors/connect-deepseek/src/types/index.ts +72 -0
- package/connectors/connect-deepseek/src/utils/config.ts +103 -0
- package/connectors/connect-deepseek/src/utils/output.ts +119 -0
- package/connectors/connect-deepseek/tsconfig.json +16 -0
- package/connectors/connect-fal/.env.example +11 -0
- package/connectors/connect-fal/CLAUDE.md +128 -0
- package/connectors/connect-fal/README.md +193 -0
- package/connectors/connect-fal/package.json +51 -0
- package/connectors/connect-fal/src/api/client.ts +172 -0
- package/connectors/connect-fal/src/api/index.ts +55 -0
- package/connectors/connect-fal/src/cli/index.ts +341 -0
- package/connectors/connect-fal/src/index.ts +19 -0
- package/connectors/connect-fal/src/types/index.ts +135 -0
- package/connectors/connect-fal/src/utils/config.ts +103 -0
- package/connectors/connect-fal/src/utils/output.ts +119 -0
- package/connectors/connect-fal/tsconfig.json +16 -0
- package/connectors/connect-fireworks/.env.example +11 -0
- package/connectors/connect-fireworks/CLAUDE.md +128 -0
- package/connectors/connect-fireworks/README.md +193 -0
- package/connectors/connect-fireworks/package.json +51 -0
- package/connectors/connect-fireworks/src/api/client.ts +63 -0
- package/connectors/connect-fireworks/src/api/index.ts +36 -0
- package/connectors/connect-fireworks/src/cli/index.ts +244 -0
- package/connectors/connect-fireworks/src/index.ts +19 -0
- package/connectors/connect-fireworks/src/types/index.ts +70 -0
- package/connectors/connect-fireworks/src/utils/config.ts +103 -0
- package/connectors/connect-fireworks/src/utils/output.ts +119 -0
- package/connectors/connect-fireworks/tsconfig.json +16 -0
- package/connectors/connect-groq/.env.example +11 -0
- package/connectors/connect-groq/CLAUDE.md +128 -0
- package/connectors/connect-groq/README.md +193 -0
- package/connectors/connect-groq/package.json +52 -0
- package/connectors/connect-groq/src/api/client.ts +108 -0
- package/connectors/connect-groq/src/api/index.ts +36 -0
- package/connectors/connect-groq/src/cli/index.ts +171 -0
- package/connectors/connect-groq/src/index.ts +19 -0
- package/connectors/connect-groq/src/types/index.ts +69 -0
- package/connectors/connect-groq/src/utils/config.ts +103 -0
- package/connectors/connect-groq/src/utils/output.ts +119 -0
- package/connectors/connect-groq/tsconfig.json +16 -0
- package/connectors/connect-luma/.env.example +11 -0
- package/connectors/connect-luma/CLAUDE.md +128 -0
- package/connectors/connect-luma/README.md +193 -0
- package/connectors/connect-luma/package.json +53 -0
- package/connectors/connect-luma/src/api/client.ts +85 -0
- package/connectors/connect-luma/src/api/index.ts +44 -0
- package/connectors/connect-luma/src/cli/index.ts +300 -0
- package/connectors/connect-luma/src/index.ts +19 -0
- package/connectors/connect-luma/src/types/index.ts +60 -0
- package/connectors/connect-luma/src/utils/config.ts +103 -0
- package/connectors/connect-luma/src/utils/output.ts +119 -0
- package/connectors/connect-luma/tsconfig.json +16 -0
- package/connectors/connect-modal/.env.example +11 -0
- package/connectors/connect-modal/CLAUDE.md +128 -0
- package/connectors/connect-modal/README.md +193 -0
- package/connectors/connect-modal/package.json +51 -0
- package/connectors/connect-modal/src/api/client.ts +119 -0
- package/connectors/connect-modal/src/api/index.ts +69 -0
- package/connectors/connect-modal/src/cli/index.ts +224 -0
- package/connectors/connect-modal/src/index.ts +21 -0
- package/connectors/connect-modal/src/types/index.ts +60 -0
- package/connectors/connect-modal/src/utils/config.ts +114 -0
- package/connectors/connect-modal/src/utils/output.ts +119 -0
- package/connectors/connect-modal/tsconfig.json +16 -0
- package/connectors/connect-perplexity/.env.example +4 -0
- package/connectors/connect-perplexity/CLAUDE.md +156 -0
- package/connectors/connect-perplexity/README.md +184 -0
- package/connectors/connect-perplexity/package.json +58 -0
- package/connectors/connect-perplexity/scripts/publish.ts +210 -0
- package/connectors/connect-perplexity/src/api/client.ts +119 -0
- package/connectors/connect-perplexity/src/api/example.ts +118 -0
- package/connectors/connect-perplexity/src/api/index.ts +48 -0
- package/connectors/connect-perplexity/src/cli/index.ts +421 -0
- package/connectors/connect-perplexity/src/index.ts +24 -0
- package/connectors/connect-perplexity/src/types/index.ts +140 -0
- package/connectors/connect-perplexity/src/utils/config.ts +208 -0
- package/connectors/connect-perplexity/src/utils/output.ts +119 -0
- package/connectors/connect-perplexity/tsconfig.json +16 -0
- package/connectors/connect-replicate/.env.example +11 -0
- package/connectors/connect-replicate/CLAUDE.md +128 -0
- package/connectors/connect-replicate/README.md +193 -0
- package/connectors/connect-replicate/package.json +51 -0
- package/connectors/connect-replicate/src/api/client.ts +109 -0
- package/connectors/connect-replicate/src/api/index.ts +71 -0
- package/connectors/connect-replicate/src/cli/index.ts +250 -0
- package/connectors/connect-replicate/src/index.ts +19 -0
- package/connectors/connect-replicate/src/types/index.ts +85 -0
- package/connectors/connect-replicate/src/utils/config.ts +103 -0
- package/connectors/connect-replicate/src/utils/output.ts +119 -0
- package/connectors/connect-replicate/tsconfig.json +16 -0
- package/connectors/connect-roboflow/.env.example +11 -0
- package/connectors/connect-roboflow/CLAUDE.md +272 -0
- package/connectors/connect-roboflow/README.md +193 -0
- package/connectors/connect-roboflow/package.json +51 -0
- package/connectors/connect-roboflow/scripts/release.ts +179 -0
- package/connectors/connect-roboflow/src/api/client.ts +213 -0
- package/connectors/connect-roboflow/src/api/example.ts +48 -0
- package/connectors/connect-roboflow/src/api/index.ts +51 -0
- package/connectors/connect-roboflow/src/cli/index.ts +254 -0
- package/connectors/connect-roboflow/src/index.ts +103 -0
- package/connectors/connect-roboflow/src/types/index.ts +237 -0
- package/connectors/connect-roboflow/src/utils/auth.ts +274 -0
- package/connectors/connect-roboflow/src/utils/bulk.ts +212 -0
- package/connectors/connect-roboflow/src/utils/config.ts +326 -0
- package/connectors/connect-roboflow/src/utils/output.ts +175 -0
- package/connectors/connect-roboflow/src/utils/settings.ts +114 -0
- package/connectors/connect-roboflow/src/utils/storage.ts +198 -0
- package/connectors/connect-roboflow/tsconfig.json +16 -0
- package/connectors/connect-runway/.env.example +11 -0
- package/connectors/connect-runway/CLAUDE.md +128 -0
- package/connectors/connect-runway/README.md +193 -0
- package/connectors/connect-runway/package.json +52 -0
- package/connectors/connect-runway/src/api/client.ts +78 -0
- package/connectors/connect-runway/src/api/index.ts +40 -0
- package/connectors/connect-runway/src/cli/index.ts +283 -0
- package/connectors/connect-runway/src/index.ts +19 -0
- package/connectors/connect-runway/src/types/index.ts +52 -0
- package/connectors/connect-runway/src/utils/config.ts +103 -0
- package/connectors/connect-runway/src/utils/output.ts +119 -0
- package/connectors/connect-runway/tsconfig.json +16 -0
- package/connectors/connect-together/.env.example +11 -0
- package/connectors/connect-together/CLAUDE.md +128 -0
- package/connectors/connect-together/README.md +193 -0
- package/connectors/connect-together/package.json +52 -0
- package/connectors/connect-together/src/api/client.ts +106 -0
- package/connectors/connect-together/src/api/index.ts +47 -0
- package/connectors/connect-together/src/cli/index.ts +228 -0
- package/connectors/connect-together/src/index.ts +19 -0
- package/connectors/connect-together/src/types/index.ts +91 -0
- package/connectors/connect-together/src/utils/config.ts +142 -0
- package/connectors/connect-together/src/utils/output.ts +119 -0
- package/connectors/connect-together/tsconfig.json +16 -0
- package/dist/index.js +112 -0
- package/package.json +1 -1
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Auto-versioning publish script
|
|
4
|
+
* - Fetches current npm version
|
|
5
|
+
* - Auto-bumps patch version if local version <= npm version
|
|
6
|
+
* - Creates git tag
|
|
7
|
+
* - Publishes to npm
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { $ } from 'bun';
|
|
11
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
12
|
+
import { join } from 'path';
|
|
13
|
+
|
|
14
|
+
interface PackageJson {
|
|
15
|
+
name: string;
|
|
16
|
+
version: string;
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type BumpType = 'patch' | 'minor' | 'major';
|
|
21
|
+
|
|
22
|
+
function parseVersion(version: string): { major: number; minor: number; patch: number } {
|
|
23
|
+
const [major, minor, patch] = version.split('.').map(Number);
|
|
24
|
+
return { major, minor, patch };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function bumpVersion(version: string, type: BumpType = 'patch'): string {
|
|
28
|
+
const { major, minor, patch } = parseVersion(version);
|
|
29
|
+
|
|
30
|
+
switch (type) {
|
|
31
|
+
case 'major':
|
|
32
|
+
return `${major + 1}.0.0`;
|
|
33
|
+
case 'minor':
|
|
34
|
+
return `${major}.${minor + 1}.0`;
|
|
35
|
+
case 'patch':
|
|
36
|
+
default:
|
|
37
|
+
return `${major}.${minor}.${patch + 1}`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function compareVersions(a: string, b: string): number {
|
|
42
|
+
const vA = parseVersion(a);
|
|
43
|
+
const vB = parseVersion(b);
|
|
44
|
+
|
|
45
|
+
if (vA.major !== vB.major) return vA.major - vB.major;
|
|
46
|
+
if (vA.minor !== vB.minor) return vA.minor - vB.minor;
|
|
47
|
+
return vA.patch - vB.patch;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function getNpmVersion(packageName: string): Promise<string | null> {
|
|
51
|
+
try {
|
|
52
|
+
const result = await $`npm view ${packageName} version 2>/dev/null`.text();
|
|
53
|
+
return result.trim() || null;
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function hasUncommittedChanges(): Promise<boolean> {
|
|
60
|
+
try {
|
|
61
|
+
const result = await $`git status --porcelain`.text();
|
|
62
|
+
return result.trim().length > 0;
|
|
63
|
+
} catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function isGitRepo(): Promise<boolean> {
|
|
69
|
+
try {
|
|
70
|
+
await $`git rev-parse --git-dir 2>/dev/null`.text();
|
|
71
|
+
return true;
|
|
72
|
+
} catch {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function createGitTag(version: string, packageName: string): Promise<boolean> {
|
|
78
|
+
const tagName = `${packageName}@${version}`;
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
// Check if tag already exists
|
|
82
|
+
const existingTags = await $`git tag -l ${tagName}`.text();
|
|
83
|
+
if (existingTags.trim()) {
|
|
84
|
+
console.log(`⚠️ Tag ${tagName} already exists, skipping tag creation`);
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
await $`git tag -a ${tagName} -m "Release ${tagName}"`;
|
|
89
|
+
console.log(`✅ Created git tag: ${tagName}`);
|
|
90
|
+
return true;
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.error(`❌ Failed to create git tag: ${error}`);
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function commitVersionBump(version: string, packageName: string): Promise<boolean> {
|
|
98
|
+
try {
|
|
99
|
+
await $`git add package.json`;
|
|
100
|
+
await $`git commit -m "chore(${packageName}): bump version to ${version}"`;
|
|
101
|
+
console.log(`✅ Committed version bump`);
|
|
102
|
+
return true;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error(`❌ Failed to commit: ${error}`);
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function main() {
|
|
110
|
+
const args = process.argv.slice(2);
|
|
111
|
+
const bumpType = (args.find(a => ['patch', 'minor', 'major'].includes(a)) || 'patch') as BumpType;
|
|
112
|
+
const skipGit = args.includes('--skip-git');
|
|
113
|
+
const dryRun = args.includes('--dry-run');
|
|
114
|
+
const force = args.includes('--force');
|
|
115
|
+
|
|
116
|
+
// Read package.json
|
|
117
|
+
const pkgPath = join(process.cwd(), 'package.json');
|
|
118
|
+
const pkg: PackageJson = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
119
|
+
|
|
120
|
+
console.log(`\n📦 Publishing ${pkg.name}\n`);
|
|
121
|
+
|
|
122
|
+
// Get current npm version
|
|
123
|
+
const npmVersion = await getNpmVersion(pkg.name);
|
|
124
|
+
let newVersion = pkg.version;
|
|
125
|
+
|
|
126
|
+
if (npmVersion) {
|
|
127
|
+
console.log(`📌 Current npm version: ${npmVersion}`);
|
|
128
|
+
console.log(`📌 Local version: ${pkg.version}`);
|
|
129
|
+
|
|
130
|
+
// Check if we need to bump
|
|
131
|
+
if (compareVersions(pkg.version, npmVersion) <= 0) {
|
|
132
|
+
newVersion = bumpVersion(npmVersion, bumpType);
|
|
133
|
+
console.log(`🔄 Auto-bumping to: ${newVersion}`);
|
|
134
|
+
} else {
|
|
135
|
+
console.log(`✅ Local version is ahead, using: ${pkg.version}`);
|
|
136
|
+
}
|
|
137
|
+
} else {
|
|
138
|
+
console.log(`📌 Package not yet published to npm`);
|
|
139
|
+
console.log(`📌 Using local version: ${pkg.version}`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Update package.json if version changed
|
|
143
|
+
if (newVersion !== pkg.version) {
|
|
144
|
+
if (dryRun) {
|
|
145
|
+
console.log(`\n🧪 DRY RUN: Would update version to ${newVersion}`);
|
|
146
|
+
} else {
|
|
147
|
+
pkg.version = newVersion;
|
|
148
|
+
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
149
|
+
console.log(`✅ Updated package.json to version ${newVersion}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Git operations
|
|
154
|
+
const isGit = await isGitRepo();
|
|
155
|
+
|
|
156
|
+
if (isGit && !skipGit) {
|
|
157
|
+
const hasChanges = await hasUncommittedChanges();
|
|
158
|
+
|
|
159
|
+
if (hasChanges && newVersion !== pkg.version) {
|
|
160
|
+
if (dryRun) {
|
|
161
|
+
console.log(`🧪 DRY RUN: Would commit version bump`);
|
|
162
|
+
} else {
|
|
163
|
+
await commitVersionBump(newVersion, pkg.name.replace('@hasna/', ''));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (dryRun) {
|
|
168
|
+
console.log(`🧪 DRY RUN: Would create tag ${pkg.name}@${newVersion}`);
|
|
169
|
+
} else {
|
|
170
|
+
await createGitTag(newVersion, pkg.name.replace('@hasna/', ''));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Build
|
|
175
|
+
console.log(`\n🔨 Building...`);
|
|
176
|
+
if (!dryRun) {
|
|
177
|
+
await $`bun run build`;
|
|
178
|
+
} else {
|
|
179
|
+
console.log(`🧪 DRY RUN: Would run build`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Publish
|
|
183
|
+
console.log(`\n🚀 Publishing to npm...`);
|
|
184
|
+
if (dryRun) {
|
|
185
|
+
console.log(`🧪 DRY RUN: Would publish ${pkg.name}@${newVersion}`);
|
|
186
|
+
} else {
|
|
187
|
+
try {
|
|
188
|
+
await $`npm publish`;
|
|
189
|
+
console.log(`\n✅ Successfully published ${pkg.name}@${newVersion}`);
|
|
190
|
+
} catch (error) {
|
|
191
|
+
console.error(`\n❌ Publish failed: ${error}`);
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Push tags
|
|
197
|
+
if (isGit && !skipGit && !dryRun) {
|
|
198
|
+
console.log(`\n📤 Pushing tags to remote...`);
|
|
199
|
+
try {
|
|
200
|
+
await $`git push --tags`;
|
|
201
|
+
console.log(`✅ Pushed tags to remote`);
|
|
202
|
+
} catch {
|
|
203
|
+
console.log(`⚠️ Could not push tags (no remote or not configured)`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
console.log(`\n✨ Done!\n`);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { PerplexityConfig, OutputFormat } from '../types';
|
|
2
|
+
import { PerplexityApiError } from '../types';
|
|
3
|
+
|
|
4
|
+
const DEFAULT_BASE_URL = 'https://api.perplexity.ai';
|
|
5
|
+
|
|
6
|
+
export interface RequestOptions {
|
|
7
|
+
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
8
|
+
params?: Record<string, string | number | boolean | undefined>;
|
|
9
|
+
body?: Record<string, unknown> | unknown[] | string;
|
|
10
|
+
headers?: Record<string, string>;
|
|
11
|
+
format?: OutputFormat;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class PerplexityClient {
|
|
15
|
+
private readonly apiKey: string;
|
|
16
|
+
private readonly baseUrl: string;
|
|
17
|
+
|
|
18
|
+
constructor(config: PerplexityConfig) {
|
|
19
|
+
if (!config.apiKey) {
|
|
20
|
+
throw new Error('API key is required');
|
|
21
|
+
}
|
|
22
|
+
this.apiKey = config.apiKey;
|
|
23
|
+
this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {
|
|
27
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
28
|
+
|
|
29
|
+
if (params) {
|
|
30
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
31
|
+
if (value !== undefined && value !== null && value !== '') {
|
|
32
|
+
url.searchParams.append(key, String(value));
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return url.toString();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Make an authenticated request to the Perplexity API
|
|
42
|
+
*/
|
|
43
|
+
async request<T>(path: string, options: RequestOptions = {}): Promise<T> {
|
|
44
|
+
const { method = 'GET', params, body, headers = {} } = options;
|
|
45
|
+
|
|
46
|
+
const url = this.buildUrl(path, params);
|
|
47
|
+
|
|
48
|
+
const requestHeaders: Record<string, string> = {
|
|
49
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
50
|
+
'Accept': 'application/json',
|
|
51
|
+
...headers,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
if (body && ['POST', 'PUT', 'PATCH'].includes(method)) {
|
|
55
|
+
requestHeaders['Content-Type'] = 'application/json';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const fetchOptions: RequestInit = {
|
|
59
|
+
method,
|
|
60
|
+
headers: requestHeaders,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
if (body && ['POST', 'PUT', 'PATCH'].includes(method)) {
|
|
64
|
+
fetchOptions.body = typeof body === 'string' ? body : JSON.stringify(body);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const response = await fetch(url, fetchOptions);
|
|
68
|
+
|
|
69
|
+
// Handle 204 No Content
|
|
70
|
+
if (response.status === 204) {
|
|
71
|
+
return {} as T;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Parse response
|
|
75
|
+
let data: unknown;
|
|
76
|
+
const contentType = response.headers.get('content-type') || '';
|
|
77
|
+
|
|
78
|
+
if (contentType.includes('application/json')) {
|
|
79
|
+
const text = await response.text();
|
|
80
|
+
if (text) {
|
|
81
|
+
try {
|
|
82
|
+
data = JSON.parse(text);
|
|
83
|
+
} catch {
|
|
84
|
+
data = text;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
data = await response.text();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Handle errors
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
const errorMessage = typeof data === 'object' && data !== null
|
|
94
|
+
? JSON.stringify(data)
|
|
95
|
+
: String(data || response.statusText);
|
|
96
|
+
throw new PerplexityApiError(errorMessage, response.status);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return data as T;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async get<T>(path: string, params?: Record<string, string | number | boolean | undefined>): Promise<T> {
|
|
103
|
+
return this.request<T>(path, { method: 'GET', params });
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async post<T>(path: string, body?: Record<string, unknown> | unknown[] | string | object, params?: Record<string, string | number | boolean | undefined>): Promise<T> {
|
|
107
|
+
return this.request<T>(path, { method: 'POST', body: body as Record<string, unknown>, params });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get a preview of the API key (for display/debugging)
|
|
112
|
+
*/
|
|
113
|
+
getApiKeyPreview(): string {
|
|
114
|
+
if (this.apiKey.length > 10) {
|
|
115
|
+
return `${this.apiKey.substring(0, 6)}...${this.apiKey.substring(this.apiKey.length - 4)}`;
|
|
116
|
+
}
|
|
117
|
+
return '***';
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { PerplexityClient } from './client';
|
|
2
|
+
import type {
|
|
3
|
+
ChatCompletionRequest,
|
|
4
|
+
ChatCompletionResponse,
|
|
5
|
+
ChatMessage,
|
|
6
|
+
PerplexityModel,
|
|
7
|
+
} from '../types';
|
|
8
|
+
|
|
9
|
+
export interface ChatOptions {
|
|
10
|
+
model?: PerplexityModel;
|
|
11
|
+
maxTokens?: number;
|
|
12
|
+
temperature?: number;
|
|
13
|
+
topP?: number;
|
|
14
|
+
topK?: number;
|
|
15
|
+
presencePenalty?: number;
|
|
16
|
+
frequencyPenalty?: number;
|
|
17
|
+
searchDomainFilter?: string[];
|
|
18
|
+
returnImages?: boolean;
|
|
19
|
+
returnRelatedQuestions?: boolean;
|
|
20
|
+
searchRecencyFilter?: 'month' | 'week' | 'day' | 'hour';
|
|
21
|
+
systemPrompt?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Chat Completions API
|
|
26
|
+
*/
|
|
27
|
+
export class ChatApi {
|
|
28
|
+
constructor(private readonly client: PerplexityClient) {}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create a chat completion
|
|
32
|
+
*/
|
|
33
|
+
async create(
|
|
34
|
+
messages: ChatMessage[],
|
|
35
|
+
options: ChatOptions = {}
|
|
36
|
+
): Promise<ChatCompletionResponse> {
|
|
37
|
+
const request: ChatCompletionRequest = {
|
|
38
|
+
model: options.model || 'sonar',
|
|
39
|
+
messages,
|
|
40
|
+
stream: false,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
if (options.maxTokens !== undefined) request.max_tokens = options.maxTokens;
|
|
44
|
+
if (options.temperature !== undefined) request.temperature = options.temperature;
|
|
45
|
+
if (options.topP !== undefined) request.top_p = options.topP;
|
|
46
|
+
if (options.topK !== undefined) request.top_k = options.topK;
|
|
47
|
+
if (options.presencePenalty !== undefined) request.presence_penalty = options.presencePenalty;
|
|
48
|
+
if (options.frequencyPenalty !== undefined) request.frequency_penalty = options.frequencyPenalty;
|
|
49
|
+
if (options.searchDomainFilter !== undefined) request.search_domain_filter = options.searchDomainFilter;
|
|
50
|
+
if (options.returnImages !== undefined) request.return_images = options.returnImages;
|
|
51
|
+
if (options.returnRelatedQuestions !== undefined) request.return_related_questions = options.returnRelatedQuestions;
|
|
52
|
+
if (options.searchRecencyFilter !== undefined) request.search_recency_filter = options.searchRecencyFilter;
|
|
53
|
+
|
|
54
|
+
return this.client.post<ChatCompletionResponse>('/chat/completions', request);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Simple ask method - send a single question and get an answer
|
|
59
|
+
*/
|
|
60
|
+
async ask(
|
|
61
|
+
question: string,
|
|
62
|
+
options: ChatOptions = {}
|
|
63
|
+
): Promise<ChatCompletionResponse> {
|
|
64
|
+
const messages: ChatMessage[] = [];
|
|
65
|
+
|
|
66
|
+
if (options.systemPrompt) {
|
|
67
|
+
messages.push({ role: 'system', content: options.systemPrompt });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
messages.push({ role: 'user', content: question });
|
|
71
|
+
|
|
72
|
+
return this.create(messages, options);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Search the web and get an answer grounded in search results
|
|
77
|
+
*/
|
|
78
|
+
async search(
|
|
79
|
+
query: string,
|
|
80
|
+
options: Omit<ChatOptions, 'systemPrompt'> & { recency?: 'month' | 'week' | 'day' | 'hour' } = {}
|
|
81
|
+
): Promise<ChatCompletionResponse> {
|
|
82
|
+
const { recency, ...restOptions } = options;
|
|
83
|
+
|
|
84
|
+
return this.ask(query, {
|
|
85
|
+
...restOptions,
|
|
86
|
+
searchRecencyFilter: recency,
|
|
87
|
+
systemPrompt: 'You are a helpful search assistant. Provide accurate, well-researched answers based on the most recent and relevant information available.',
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Deep research on a topic
|
|
93
|
+
*/
|
|
94
|
+
async research(
|
|
95
|
+
topic: string,
|
|
96
|
+
options: Omit<ChatOptions, 'model' | 'systemPrompt'> = {}
|
|
97
|
+
): Promise<ChatCompletionResponse> {
|
|
98
|
+
return this.ask(topic, {
|
|
99
|
+
...options,
|
|
100
|
+
model: 'sonar-deep-research',
|
|
101
|
+
systemPrompt: 'You are a research assistant. Provide comprehensive, well-cited analysis on the given topic.',
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Reasoning task
|
|
107
|
+
*/
|
|
108
|
+
async reason(
|
|
109
|
+
prompt: string,
|
|
110
|
+
options: Omit<ChatOptions, 'model' | 'systemPrompt'> = {}
|
|
111
|
+
): Promise<ChatCompletionResponse> {
|
|
112
|
+
return this.ask(prompt, {
|
|
113
|
+
...options,
|
|
114
|
+
model: 'sonar-reasoning-pro',
|
|
115
|
+
systemPrompt: 'You are a logical reasoning assistant. Think through problems step by step and provide well-reasoned answers.',
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { PerplexityConfig } from '../types';
|
|
2
|
+
import { PerplexityClient } from './client';
|
|
3
|
+
import { ChatApi } from './example';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Perplexity AI API Client
|
|
7
|
+
*/
|
|
8
|
+
export class Perplexity {
|
|
9
|
+
private readonly client: PerplexityClient;
|
|
10
|
+
|
|
11
|
+
// API modules
|
|
12
|
+
public readonly chat: ChatApi;
|
|
13
|
+
|
|
14
|
+
constructor(config: PerplexityConfig) {
|
|
15
|
+
this.client = new PerplexityClient(config);
|
|
16
|
+
this.chat = new ChatApi(this.client);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Create a client from environment variables
|
|
21
|
+
* Looks for PERPLEXITY_API_KEY
|
|
22
|
+
*/
|
|
23
|
+
static fromEnv(): Perplexity {
|
|
24
|
+
const apiKey = process.env.PERPLEXITY_API_KEY;
|
|
25
|
+
|
|
26
|
+
if (!apiKey) {
|
|
27
|
+
throw new Error('PERPLEXITY_API_KEY environment variable is required');
|
|
28
|
+
}
|
|
29
|
+
return new Perplexity({ apiKey });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get a preview of the API key (for debugging)
|
|
34
|
+
*/
|
|
35
|
+
getApiKeyPreview(): string {
|
|
36
|
+
return this.client.getApiKeyPreview();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get the underlying client for direct API access
|
|
41
|
+
*/
|
|
42
|
+
getClient(): PerplexityClient {
|
|
43
|
+
return this.client;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { PerplexityClient } from './client';
|
|
48
|
+
export { ChatApi } from './example';
|