@honor-claw/yoyo 0.0.1-beta.5 → 0.0.1-beta.7
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/index.ts +3 -7
- package/openclaw.plugin.json +4 -0
- package/package.json +1 -2
- package/skills/search/SKILL.md +182 -0
- package/skills/search/scripts/search.sh +69 -0
- package/src/apis/honor-auth.ts +3 -1
- package/src/cloud-channel/channel.ts +196 -59
- package/src/cloud-channel/client.ts +27 -8
- package/src/cloud-channel/types.ts +21 -0
- package/src/commands/env/impl.ts +38 -0
- package/src/commands/env/index.ts +1 -0
- package/src/commands/index.ts +10 -2
- package/src/commands/login/impl.ts +6 -4
- package/src/commands/logout/impl.ts +26 -0
- package/src/commands/logout/index.ts +1 -53
- package/src/gateway-client/client.ts +16 -19
- package/src/gateway-client/types.ts +2 -2
- package/src/honor-auth/config.ts +25 -17
- package/src/modules/claw-configs/config-manager.ts +86 -6
- package/src/modules/claw-configs/hosts.ts +30 -0
- package/src/modules/claw-configs/index.ts +1 -0
- package/src/modules/claw-configs/types.ts +2 -0
- package/src/modules/device/device-info.ts +20 -9
- package/src/modules/device/providers/linux.ts +128 -0
- package/src/modules/device/providers/macos.ts +116 -0
- package/src/modules/device/providers/pad.ts +0 -16
- package/src/modules/device/registry.ts +3 -2
- package/src/modules/login/impl.ts +22 -2
- package/src/runtime.ts +20 -0
- package/src/schemas.ts +3 -2
- package/src/services/connection/impl.ts +7 -3
- package/src/utils/version.ts +21 -0
package/index.ts
CHANGED
|
@@ -2,24 +2,20 @@ import { type OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
|
2
2
|
import { setYoyoRuntime } from "./src/runtime.js";
|
|
3
3
|
import { registerCommands } from "./src/commands/index.js";
|
|
4
4
|
import { YoyoPluginConfigSchema } from "./src/schemas.js";
|
|
5
|
-
import {
|
|
5
|
+
import { createClawConnectionService } from "./src/services/connection/index.js";
|
|
6
6
|
import { setClawLogger } from "./src/utils/logger.js";
|
|
7
|
-
import { copyTemplateToWorkspace } from "./src/agent/index.js";
|
|
8
7
|
|
|
9
8
|
const plugin = {
|
|
10
9
|
id: "yoyo",
|
|
11
10
|
name: "YOYOClaw",
|
|
12
11
|
description: "OpenClaw Honor Yoyo connection plugin",
|
|
13
12
|
configSchema: YoyoPluginConfigSchema,
|
|
14
|
-
|
|
13
|
+
register(api: OpenClawPluginApi) {
|
|
15
14
|
setYoyoRuntime(api.runtime);
|
|
16
15
|
setClawLogger(api.logger);
|
|
17
16
|
|
|
18
|
-
// 复制智能体模板到工作目录
|
|
19
|
-
await copyTemplateToWorkspace(api)
|
|
20
|
-
|
|
21
17
|
// 利用服务来管理核心连接任务进行~
|
|
22
|
-
api.registerService(
|
|
18
|
+
api.registerService(createClawConnectionService(api));
|
|
23
19
|
|
|
24
20
|
// 注册所有的命令行
|
|
25
21
|
registerCommands(api);
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@honor-claw/yoyo",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenClaw Honor Yoyo connection plugin",
|
|
6
6
|
"scripts": {
|
|
@@ -30,7 +30,6 @@
|
|
|
30
30
|
]
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@sinclair/typebox": "0.34.48",
|
|
34
33
|
"http-proxy-agent": "^8.0.0",
|
|
35
34
|
"https-proxy-agent": "^8.0.0",
|
|
36
35
|
"jsonwebtoken": "^9.0.3",
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: search
|
|
3
|
+
description: "Search the web using Tavily's LLM-optimized search API. Returns relevant results with content snippets, scores, and metadata. Use when you need to find web content on any topic without writing code."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Search Skill
|
|
7
|
+
|
|
8
|
+
Search the web and get relevant results optimized for LLM consumption.
|
|
9
|
+
|
|
10
|
+
## Authentication
|
|
11
|
+
|
|
12
|
+
The script uses OAuth via the Tavily MCP server. **No manual setup required** - on first run, it will:
|
|
13
|
+
1. Check for existing tokens in `~/.mcp-auth/`
|
|
14
|
+
2. If none found, automatically open your browser for OAuth authentication
|
|
15
|
+
|
|
16
|
+
> **Note:** You must have an existing Tavily account. The OAuth flow only supports login — account creation is not available through this flow. [Sign up at tavily.com](https://tavily.com) first if you don't have an account.
|
|
17
|
+
|
|
18
|
+
### Alternative: API Key
|
|
19
|
+
|
|
20
|
+
If you prefer using an API key, get one at https://tavily.com and add to `~/.claude/settings.json`:
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"env": {
|
|
24
|
+
"TAVILY_API_KEY": "tvly-your-api-key-here"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
### Using the Script
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
./scripts/search.sh '<json>'
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Examples:**
|
|
38
|
+
```bash
|
|
39
|
+
# Basic search
|
|
40
|
+
./scripts/search.sh '{"query": "python async patterns"}'
|
|
41
|
+
|
|
42
|
+
# With options
|
|
43
|
+
./scripts/search.sh '{"query": "React hooks tutorial", "max_results": 10}'
|
|
44
|
+
|
|
45
|
+
# Advanced search with filters
|
|
46
|
+
./scripts/search.sh '{"query": "AI news", "time_range": "week", "max_results": 10}'
|
|
47
|
+
|
|
48
|
+
# Domain-filtered search
|
|
49
|
+
./scripts/search.sh '{"query": "machine learning", "include_domains": ["arxiv.org", "github.com"], "search_depth": "advanced"}'
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Basic Search
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
curl --request POST \
|
|
56
|
+
--url https://api.tavily.com/search \
|
|
57
|
+
--header "Authorization: Bearer $TAVILY_API_KEY" \
|
|
58
|
+
--header 'Content-Type: application/json' \
|
|
59
|
+
--data '{
|
|
60
|
+
"query": "latest developments in quantum computing",
|
|
61
|
+
"max_results": 5
|
|
62
|
+
}'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Advanced Search
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
curl --request POST \
|
|
69
|
+
--url https://api.tavily.com/search \
|
|
70
|
+
--header "Authorization: Bearer $TAVILY_API_KEY" \
|
|
71
|
+
--header 'Content-Type: application/json' \
|
|
72
|
+
--data '{
|
|
73
|
+
"query": "machine learning best practices",
|
|
74
|
+
"max_results": 10,
|
|
75
|
+
"search_depth": "advanced",
|
|
76
|
+
"include_domains": ["arxiv.org", "github.com"]
|
|
77
|
+
}'
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## API Reference
|
|
81
|
+
|
|
82
|
+
### Endpoint
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
POST https://api.tavily.com/search
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Headers
|
|
89
|
+
|
|
90
|
+
| Header | Value |
|
|
91
|
+
|--------|-------|
|
|
92
|
+
| `Authorization` | `Bearer <TAVILY_API_KEY>` |
|
|
93
|
+
| `Content-Type` | `application/json` |
|
|
94
|
+
|
|
95
|
+
### Request Body
|
|
96
|
+
|
|
97
|
+
| Field | Type | Default | Description |
|
|
98
|
+
|-------|------|---------|-------------|
|
|
99
|
+
| `query` | string | Required | Search query (keep under 400 chars) |
|
|
100
|
+
| `max_results` | integer | 10 | Maximum results (0-20) |
|
|
101
|
+
| `search_depth` | string | `"basic"` | `ultra-fast`, `fast`, `basic`, `advanced` |
|
|
102
|
+
| `topic` | string | `"general"` | Search topic (general only) |
|
|
103
|
+
| `time_range` | string | null | `day`, `week`, `month`, `year` |
|
|
104
|
+
| `start_date` | string | null | Return results after this date (`YYYY-MM-DD`) |
|
|
105
|
+
| `end_date` | string | null | Return results before this date (`YYYY-MM-DD`) |
|
|
106
|
+
| `include_domains` | array | [] | Domains to include (max 300) |
|
|
107
|
+
| `exclude_domains` | array | [] | Domains to exclude (max 150) |
|
|
108
|
+
| `country` | string | null | Boost results from a specific country (general topic only) |
|
|
109
|
+
| `include_raw_content` | boolean | false | Include full page content |
|
|
110
|
+
| `include_images` | boolean | false | Include image results |
|
|
111
|
+
| `include_image_descriptions` | boolean | false | Include descriptions for images |
|
|
112
|
+
| `include_favicon` | boolean | false | Include favicon URL for each result |
|
|
113
|
+
|
|
114
|
+
### Response Format
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"query": "latest developments in quantum computing",
|
|
119
|
+
"results": [
|
|
120
|
+
{
|
|
121
|
+
"title": "Page Title",
|
|
122
|
+
"url": "https://example.com/page",
|
|
123
|
+
"content": "Extracted text snippet...",
|
|
124
|
+
"score": 0.85
|
|
125
|
+
}
|
|
126
|
+
],
|
|
127
|
+
"response_time": 1.2
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Search Depth
|
|
132
|
+
|
|
133
|
+
| Depth | Latency | Relevance | Content Type |
|
|
134
|
+
|-------|---------|-----------|--------------|
|
|
135
|
+
| `ultra-fast` | Lowest | Lower | NLP summary |
|
|
136
|
+
| `fast` | Low | Good | Chunks |
|
|
137
|
+
| `basic` | Medium | High | NLP summary |
|
|
138
|
+
| `advanced` | Higher | Highest | Chunks |
|
|
139
|
+
|
|
140
|
+
**When to use each:**
|
|
141
|
+
- `ultra-fast`: Real-time chat, autocomplete
|
|
142
|
+
- `fast`: Need chunks but latency matters
|
|
143
|
+
- `basic`: General-purpose, balanced
|
|
144
|
+
- `advanced`: Precision matters (default recommendation)
|
|
145
|
+
|
|
146
|
+
## Examples
|
|
147
|
+
|
|
148
|
+
### Domain-Filtered Search
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
curl --request POST \
|
|
152
|
+
--url https://api.tavily.com/search \
|
|
153
|
+
--header "Authorization: Bearer $TAVILY_API_KEY" \
|
|
154
|
+
--header 'Content-Type: application/json' \
|
|
155
|
+
--data '{
|
|
156
|
+
"query": "Python async best practices",
|
|
157
|
+
"include_domains": ["docs.python.org", "realpython.com", "github.com"],
|
|
158
|
+
"search_depth": "advanced"
|
|
159
|
+
}'
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Search with Full Content
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
curl --request POST \
|
|
166
|
+
--url https://api.tavily.com/search \
|
|
167
|
+
--header "Authorization: Bearer $TAVILY_API_KEY" \
|
|
168
|
+
--header 'Content-Type: application/json' \
|
|
169
|
+
--data '{
|
|
170
|
+
"query": "React hooks tutorial",
|
|
171
|
+
"max_results": 3,
|
|
172
|
+
"include_raw_content": true
|
|
173
|
+
}'
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Tips
|
|
177
|
+
|
|
178
|
+
- **Keep queries under 400 characters** - Think search query, not prompt
|
|
179
|
+
- **Break complex queries into sub-queries** - Better results than one massive query
|
|
180
|
+
- **Use `include_domains`** to focus on trusted sources
|
|
181
|
+
- **Use `time_range`** for recent information
|
|
182
|
+
- **Filter by `score`** (0-1) to get highest relevance results
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Tavily Search API script
|
|
3
|
+
# Usage: ./search.sh '{"query": "your search query", ...}'
|
|
4
|
+
# Example: ./search.sh '{"query": "AI news", "time_range": "week", "max_results": 10}'
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Check for TAVILY_API_KEY environment variable
|
|
9
|
+
if [ -z "$TAVILY_API_KEY" ]; then
|
|
10
|
+
echo "Error: TAVILY_API_KEY environment variable is required" >&2
|
|
11
|
+
echo "Please set it: export TAVILY_API_KEY='your-api-key'" >&2
|
|
12
|
+
exit 1
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
JSON_INPUT="$1"
|
|
16
|
+
|
|
17
|
+
if [ -z "$JSON_INPUT" ]; then
|
|
18
|
+
echo "Usage: ./search.sh '<json>'"
|
|
19
|
+
echo ""
|
|
20
|
+
echo "Required:"
|
|
21
|
+
echo " query: string - Search query (keep under 400 chars)"
|
|
22
|
+
echo ""
|
|
23
|
+
echo "Optional:"
|
|
24
|
+
echo " search_depth: \"ultra-fast\", \"fast\", \"basic\" (default), \"advanced\""
|
|
25
|
+
echo " topic: \"general\" (default)"
|
|
26
|
+
echo " max_results: 1-20 (default: 10)"
|
|
27
|
+
echo " time_range: \"day\", \"week\", \"month\", \"year\""
|
|
28
|
+
echo " start_date: \"YYYY-MM-DD\""
|
|
29
|
+
echo " end_date: \"YYYY-MM-DD\""
|
|
30
|
+
echo " include_domains: [\"domain1.com\", \"domain2.com\"]"
|
|
31
|
+
echo " exclude_domains: [\"domain1.com\", \"domain2.com\"]"
|
|
32
|
+
echo " country: country name (general topic only)"
|
|
33
|
+
echo " include_raw_content: true/false"
|
|
34
|
+
echo " include_images: true/false"
|
|
35
|
+
echo " include_image_descriptions: true/false"
|
|
36
|
+
echo " include_favicon: true/false"
|
|
37
|
+
echo ""
|
|
38
|
+
echo "Example:"
|
|
39
|
+
echo " ./search.sh '{\"query\": \"latest AI trends\", \"time_range\": \"week\"}'"
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
MCP_REQUEST='{
|
|
44
|
+
"jsonrpc": "2.0",
|
|
45
|
+
"id": 1,
|
|
46
|
+
"method": "tools/call",
|
|
47
|
+
"params": {
|
|
48
|
+
"name": "tavily_search",
|
|
49
|
+
"arguments": '"$JSON_INPUT"'
|
|
50
|
+
}
|
|
51
|
+
}'
|
|
52
|
+
|
|
53
|
+
# Call Tavily MCP server via HTTPS
|
|
54
|
+
RESPONSE=$(curl -s --request POST \
|
|
55
|
+
--url "https://mcp.tavily.com/mcp" \
|
|
56
|
+
--header "Authorization: Bearer $TAVILY_API_KEY" \
|
|
57
|
+
--header 'Content-Type: application/json' \
|
|
58
|
+
--header 'Accept: application/json, text/event-stream' \
|
|
59
|
+
--header 'x-client-source: claude-code-skill' \
|
|
60
|
+
--data "$MCP_REQUEST")
|
|
61
|
+
|
|
62
|
+
# Parse SSE response and extract the JSON result
|
|
63
|
+
JSON_DATA=$(echo "$RESPONSE" | grep '^data:' | sed 's/^data://' | head -1)
|
|
64
|
+
|
|
65
|
+
if [ -n "$JSON_DATA" ]; then
|
|
66
|
+
echo "$JSON_DATA"
|
|
67
|
+
else
|
|
68
|
+
echo "$RESPONSE"
|
|
69
|
+
fi
|
package/src/apis/honor-auth.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type { TokenResponse, HonorAuthConfig } from '../honor-auth/types.js';
|
|
|
9
9
|
import { uuid } from '../utils/id.js';
|
|
10
10
|
import { isOKResponse } from './helpers.js';
|
|
11
11
|
import type { HttpApiWrapper } from './types.js';
|
|
12
|
+
import { takeApiHost } from '../modules/claw-configs/hosts.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* PKCE参数
|
|
@@ -101,7 +102,8 @@ export class HonorAuthClient {
|
|
|
101
102
|
* 使用授权码换取Token
|
|
102
103
|
*/
|
|
103
104
|
async exchangeToken(code: string) {
|
|
104
|
-
const
|
|
105
|
+
const hosts = takeApiHost();
|
|
106
|
+
const tokenUrl = `https://${hosts.ics}/honorboard/auth/v1/oauth/jwtToken`;
|
|
105
107
|
|
|
106
108
|
const data = {
|
|
107
109
|
clientId: this.config.clientId,
|