@scotthuang/openclaw-bytedance 0.1.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.
@@ -0,0 +1,314 @@
1
+ import { createProviderHttpError, formatProviderHttpErrorMessage, readProviderJsonResponse, } from "openclaw/plugin-sdk/provider-http";
2
+ import { buildSearchCacheKey, formatCliCommand, mergeScopedSearchConfig, readCachedSearchPayload, readConfiguredSecretString, readNumberParam, readStringParam, resolveProviderWebSearchPluginConfig, resolveSearchCacheTtlMs, resolveSearchTimeoutSeconds, resolveSiteName, withTrustedWebSearchEndpoint, wrapWebContent, writeCachedSearchPayload, } from "openclaw/plugin-sdk/provider-web-search";
3
+ import { SEARCH_TRAFFIC_TAG, buildArkEndpoint, resolveArkSearchApiKey, resolveArkSearchBaseUrl, } from "./credentials.js";
4
+ import { formatErr, log } from "./logger.js";
5
+ /**
6
+ * ByteDance (Volcengine Ark) web-search provider runtime.
7
+ *
8
+ * Backed by Volcengine's "AskEcho Search Infinity" service, which is the same
9
+ * search engine the official `mcp_server_askecho_search_infinity` MCP server
10
+ * wraps. This is the search backend bundled with Agent Plan / Harness.
11
+ *
12
+ * POST https://open.feedcoopapi.com/search_api/web_search
13
+ * Authorization: Bearer <ARK_SEARCH_API_KEY>
14
+ * Content-Type: application/json
15
+ * X-Traffic-Tag: ark_mcp_server_<tag>
16
+ * { "Query": "...", "SearchType": "web", "Count": 10, "NeedSummary": true,
17
+ * "TimeRange": "OneDay|OneWeek|OneMonth|OneYear|YYYY-MM-DD..YYYY-MM-DD",
18
+ * "Filter": { "AuthInfoLevel": 0|1 } }
19
+ *
20
+ * Note: Search requires its **own** API key, separate from the chat key:
21
+ * - Vision/chat key → ARK_API_KEY → Authorization for /api/plan/v3/*
22
+ * - Search key → ARK_SEARCH_API_KEY (alias: ASK_ECHO_SEARCH_INFINITY_API_KEY)
23
+ */
24
+ const SEARCH_PATH = "/search_api/web_search";
25
+ const TIME_RANGE_SHORTCUTS = new Set([
26
+ "OneDay",
27
+ "OneWeek",
28
+ "OneMonth",
29
+ "OneYear",
30
+ ]);
31
+ const DATE_RANGE_PATTERN = /^(\d{4}-\d{2}-\d{2})\.\.(\d{4}-\d{2}-\d{2})$/;
32
+ const MAX_QUERY_LENGTH = 100;
33
+ const MAX_WEB_COUNT = 50;
34
+ const DEFAULT_COUNT = 5;
35
+ function readSearchType(value) {
36
+ if (value === "web" || value === "image")
37
+ return value;
38
+ return undefined;
39
+ }
40
+ function truncate(text, max) {
41
+ if (typeof text !== "string")
42
+ return "";
43
+ return text.length > max ? `${text.slice(0, max)}…` : text;
44
+ }
45
+ function resolveSearchType(args, searchConfig) {
46
+ return (readSearchType(args.searchType) ??
47
+ readSearchType(args.search_type) ??
48
+ readSearchType(searchConfig?.searchType) ??
49
+ "web");
50
+ }
51
+ function resolveAuthLevel(args) {
52
+ const v = args.authLevel ?? args.auth_level;
53
+ if (v === 1 || v === "1")
54
+ return 1;
55
+ return 0;
56
+ }
57
+ function readTimeRange(value) {
58
+ if (typeof value !== "string")
59
+ return undefined;
60
+ const trimmed = value.trim();
61
+ if (trimmed.length === 0)
62
+ return undefined;
63
+ if (TIME_RANGE_SHORTCUTS.has(trimmed))
64
+ return trimmed;
65
+ const match = DATE_RANGE_PATTERN.exec(trimmed);
66
+ if (!match) {
67
+ throw new Error(`Invalid timeRange '${trimmed}'. Use OneDay/OneWeek/OneMonth/OneYear or YYYY-MM-DD..YYYY-MM-DD.`);
68
+ }
69
+ const start = new Date(match[1]);
70
+ const end = new Date(match[2]);
71
+ if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime())) {
72
+ throw new Error(`Invalid date in timeRange '${trimmed}'.`);
73
+ }
74
+ if (start > end) {
75
+ throw new Error(`timeRange start date must not be after end date.`);
76
+ }
77
+ return trimmed;
78
+ }
79
+ function clampCount(count, searchType) {
80
+ const raw = typeof count === "number" && Number.isFinite(count) ? Math.floor(count) : DEFAULT_COUNT;
81
+ const max = searchType === "web" ? MAX_WEB_COUNT : 5;
82
+ if (raw < 1)
83
+ return 1;
84
+ if (raw > max)
85
+ return max;
86
+ return raw;
87
+ }
88
+ function buildPayload(req) {
89
+ const payload = {
90
+ Query: req.Query,
91
+ SearchType: req.SearchType,
92
+ Count: req.Count,
93
+ };
94
+ if (req.SearchType === "web") {
95
+ payload.NeedSummary = true;
96
+ if (req.Filter)
97
+ payload.Filter = req.Filter;
98
+ if (req.TimeRange)
99
+ payload.TimeRange = req.TimeRange;
100
+ }
101
+ return payload;
102
+ }
103
+ function normalizeReference(raw) {
104
+ const url = typeof raw.Url === "string" && raw.Url.length > 0 ? raw.Url : undefined;
105
+ if (!url)
106
+ return undefined;
107
+ const title = typeof raw.Title === "string" ? raw.Title : "";
108
+ // Snippet is short; Summary is the longer model-generated abstract.
109
+ const description = typeof raw.Snippet === "string" ? raw.Snippet : "";
110
+ const summary = typeof raw.Summary === "string" && raw.Summary.length > 0 ? raw.Summary : undefined;
111
+ return {
112
+ title: title ? wrapWebContent(title, "web_search") : "",
113
+ url,
114
+ description: description ? wrapWebContent(description, "web_search") : "",
115
+ summary: summary ? wrapWebContent(summary, "web_search") : undefined,
116
+ published: typeof raw.PublishTime === "string" ? raw.PublishTime : undefined,
117
+ siteName: (typeof raw.SiteName === "string" && raw.SiteName.length > 0
118
+ ? raw.SiteName
119
+ : resolveSiteName(url)) || undefined,
120
+ };
121
+ }
122
+ function extractReferences(payload, searchType, count) {
123
+ const list = searchType === "image" ? payload.Result?.ImageResults : payload.Result?.WebResults;
124
+ if (!Array.isArray(list))
125
+ return [];
126
+ const out = [];
127
+ for (const raw of list) {
128
+ const ref = normalizeReference(raw);
129
+ if (ref)
130
+ out.push(ref);
131
+ if (out.length >= count)
132
+ break;
133
+ }
134
+ return out;
135
+ }
136
+ async function runAskEchoSearch(params) {
137
+ const endpoint = buildArkEndpoint(params.baseUrl, SEARCH_PATH);
138
+ log.debug(`web_search: POST ${endpoint} type=${params.body.SearchType} count=${params.body.Count} ` +
139
+ `timeRange=${params.body.TimeRange ?? "-"} authLevel=${params.body.Filter?.AuthInfoLevel ?? 0} ` +
140
+ `query="${truncate(params.body.Query, 80)}" timeoutSec=${params.timeoutSeconds}`);
141
+ const startedAt = Date.now();
142
+ return withTrustedWebSearchEndpoint({
143
+ url: endpoint,
144
+ timeoutSeconds: params.timeoutSeconds,
145
+ init: {
146
+ method: "POST",
147
+ headers: {
148
+ Authorization: `Bearer ${params.apiKey}`,
149
+ "Content-Type": "application/json",
150
+ Accept: "application/json",
151
+ "X-Traffic-Tag": SEARCH_TRAFFIC_TAG,
152
+ },
153
+ body: JSON.stringify(buildPayload(params.body)),
154
+ },
155
+ }, async (res) => {
156
+ const elapsed = Date.now() - startedAt;
157
+ if (!res.ok) {
158
+ log.warn(`web_search: HTTP ${res.status} from ${endpoint} after ${elapsed}ms ` +
159
+ `(query="${truncate(params.body.Query, 60)}")`);
160
+ throw await createProviderHttpError(res, "Volcengine Ark Web Search error");
161
+ }
162
+ let data;
163
+ try {
164
+ data = await readProviderJsonResponse(res, "Volcengine Ark Web Search error");
165
+ }
166
+ catch (err) {
167
+ log.error(`web_search: malformed JSON from ${endpoint} after ${elapsed}ms: ${formatErr(err)}`);
168
+ throw err;
169
+ }
170
+ if (data.error?.message) {
171
+ log.warn(`web_search: provider returned error envelope (code=${data.error.code ?? "?"}, ` +
172
+ `type=${data.error.type ?? "?"}): ${truncate(data.error.message, 200)}`);
173
+ throw new Error(formatProviderHttpErrorMessage({
174
+ label: "Volcengine Ark Web Search error",
175
+ status: typeof data.error.code === "number" ? data.error.code : 0,
176
+ detail: data.error.message,
177
+ }));
178
+ }
179
+ const resultsLen = Array.isArray(params.body.SearchType === "image" ? data.Result?.ImageResults : data.Result?.WebResults)
180
+ ? (params.body.SearchType === "image"
181
+ ? data.Result.ImageResults.length
182
+ : data.Result.WebResults.length)
183
+ : 0;
184
+ log.debug(`web_search: HTTP 200 in ${elapsed}ms requestId=${data.ResponseMetadata?.RequestId ?? "-"} ` +
185
+ `rawResults=${resultsLen}`);
186
+ return data;
187
+ });
188
+ }
189
+ function missingApiKeyPayload() {
190
+ return {
191
+ error: "missing_ark_search_api_key",
192
+ message: `web_search (bytedance) needs a Volcengine Ark Harness search key. ` +
193
+ `Set ARK_SEARCH_API_KEY (or ASK_ECHO_SEARCH_INFINITY_API_KEY) in the environment, ` +
194
+ `or run \`${formatCliCommand("openclaw configure --section web")}\` to store it. ` +
195
+ `Get a key from the Volcengine console (Agent Plan → 使用配置 → 配置 Harness → 联网 API Key).`,
196
+ docs: "https://www.volcengine.com/docs/82379/2301412",
197
+ };
198
+ }
199
+ export async function executeByteDanceWebSearchProviderTool(ctx, args) {
200
+ const invokeStartedAt = Date.now();
201
+ const searchConfig = mergeScopedSearchConfig(ctx.searchConfig, "bytedance", resolveProviderWebSearchPluginConfig(ctx.config, "bytedance"), { mirrorApiKeyToTopLevel: true });
202
+ const explicitApiKey = readConfiguredSecretString(searchConfig?.apiKey, "tools.web.search.apiKey");
203
+ const apiKey = resolveArkSearchApiKey(explicitApiKey);
204
+ if (!apiKey) {
205
+ log.warn("web_search: missing ARK_SEARCH_API_KEY (and no plugins.entries.bytedance.config.webSearch.apiKey); " +
206
+ "returning structured missing_ark_search_api_key payload");
207
+ return missingApiKeyPayload();
208
+ }
209
+ const baseUrl = resolveArkSearchBaseUrl(searchConfig?.baseUrl);
210
+ // Validate query
211
+ const queryRaw = readStringParam(args, "query", { required: true });
212
+ const query = queryRaw.trim();
213
+ if (query.length === 0) {
214
+ log.warn("web_search: rejected empty query");
215
+ throw new Error("query must not be empty");
216
+ }
217
+ if (query.length > MAX_QUERY_LENGTH) {
218
+ log.warn(`web_search: rejected oversize query (len=${query.length}, max=${MAX_QUERY_LENGTH})`);
219
+ throw new Error(`query length must be 1-${MAX_QUERY_LENGTH} characters`);
220
+ }
221
+ const searchType = resolveSearchType(args, searchConfig);
222
+ const requestedCount = readNumberParam(args, "count", { integer: true });
223
+ const count = clampCount(requestedCount ?? searchConfig?.maxResults, searchType);
224
+ let timeRange;
225
+ try {
226
+ timeRange =
227
+ readTimeRange(args.timeRange) ??
228
+ readTimeRange(args.time_range) ??
229
+ readTimeRange(searchConfig?.timeRange);
230
+ }
231
+ catch (err) {
232
+ log.warn(`web_search: invalid timeRange parameter: ${formatErr(err)}`);
233
+ throw err;
234
+ }
235
+ const authLevel = resolveAuthLevel(args);
236
+ const filter = authLevel > 0 ? { AuthInfoLevel: authLevel } : undefined;
237
+ log.debug(`web_search: invoke type=${searchType} count=${count} requested=${requestedCount ?? "-"} ` +
238
+ `timeRange=${timeRange ?? "-"} authLevel=${authLevel} baseUrl=${baseUrl} ` +
239
+ `query="${truncate(query, 80)}"`);
240
+ const cacheKey = buildSearchCacheKey([
241
+ "bytedance",
242
+ baseUrl,
243
+ searchType,
244
+ query,
245
+ count,
246
+ timeRange ?? "",
247
+ authLevel,
248
+ ]);
249
+ const cached = readCachedSearchPayload(cacheKey);
250
+ if (cached) {
251
+ log.debug(`web_search: cache hit (key=${cacheKey.slice(0, 16)}…) skipping HTTP for query="${truncate(query, 60)}"`);
252
+ return cached;
253
+ }
254
+ const start = Date.now();
255
+ const timeoutSeconds = resolveSearchTimeoutSeconds(searchConfig);
256
+ const cacheTtlMs = resolveSearchCacheTtlMs(searchConfig);
257
+ let data;
258
+ try {
259
+ data = await runAskEchoSearch({
260
+ apiKey,
261
+ baseUrl,
262
+ body: {
263
+ Query: query,
264
+ SearchType: searchType,
265
+ Count: count,
266
+ NeedSummary: searchType === "web" ? true : undefined,
267
+ TimeRange: timeRange,
268
+ Filter: filter,
269
+ },
270
+ timeoutSeconds,
271
+ });
272
+ }
273
+ catch (err) {
274
+ log.error(`web_search: request failed after ${Date.now() - start}ms ` +
275
+ `(query="${truncate(query, 60)}"): ${formatErr(err)}`);
276
+ throw err;
277
+ }
278
+ const references = extractReferences(data, searchType, count);
279
+ const tookMs = Date.now() - start;
280
+ const payload = {
281
+ query,
282
+ provider: "bytedance",
283
+ searchType,
284
+ count: references.length,
285
+ tookMs,
286
+ requestId: data.ResponseMetadata?.RequestId,
287
+ externalContent: {
288
+ untrusted: true,
289
+ source: "web_search",
290
+ provider: "bytedance",
291
+ wrapped: true,
292
+ },
293
+ results: references,
294
+ };
295
+ if (timeRange)
296
+ payload.timeRange = timeRange;
297
+ writeCachedSearchPayload(cacheKey, payload, cacheTtlMs);
298
+ log.info(`web_search: ok type=${searchType} returned=${references.length}/${count} ` +
299
+ `tookMs=${tookMs} totalMs=${Date.now() - invokeStartedAt} ` +
300
+ `requestId=${data.ResponseMetadata?.RequestId ?? "-"} ` +
301
+ `query="${truncate(query, 60)}"`);
302
+ return payload;
303
+ }
304
+ export const __testing = {
305
+ resolveSearchType,
306
+ resolveAuthLevel,
307
+ readTimeRange,
308
+ clampCount,
309
+ buildPayload,
310
+ normalizeReference,
311
+ extractReferences,
312
+ SEARCH_PATH,
313
+ };
314
+ //# sourceMappingURL=bytedance-web-search-provider.runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bytedance-web-search-provider.runtime.js","sourceRoot":"","sources":["../../src/bytedance-web-search-provider.runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Shared credential / endpoint resolution for the ByteDance (Volcengine Ark) plugin.
3
+ *
4
+ * This plugin uses the **Volcengine Ark Agent Plan** product surface, which has
5
+ * two independent API surfaces:
6
+ *
7
+ * 1. **Vision (image understanding)** — OpenAI-compatible Chat Completions:
8
+ * Endpoint: ${ARK_BASE_URL}/chat/completions
9
+ * Auth: Authorization: Bearer ${ARK_API_KEY}
10
+ * Default: https://ark.cn-beijing.volces.com/api/plan/v3
11
+ *
12
+ * 2. **Web search (Harness "AskEcho Search Infinity")** — separate service
13
+ * with its own quota and its own API key:
14
+ * Endpoint: ${ARK_SEARCH_BASE_URL}/search_api/web_search
15
+ * Auth: Authorization: Bearer ${ARK_SEARCH_API_KEY}
16
+ * Default: https://open.feedcoopapi.com
17
+ *
18
+ * Both keys are read at runtime from configuration or environment variables
19
+ * — this plugin **never bundles any credentials**.
20
+ */
21
+ export declare const DEFAULT_ARK_BASE_URL = "https://ark.cn-beijing.volces.com/api/plan/v3";
22
+ export declare const ARK_API_KEY_ENV_VARS: readonly ["ARK_API_KEY", "VOLCENGINE_API_KEY"];
23
+ export declare const ARK_BASE_URL_ENV_VARS: readonly ["ARK_BASE_URL", "VOLCENGINE_BASE_URL"];
24
+ export declare const DEFAULT_ARK_SEARCH_BASE_URL = "https://open.feedcoopapi.com";
25
+ export declare const ARK_SEARCH_API_KEY_ENV_VARS: readonly ["ARK_SEARCH_API_KEY", "ASK_ECHO_SEARCH_INFINITY_API_KEY", "VOLCENGINE_SEARCH_API_KEY"];
26
+ export declare const ARK_SEARCH_BASE_URL_ENV_VARS: readonly ["ARK_SEARCH_BASE_URL"];
27
+ export declare const DEFAULT_VISION_MODEL = "doubao-seed-2.0-pro";
28
+ export declare const SEARCH_TRAFFIC_TAG = "ark_mcp_server_openclaw_bytedance";
29
+ /** Resolve the Ark API key from (in order): explicit override → env vars. */
30
+ export declare function resolveArkApiKey(explicit?: unknown): string | undefined;
31
+ /** Resolve the Ark Base URL with fallback to env vars and the built-in default. */
32
+ export declare function resolveArkBaseUrl(explicit?: unknown): string;
33
+ /** Resolve the AskEcho Search Infinity API key. */
34
+ export declare function resolveArkSearchApiKey(explicit?: unknown): string | undefined;
35
+ /** Resolve the AskEcho Search Infinity base URL. */
36
+ export declare function resolveArkSearchBaseUrl(explicit?: unknown): string;
37
+ /**
38
+ * Build a full endpoint URL for an Ark API path (e.g. `/responses`,
39
+ * `/chat/completions`). Path must begin with a leading slash.
40
+ */
41
+ export declare function buildArkEndpoint(baseUrl: string, path: string): string;
42
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,eAAO,MAAM,oBAAoB,kDAAkD,CAAC;AACpF,eAAO,MAAM,oBAAoB,gDAAiD,CAAC;AACnF,eAAO,MAAM,qBAAqB,kDAAmD,CAAC;AAItF,eAAO,MAAM,2BAA2B,iCAAiC,CAAC;AAC1E,eAAO,MAAM,2BAA2B,kGAM9B,CAAC;AACX,eAAO,MAAM,4BAA4B,kCAAmC,CAAC;AAI7E,eAAO,MAAM,oBAAoB,wBAAwB,CAAC;AAK1D,eAAO,MAAM,kBAAkB,sCAAsC,CAAC;AA+BtE,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAEvE;AAED,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAI5D;AAID,mDAAmD;AACnD,wBAAgB,sBAAsB,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE7E;AAED,oDAAoD;AACpD,wBAAgB,uBAAuB,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAIlE;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKtE"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Shared credential / endpoint resolution for the ByteDance (Volcengine Ark) plugin.
3
+ *
4
+ * This plugin uses the **Volcengine Ark Agent Plan** product surface, which has
5
+ * two independent API surfaces:
6
+ *
7
+ * 1. **Vision (image understanding)** — OpenAI-compatible Chat Completions:
8
+ * Endpoint: ${ARK_BASE_URL}/chat/completions
9
+ * Auth: Authorization: Bearer ${ARK_API_KEY}
10
+ * Default: https://ark.cn-beijing.volces.com/api/plan/v3
11
+ *
12
+ * 2. **Web search (Harness "AskEcho Search Infinity")** — separate service
13
+ * with its own quota and its own API key:
14
+ * Endpoint: ${ARK_SEARCH_BASE_URL}/search_api/web_search
15
+ * Auth: Authorization: Bearer ${ARK_SEARCH_API_KEY}
16
+ * Default: https://open.feedcoopapi.com
17
+ *
18
+ * Both keys are read at runtime from configuration or environment variables
19
+ * — this plugin **never bundles any credentials**.
20
+ */
21
+ // --- Vision / chat-completions ------------------------------------------
22
+ export const DEFAULT_ARK_BASE_URL = "https://ark.cn-beijing.volces.com/api/plan/v3";
23
+ export const ARK_API_KEY_ENV_VARS = ["ARK_API_KEY", "VOLCENGINE_API_KEY"];
24
+ export const ARK_BASE_URL_ENV_VARS = ["ARK_BASE_URL", "VOLCENGINE_BASE_URL"];
25
+ // --- Web search (AskEcho Search Infinity) -------------------------------
26
+ export const DEFAULT_ARK_SEARCH_BASE_URL = "https://open.feedcoopapi.com";
27
+ export const ARK_SEARCH_API_KEY_ENV_VARS = [
28
+ "ARK_SEARCH_API_KEY",
29
+ // Match the variable name used by Volcengine's official MCP server, so
30
+ // existing Harness setups can drop in without renaming.
31
+ "ASK_ECHO_SEARCH_INFINITY_API_KEY",
32
+ "VOLCENGINE_SEARCH_API_KEY",
33
+ ];
34
+ export const ARK_SEARCH_BASE_URL_ENV_VARS = ["ARK_SEARCH_BASE_URL"];
35
+ // --- Defaults -----------------------------------------------------------
36
+ export const DEFAULT_VISION_MODEL = "doubao-seed-2.0-pro";
37
+ // "Traffic tag" header value used by the official Volcengine MCP server to
38
+ // identify the calling tool. We follow the same convention so search-side
39
+ // dashboards can attribute traffic to this plugin.
40
+ export const SEARCH_TRAFFIC_TAG = "ark_mcp_server_openclaw_bytedance";
41
+ // --- Helpers ------------------------------------------------------------
42
+ function readEnv(names) {
43
+ for (const name of names) {
44
+ const raw = process.env[name];
45
+ if (typeof raw === "string") {
46
+ const trimmed = raw.trim();
47
+ if (trimmed.length > 0) {
48
+ return trimmed;
49
+ }
50
+ }
51
+ }
52
+ return undefined;
53
+ }
54
+ function readString(value) {
55
+ if (typeof value !== "string") {
56
+ return undefined;
57
+ }
58
+ const trimmed = value.trim();
59
+ return trimmed.length > 0 ? trimmed : undefined;
60
+ }
61
+ function stripTrailingSlashes(s) {
62
+ return s.replace(/\/+$/, "");
63
+ }
64
+ // --- Public resolvers (vision/chat) -------------------------------------
65
+ /** Resolve the Ark API key from (in order): explicit override → env vars. */
66
+ export function resolveArkApiKey(explicit) {
67
+ return readString(explicit) ?? readEnv(ARK_API_KEY_ENV_VARS);
68
+ }
69
+ /** Resolve the Ark Base URL with fallback to env vars and the built-in default. */
70
+ export function resolveArkBaseUrl(explicit) {
71
+ return stripTrailingSlashes(readString(explicit) ?? readEnv(ARK_BASE_URL_ENV_VARS) ?? DEFAULT_ARK_BASE_URL);
72
+ }
73
+ // --- Public resolvers (search) ------------------------------------------
74
+ /** Resolve the AskEcho Search Infinity API key. */
75
+ export function resolveArkSearchApiKey(explicit) {
76
+ return readString(explicit) ?? readEnv(ARK_SEARCH_API_KEY_ENV_VARS);
77
+ }
78
+ /** Resolve the AskEcho Search Infinity base URL. */
79
+ export function resolveArkSearchBaseUrl(explicit) {
80
+ return stripTrailingSlashes(readString(explicit) ?? readEnv(ARK_SEARCH_BASE_URL_ENV_VARS) ?? DEFAULT_ARK_SEARCH_BASE_URL);
81
+ }
82
+ // --- URL builder --------------------------------------------------------
83
+ /**
84
+ * Build a full endpoint URL for an Ark API path (e.g. `/responses`,
85
+ * `/chat/completions`). Path must begin with a leading slash.
86
+ */
87
+ export function buildArkEndpoint(baseUrl, path) {
88
+ if (!path.startsWith("/")) {
89
+ throw new Error(`Ark API path must start with '/': got ${path}`);
90
+ }
91
+ return `${stripTrailingSlashes(baseUrl)}${path}`;
92
+ }
93
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Module-level logger for the openclaw-bytedance plugin.
3
+ *
4
+ * The OpenClaw host hands the plugin a `PluginLogger` only at `register(api)`
5
+ * time. Provider plugins (web search / media understanding) are plain data
6
+ * objects whose runtime methods are invoked later by the host without a
7
+ * logger argument, so we capture the host logger at registration time and
8
+ * expose it through this module to the runtime files.
9
+ *
10
+ * Design:
11
+ * - Default is a no-op so unit tests / direct imports never crash.
12
+ * - `setPluginLogger(api.logger)` is called from `index.ts` register().
13
+ * - All log lines are prefixed with `[bytedance] ...` to match OpenClaw's
14
+ * extension convention (matches `extensions/voice-call`,
15
+ * `extensions/memory-core`, etc).
16
+ * - `debug` is optional on `PluginLogger`, so we forward it through `?.`
17
+ * and silently drop debug lines when the host did not wire a debug sink.
18
+ */
19
+ /** Minimal subset of openclaw's PluginLogger we depend on. */
20
+ export interface PluginLoggerLike {
21
+ debug?: (message: string) => void;
22
+ info: (message: string) => void;
23
+ warn: (message: string) => void;
24
+ error: (message: string) => void;
25
+ }
26
+ /** Inject the host-provided logger. Called once from `index.ts#register`. */
27
+ export declare function setPluginLogger(logger: PluginLoggerLike | undefined): void;
28
+ /** Reset to no-op (useful for tests). */
29
+ export declare function resetPluginLogger(): void;
30
+ export declare const log: {
31
+ debug(message: string): void;
32
+ info(message: string): void;
33
+ warn(message: string): void;
34
+ error(message: string): void;
35
+ };
36
+ /**
37
+ * Format an error/exception consistently for log output.
38
+ * Keeps it short (no stack flood) while preserving useful detail.
39
+ */
40
+ export declare function formatErr(err: unknown): string;
41
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,8DAA8D;AAC9D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAaD,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAE1E;AAED,yCAAyC;AACzC,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAMD,eAAO,MAAM,GAAG;mBACC,MAAM,GAAG,IAAI;kBAGd,MAAM,GAAG,IAAI;kBAGb,MAAM,GAAG,IAAI;mBAGZ,MAAM,GAAG,IAAI;CAG7B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAU9C"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Module-level logger for the openclaw-bytedance plugin.
3
+ *
4
+ * The OpenClaw host hands the plugin a `PluginLogger` only at `register(api)`
5
+ * time. Provider plugins (web search / media understanding) are plain data
6
+ * objects whose runtime methods are invoked later by the host without a
7
+ * logger argument, so we capture the host logger at registration time and
8
+ * expose it through this module to the runtime files.
9
+ *
10
+ * Design:
11
+ * - Default is a no-op so unit tests / direct imports never crash.
12
+ * - `setPluginLogger(api.logger)` is called from `index.ts` register().
13
+ * - All log lines are prefixed with `[bytedance] ...` to match OpenClaw's
14
+ * extension convention (matches `extensions/voice-call`,
15
+ * `extensions/memory-core`, etc).
16
+ * - `debug` is optional on `PluginLogger`, so we forward it through `?.`
17
+ * and silently drop debug lines when the host did not wire a debug sink.
18
+ */
19
+ const PREFIX = "[bytedance]";
20
+ const NOOP_LOGGER = {
21
+ debug: () => { },
22
+ info: () => { },
23
+ warn: () => { },
24
+ error: () => { },
25
+ };
26
+ let activeLogger = NOOP_LOGGER;
27
+ /** Inject the host-provided logger. Called once from `index.ts#register`. */
28
+ export function setPluginLogger(logger) {
29
+ activeLogger = logger ?? NOOP_LOGGER;
30
+ }
31
+ /** Reset to no-op (useful for tests). */
32
+ export function resetPluginLogger() {
33
+ activeLogger = NOOP_LOGGER;
34
+ }
35
+ function withPrefix(message) {
36
+ return `${PREFIX} ${message}`;
37
+ }
38
+ export const log = {
39
+ debug(message) {
40
+ activeLogger.debug?.(withPrefix(message));
41
+ },
42
+ info(message) {
43
+ activeLogger.info(withPrefix(message));
44
+ },
45
+ warn(message) {
46
+ activeLogger.warn(withPrefix(message));
47
+ },
48
+ error(message) {
49
+ activeLogger.error(withPrefix(message));
50
+ },
51
+ };
52
+ /**
53
+ * Format an error/exception consistently for log output.
54
+ * Keeps it short (no stack flood) while preserving useful detail.
55
+ */
56
+ export function formatErr(err) {
57
+ if (err instanceof Error) {
58
+ return err.message ? `${err.name}: ${err.message}` : err.name;
59
+ }
60
+ if (typeof err === "string")
61
+ return err;
62
+ try {
63
+ return JSON.stringify(err);
64
+ }
65
+ catch {
66
+ return String(err);
67
+ }
68
+ }
69
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAUH,MAAM,MAAM,GAAG,aAAa,CAAC;AAE7B,MAAM,WAAW,GAAqB;IACpC,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;IACf,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;CAChB,CAAC;AAEF,IAAI,YAAY,GAAqB,WAAW,CAAC;AAEjD,6EAA6E;AAC7E,MAAM,UAAU,eAAe,CAAC,MAAoC;IAClE,YAAY,GAAG,MAAM,IAAI,WAAW,CAAC;AACvC,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,iBAAiB;IAC/B,YAAY,GAAG,WAAW,CAAC;AAC7B,CAAC;AAED,SAAS,UAAU,CAAC,OAAe;IACjC,OAAO,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,KAAK,CAAC,OAAe;QACnB,YAAY,CAAC,KAAK,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,CAAC,OAAe;QAClB,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,CAAC,OAAe;QAClB,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IACzC,CAAC;IACD,KAAK,CAAC,OAAe;QACnB,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1C,CAAC;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,GAAY;IACpC,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAChE,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACxC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { MediaUnderstandingProvider } from "openclaw/plugin-sdk/media-understanding";
2
+ export declare const bytedanceMediaUnderstandingProvider: MediaUnderstandingProvider;
3
+ //# sourceMappingURL=media-understanding-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-understanding-provider.d.ts","sourceRoot":"","sources":["../../src/media-understanding-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAMV,0BAA0B,EAC3B,MAAM,yCAAyC,CAAC;AA6ZjD,eAAO,MAAM,mCAAmC,EAAE,0BAOjD,CAAC"}