dashscope-search 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.
Files changed (3) hide show
  1. package/README.md +44 -0
  2. package/index.js +102 -0
  3. package/package.json +10 -0
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # dashscope-search
2
+
3
+ DashScope web search plugin for OpenClaw. Uses Qwen OAuth token for free web search.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g dashscope-search
9
+ ```
10
+
11
+ ## Configure OpenClaw
12
+
13
+ Add to `~/.openclaw/openclaw.json`:
14
+
15
+ ```json
16
+ {
17
+ "tools": {
18
+ "web": {
19
+ "search": {
20
+ "provider": "dashscope-search"
21
+ }
22
+ }
23
+ },
24
+ "plugins": {
25
+ "entries": {
26
+ "dashscope-search": {
27
+ "enabled": true,
28
+ "config": {}
29
+ }
30
+ }
31
+ }
32
+ }
33
+ ```
34
+
35
+ ## How It Works
36
+
37
+ 1. Queries your local qwen-proxy (port 4099) first
38
+ 2. Falls back to direct DashScope API using `~/.qwen/oauth_creds.json`
39
+ 3. Returns Tavily-compatible format for OpenClaw compatibility
40
+ 4. No API keys needed — uses your Qwen OAuth token
41
+
42
+ ## License
43
+
44
+ MIT
package/index.js ADDED
@@ -0,0 +1,102 @@
1
+ import { createRequire } from 'node:module';
2
+ import * as os from 'node:os';
3
+ import * as path from 'node:path';
4
+ import * as fs from 'node:fs/promises';
5
+
6
+ const require = createRequire(import.meta.url);
7
+
8
+ export function registerWebSearchProvider(context) {
9
+ return {
10
+ name: 'dashscope-search',
11
+
12
+ async search(query, options = {}) {
13
+ const maxResults = options.maxResults || 10;
14
+
15
+ // Try our proxy first (uses Qwen OAuth token)
16
+ const proxyResult = await searchViaProxy(query, maxResults);
17
+ if (proxyResult) return proxyResult;
18
+
19
+ // Fallback: call DashScope directly using OAuth creds
20
+ return await searchDirectDashScope(query, maxResults);
21
+ },
22
+
23
+ // What OpenClaw expects
24
+ getDisplayName() {
25
+ return 'DashScope';
26
+ },
27
+
28
+ isAvailable() {
29
+ return true;
30
+ }
31
+ };
32
+ }
33
+
34
+ async function searchViaProxy(query, maxResults) {
35
+ try {
36
+ const res = await fetch('http://127.0.0.1:4099/v1/search', {
37
+ method: 'POST',
38
+ headers: { 'Content-Type': 'application/json' },
39
+ body: JSON.stringify({ query, max_results: maxResults }),
40
+ signal: AbortSignal.timeout(10000)
41
+ });
42
+
43
+ if (!res.ok) return null;
44
+
45
+ const data = await res.json();
46
+ if (!data.results || data.results.length === 0) return null;
47
+
48
+ return {
49
+ query,
50
+ results: data.results.map(r => ({
51
+ title: r.title || '',
52
+ url: r.url || '',
53
+ content: r.content || '',
54
+ score: r.score || 0,
55
+ publishedDate: r.published_date || ''
56
+ }))
57
+ };
58
+ } catch {
59
+ return null;
60
+ }
61
+ }
62
+
63
+ async function searchDirectDashScope(query, maxResults) {
64
+ try {
65
+ const credsPath = path.join(os.homedir(), '.qwen', 'oauth_creds.json');
66
+ const creds = JSON.parse(await fs.readFile(credsPath, 'utf-8'));
67
+
68
+ if (!creds.access_token) return null;
69
+
70
+ const resourceUrl = creds.resource_url || 'portal.qwen.ai';
71
+ const baseUrl = resourceUrl.startsWith('http') ? resourceUrl : `https://${resourceUrl}`;
72
+ const apiEndpoint = `${baseUrl.replace(/\/$/, '')}/api/v1/indices/plugin/web_search`;
73
+
74
+ const res = await fetch(apiEndpoint, {
75
+ method: 'POST',
76
+ headers: {
77
+ 'Content-Type': 'application/json',
78
+ 'Authorization': `Bearer ${creds.access_token}`
79
+ },
80
+ body: JSON.stringify({ uq: query, page: 1, rows: maxResults }),
81
+ signal: AbortSignal.timeout(10000)
82
+ });
83
+
84
+ if (!res.ok) return null;
85
+
86
+ const data = await res.json();
87
+ if (data.status !== 0 || !data.data?.docs) return null;
88
+
89
+ return {
90
+ query,
91
+ results: data.data.docs.map(doc => ({
92
+ title: doc.title || '',
93
+ url: doc.url || '',
94
+ content: doc.snippet || '',
95
+ score: doc._score || 0,
96
+ publishedDate: doc.timestamp_format || ''
97
+ }))
98
+ };
99
+ } catch {
100
+ return null;
101
+ }
102
+ }
package/package.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "dashscope-search",
3
+ "version": "1.0.0",
4
+ "description": "DashScope web search plugin for OpenClaw using Qwen OAuth",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "keywords": ["openclaw", "dashscope", "web-search", "qwen"],
8
+ "author": "wraient",
9
+ "license": "MIT"
10
+ }