@kweaver-ai/kweaver-sdk 0.6.4 → 0.6.6

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 CHANGED
@@ -153,8 +153,8 @@ const skillMd = await client.skills.fetchContent("skill-id");
153
153
  ## CLI Reference
154
154
 
155
155
  ```
156
- kweaver auth login <url> [--alias name] [--no-auth] [--no-browser] [-u user] [-p pass] [--http-signin] [--playwright] [--insecure|-k]
157
- # -u/-p: tries HTTP /oauth2/signin first (refresh_token). If studioweb is missing: falls back to Playwright when installed, else prints install hint. --http-signin: HTTP only. --playwright: force browser automation.
156
+ kweaver auth login <url> [--alias name] [--no-auth] [--no-browser] [-u user] [-p pass] [--http-signin] [--insecure|-k]
157
+ # -u/-p (with or without --http-signin): HTTP POST /oauth2/signin (yields refresh_token). Missing -u/-p are prompted from stdin (password hidden when TTY).
158
158
  kweaver auth login <url> --client-id ID --client-secret S --refresh-token T (headless login)
159
159
  kweaver auth export [url|alias] [--json] (export command to run on a headless host)
160
160
  kweaver auth status / whoami [url|alias] [--json] # whoami: --json; with KWEAVER_BASE_URL+KWEAVER_TOKEN when no ~/.kweaver/ platform
@@ -180,7 +180,9 @@ kweaver skill list/market/get/register/status/delete/content/read-file/download/
180
180
  kweaver vega health/stats/inspect/sql/catalog/resource/connector-type
181
181
  kweaver context-loader config set/use/list/show
182
182
  kweaver context-loader kn-search/query-object-instance/...
183
- kweaver call <path> [-X METHOD] [-d BODY] [-H header]
183
+ kweaver toolbox create/list/publish/unpublish/delete
184
+ kweaver tool upload/list/enable/disable
185
+ kweaver call <path> [-X METHOD] [-d BODY] [-H header] [-F key=value]
184
186
  ```
185
187
 
186
188
  ### Dataflow CLI examples
@@ -211,6 +213,25 @@ kweaver vega sql -d '{"resource_type":"mysql","query":"SELECT * FROM {{res-1}} L
211
213
 
212
214
  If both `-d` and `--query` / `--resource-type` are present, **only `-d` is used**.
213
215
 
216
+ ### Register an Agent toolbox
217
+
218
+ ```bash
219
+ # 1. Create a toolbox pointing at your service
220
+ kweaver toolbox create \
221
+ --name my_actions \
222
+ --service-url http://my-svc:8080 \
223
+ --description "Demo action backend"
224
+ # → {"box_id":"<BOX_ID>"}
225
+
226
+ # 2. Upload an OpenAPI spec as a tool
227
+ kweaver tool upload --toolbox <BOX_ID> ./openapi.json
228
+ # → {"success_ids":["<TOOL_ID>"]}
229
+
230
+ # 3. Publish the toolbox and enable the tool
231
+ kweaver toolbox publish <BOX_ID>
232
+ kweaver tool enable --toolbox <BOX_ID> <TOOL_ID>
233
+ ```
234
+
214
235
  **No-auth platforms:** If OAuth is not enabled, use `kweaver auth <url> --no-auth` (or run a normal `auth login`; a **404** on `POST /oauth2/clients` switches to no-auth automatically). Credentials are still saved under `~/.kweaver/` and work with `auth use` / `auth list`. Optional: `KWEAVER_NO_AUTH=1` with `KWEAVER_BASE_URL` when no token env is set. SDK: `new KWeaverClient({ baseUrl, auth: false })` or `kweaver.configure({ baseUrl, auth: false })`.
215
236
 
216
237
  ## Environment Variables
package/README.zh.md CHANGED
@@ -146,8 +146,8 @@ const skillMd = await client.skills.fetchContent("skill-id");
146
146
  ## 命令速查
147
147
 
148
148
  ```
149
- kweaver auth login <url> [--alias name] [--no-auth] [--no-browser] [-u user] [-p pass] [--http-signin] [--playwright] [--insecure|-k]
150
- # -u/-p:默认先试 HTTP /oauth2/signin(可拿 refresh_token);无 studioweb 时:已装 Playwright 则回退无头浏览器,否则提示安装 Playwright;--http-signin 仅 HTTP;--playwright 强制浏览器
149
+ kweaver auth login <url> [--alias name] [--no-auth] [--no-browser] [-u user] [-p pass] [--http-signin] [--insecure|-k]
150
+ # -u/-p(无论是否带 --http-signin):HTTP POST /oauth2/signin(可拿 refresh_token);缺失的用户名/密码会从 stdin 提示输入(TTY 下密码隐藏)
151
151
  kweaver auth login <url> --client-id ID --client-secret S --refresh-token T (无浏览器登录)
152
152
  kweaver auth export [url|alias] [--json] (导出在无浏览器机器上运行的命令)
153
153
  kweaver auth status / whoami [url|alias] [--json] # whoami 支持 --json;无 ~/.kweaver/ 当前平台时可配 KWEAVER_BASE_URL+KWEAVER_TOKEN
@@ -14,7 +14,7 @@ export interface DataflowCreateBody {
14
14
  }
15
15
  export interface DataflowResult {
16
16
  status: "success" | "completed" | "failed" | "error";
17
- reason?: string;
17
+ reason?: unknown;
18
18
  }
19
19
  export interface CreateDataflowOptions {
20
20
  baseUrl: string;
@@ -0,0 +1,47 @@
1
+ interface BaseOpts {
2
+ baseUrl: string;
3
+ accessToken: string;
4
+ businessDomain?: string;
5
+ }
6
+ export interface CreateToolboxOptions extends BaseOpts {
7
+ name: string;
8
+ description: string;
9
+ serviceUrl: string;
10
+ metadataType?: "openapi";
11
+ source?: string;
12
+ }
13
+ export declare function createToolbox(opts: CreateToolboxOptions): Promise<string>;
14
+ export interface DeleteToolboxOptions extends BaseOpts {
15
+ boxId: string;
16
+ }
17
+ export declare function deleteToolbox(opts: DeleteToolboxOptions): Promise<void>;
18
+ export interface SetToolboxStatusOptions extends BaseOpts {
19
+ boxId: string;
20
+ status: "published" | "draft";
21
+ }
22
+ export declare function setToolboxStatus(opts: SetToolboxStatusOptions): Promise<void>;
23
+ export interface UploadToolOptions extends BaseOpts {
24
+ boxId: string;
25
+ filePath: string;
26
+ metadataType?: "openapi";
27
+ }
28
+ export declare function uploadTool(opts: UploadToolOptions): Promise<string>;
29
+ export interface SetToolStatusesOptions extends BaseOpts {
30
+ boxId: string;
31
+ updates: Array<{
32
+ toolId: string;
33
+ status: "enabled" | "disabled";
34
+ }>;
35
+ }
36
+ export declare function setToolStatuses(opts: SetToolStatusesOptions): Promise<void>;
37
+ export interface ListToolboxesOptions extends BaseOpts {
38
+ keyword?: string;
39
+ limit?: number;
40
+ offset?: number;
41
+ }
42
+ export declare function listToolboxes(opts: ListToolboxesOptions): Promise<string>;
43
+ export interface ListToolsOptions extends BaseOpts {
44
+ boxId: string;
45
+ }
46
+ export declare function listTools(opts: ListToolsOptions): Promise<string>;
47
+ export {};
@@ -0,0 +1,90 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { basename } from "node:path";
3
+ import { fetchTextOrThrow } from "../utils/http.js";
4
+ import { buildHeaders } from "./headers.js";
5
+ // Backend endpoints under /api/agent-operator-integration/v1/tool-box.
6
+ //
7
+ // Verified against kweaver/examples/03-action-lifecycle/run.sh (lines 78–197):
8
+ // POST /tool-box create
9
+ // DELETE /tool-box/{id} delete
10
+ // POST /tool-box/{id}/status publish/draft
11
+ // POST /tool-box/{id}/tool upload tool (multipart)
12
+ // POST /tool-box/{id}/tools/status enable/disable (batch)
13
+ //
14
+ // Verified during Task 8 e2e against the live backend (2026-04-18):
15
+ // GET /tool-box?keyword=&limit=&offset= list toolboxes
16
+ // GET /tool-box/{id}/tool list tools
17
+ const PATH = "/api/agent-operator-integration/v1/tool-box";
18
+ function url(base, suffix = "") {
19
+ return `${base.replace(/\/+$/, "")}${PATH}${suffix}`;
20
+ }
21
+ export async function createToolbox(opts) {
22
+ const body = JSON.stringify({
23
+ metadata_type: opts.metadataType ?? "openapi",
24
+ box_name: opts.name,
25
+ box_desc: opts.description,
26
+ box_svc_url: opts.serviceUrl,
27
+ source: opts.source ?? "custom",
28
+ });
29
+ const { body: text } = await fetchTextOrThrow(url(opts.baseUrl), {
30
+ method: "POST",
31
+ headers: { ...buildHeaders(opts.accessToken, opts.businessDomain ?? "bd_public"), "content-type": "application/json" },
32
+ body,
33
+ });
34
+ return text;
35
+ }
36
+ export async function deleteToolbox(opts) {
37
+ await fetchTextOrThrow(url(opts.baseUrl, `/${encodeURIComponent(opts.boxId)}`), {
38
+ method: "DELETE",
39
+ headers: buildHeaders(opts.accessToken, opts.businessDomain ?? "bd_public"),
40
+ });
41
+ }
42
+ export async function setToolboxStatus(opts) {
43
+ await fetchTextOrThrow(url(opts.baseUrl, `/${encodeURIComponent(opts.boxId)}/status`), {
44
+ method: "POST",
45
+ headers: { ...buildHeaders(opts.accessToken, opts.businessDomain ?? "bd_public"), "content-type": "application/json" },
46
+ body: JSON.stringify({ status: opts.status }),
47
+ });
48
+ }
49
+ export async function uploadTool(opts) {
50
+ const buf = await readFile(opts.filePath);
51
+ const form = new FormData();
52
+ form.append("metadata_type", opts.metadataType ?? "openapi");
53
+ form.append("data", new Blob([buf]), basename(opts.filePath));
54
+ const { body: text } = await fetchTextOrThrow(url(opts.baseUrl, `/${encodeURIComponent(opts.boxId)}/tool`), {
55
+ method: "POST",
56
+ headers: buildHeaders(opts.accessToken, opts.businessDomain ?? "bd_public"),
57
+ body: form,
58
+ });
59
+ return text;
60
+ }
61
+ export async function setToolStatuses(opts) {
62
+ const body = JSON.stringify(opts.updates.map((u) => ({ tool_id: u.toolId, status: u.status })));
63
+ await fetchTextOrThrow(url(opts.baseUrl, `/${encodeURIComponent(opts.boxId)}/tools/status`), {
64
+ method: "POST",
65
+ headers: { ...buildHeaders(opts.accessToken, opts.businessDomain ?? "bd_public"), "content-type": "application/json" },
66
+ body,
67
+ });
68
+ }
69
+ export async function listToolboxes(opts) {
70
+ const qp = new URLSearchParams();
71
+ if (opts.keyword !== undefined)
72
+ qp.set("keyword", opts.keyword);
73
+ if (opts.limit !== undefined)
74
+ qp.set("limit", String(opts.limit));
75
+ if (opts.offset !== undefined)
76
+ qp.set("offset", String(opts.offset));
77
+ const suffix = qp.toString() ? `?${qp}` : "";
78
+ const { body } = await fetchTextOrThrow(url(opts.baseUrl, suffix), {
79
+ method: "GET",
80
+ headers: buildHeaders(opts.accessToken, opts.businessDomain ?? "bd_public"),
81
+ });
82
+ return body;
83
+ }
84
+ export async function listTools(opts) {
85
+ const { body } = await fetchTextOrThrow(url(opts.baseUrl, `/${encodeURIComponent(opts.boxId)}/tool`), {
86
+ method: "GET",
87
+ headers: buildHeaders(opts.accessToken, opts.businessDomain ?? "bd_public"),
88
+ });
89
+ return body;
90
+ }
@@ -32,6 +32,40 @@ export declare function normalizeBaseUrl(value: string): string;
32
32
  */
33
33
  /** @internal Exported for CLI env-only identity resolution (`env-snapshot.ts`). */
34
34
  export declare function runWithTlsInsecure<T>(tlsInsecure: boolean | undefined, fn: () => Promise<T>): Promise<T>;
35
+ /**
36
+ * Headless login: read authorization code from stdin (full callback URL or raw code).
37
+ * Used with `--no-browser` or when automatic browser launch fails.
38
+ *
39
+ * `io` is injectable for tests; defaults to `process.stdin` / `process.stderr`.
40
+ */
41
+ export declare function promptForCode(authUrl: string, state: string, port: number, pasteMode?: "explicit" | "fallback", io?: {
42
+ input?: NodeJS.ReadableStream;
43
+ output?: NodeJS.WritableStream;
44
+ }): Promise<string>;
45
+ /**
46
+ * Prompt the user for a username on stderr (input echoed).
47
+ *
48
+ * `io` is injectable for tests; defaults to `process.stdin` / `process.stderr`.
49
+ */
50
+ export declare function promptForUsername(promptLabel?: string, io?: {
51
+ input?: NodeJS.ReadableStream;
52
+ output?: NodeJS.WritableStream;
53
+ }): Promise<string>;
54
+ /**
55
+ * Prompt the user for a password on stderr without echoing keystrokes (TTY only).
56
+ *
57
+ * Falls back to a regular readline prompt when stdin is not a TTY (e.g. piped input
58
+ * during scripted use); callers needing strict no-echo should detect this case themselves.
59
+ *
60
+ * `io` is injectable for tests.
61
+ */
62
+ export declare function promptForPassword(promptLabel?: string, io?: {
63
+ input?: NodeJS.ReadableStream & {
64
+ isTTY?: boolean;
65
+ setRawMode?: (mode: boolean) => unknown;
66
+ };
67
+ output?: NodeJS.WritableStream;
68
+ }): Promise<string>;
35
69
  /**
36
70
  * OAuth2 Authorization Code login flow.
37
71
  * 1. Register client (if not already registered), OR use a provided client ID
@@ -53,24 +87,6 @@ export declare function oauth2Login(baseUrl: string, options?: {
53
87
  */
54
88
  noBrowser?: boolean;
55
89
  }): Promise<TokenConfig>;
56
- /**
57
- * Playwright-automated OAuth2 login.
58
- *
59
- * Uses the full OAuth2 authorization code flow (same as `oauth2Login`) but
60
- * automates the browser interaction with Playwright. This produces a
61
- * refresh_token so the CLI can auto-refresh without re-login.
62
- *
63
- * When `username` and `password` are provided the browser runs headless and
64
- * fills the login form automatically. Otherwise it opens a visible browser
65
- * window for manual login (same UX as the old cookie-based flow).
66
- */
67
- export declare function playwrightLogin(baseUrl: string, options?: {
68
- username?: string;
69
- password?: string;
70
- port?: number;
71
- scope?: string;
72
- tlsInsecure?: boolean;
73
- }): Promise<TokenConfig>;
74
90
  /**
75
91
  * Parse Next.js `__NEXT_DATA__` from the OAuth2 sign-in HTML shell (CSRF + optional challenge/remember for POST /oauth2/signin).
76
92
  * Hydra `login_challenge` may appear only in the sign-in URL; use that when `pageProps.challenge` is absent.
@@ -83,10 +99,25 @@ export declare function parseSigninPageHtmlProps(html: string): {
83
99
  rsaPublicKeyMaterial?: string;
84
100
  };
85
101
  /**
86
- * True when {@link oauth2PasswordSigninLogin} failed because the Studio web sign-in shell
87
- * (`/interface/studioweb/login`) is missing or unreachable — callers may fall back to Playwright.
102
+ * Build the JSON body for `POST /oauth2/signin` (matches the browser `oauth2-ui` form).
103
+ *
104
+ * `device.client_type` MUST be a value present in the EACP whitelist defined by
105
+ * `kweaver/deploy/auto_cofig/auto_config.sh`. `console_web` is the canonical CLI value
106
+ * (also used by `kweaver-admin`); other values such as `unknown` are rejected by strict
107
+ * deployments with `管理员已禁止此类客户端登录` — surfaced upstream as a `request_forbidden`
108
+ * `No CSRF value available in the session cookie` error after Hydra discards the rejected
109
+ * login challenge.
110
+ *
111
+ * `vcode` and `dualfactorauthinfo` must be present even when empty; otherwise eachttpserver
112
+ * returns HTTP 400 (invalid parameter).
88
113
  */
89
- export declare function isStudiowebShellUnavailableError(err: unknown): boolean;
114
+ export declare function buildOauth2SigninPostBody(opts: {
115
+ csrftoken: string;
116
+ challenge: string;
117
+ account: string;
118
+ passwordCipher: string;
119
+ remember: boolean;
120
+ }): Record<string, unknown>;
90
121
  /**
91
122
  * OAuth2 Authorization Code login using HTTP **only**: `GET /oauth2/signin` (Next.js shell) and
92
123
  * `POST /oauth2/signin` with an RSA PKCS#1 v1.5–encrypted password (same as the browser `rsa.min` / Studio