@kweaver-ai/kweaver-sdk 0.6.8 → 0.6.10

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.
@@ -12,11 +12,24 @@ export async function listAgents(options) {
12
12
  custom_space_id,
13
13
  is_to_square,
14
14
  });
15
- const response = await fetchWithRetry(url, {
15
+ // Some deployments (observed on dip-poc.aishu.cn) return an empty entries
16
+ // array when this endpoint is called with `application/json`; the same
17
+ // payload sent as `text/plain` works. Other deployments only accept
18
+ // `application/json` (and reject text/plain with 4xx). Try text/plain first
19
+ // and fall back to application/json on 4xx so both platform variants work
20
+ // out of the box.
21
+ const tryPost = async (contentType) => fetchWithRetry(url, {
16
22
  method: "POST",
17
- headers: buildHeaders(accessToken, businessDomain),
23
+ headers: {
24
+ ...buildHeaders(accessToken, businessDomain),
25
+ "content-type": contentType,
26
+ },
18
27
  body,
19
28
  });
29
+ let response = await tryPost("text/plain;charset=UTF-8");
30
+ if (!response.ok && response.status >= 400 && response.status < 500) {
31
+ response = await tryPost("application/json");
32
+ }
20
33
  const responseBody = await response.text();
21
34
  if (!response.ok) {
22
35
  throw new HttpError(response.status, response.statusText, responseBody);
@@ -44,11 +44,40 @@ export declare function actionTypeQuery(options: ActionTypeQueryOptions): Promis
44
44
  /**
45
45
  * Action-type execute: POST (has side effects).
46
46
  *
47
- * The request body must include `_instance_identities`an array of objects
48
- * identifying which instances the action operates on:
47
+ * The request body must use the envelope shape below top-level scalar fields
48
+ * (other than `trigger_type` and `_instance_identities`) are silently dropped
49
+ * by the backend, which causes downstream tools to receive `null` parameters
50
+ * (and typically respond with 401 token expired or 500 type errors).
51
+ *
49
52
  * ```json
50
- * {"_instance_identities": [{"<primary_key>": "<value>"}], ...otherParams}
53
+ * {
54
+ * "trigger_type": "manual",
55
+ * "_instance_identities": [{"<primary_key>": "<value>"}],
56
+ * "dynamic_params": {
57
+ * "<param_name>": "<value>",
58
+ * "Authorization": "Bearer <token>"
59
+ * }
60
+ * }
51
61
  * ```
62
+ *
63
+ * - `_instance_identities` may be `[]` for "create"-style actions.
64
+ * - Each ActionType parameter has a `value_from` discriminator:
65
+ * • `input` — caller MUST supply via `dynamic_params`. Includes
66
+ * `source: header` params (e.g. `Authorization`/`token`),
67
+ * which are usually credentials for the DOWNSTREAM system
68
+ * the action calls — NOT the platform session token. The
69
+ * SDK never auto-forwards its session token.
70
+ * • `const` — frozen in the ActionType snapshot; values in body are
71
+ * silently ignored. Edit the ActionType definition to
72
+ * `input` first if you need caller override.
73
+ * • `property` — auto-populated from the resolved instance's property;
74
+ * do not (and cannot) supply via body.
75
+ *
76
+ * Practical recipe: query the ActionType, filter parameters where
77
+ * `value_from == "input"`, put exactly those names into `dynamic_params`.
78
+ *
79
+ * See `skills/kweaver-core/references/bkn.md` ("action-type execute 请求体契约")
80
+ * for the full contract and troubleshooting table.
52
81
  */
53
82
  export interface ActionTypeExecuteOptions extends OntologyQueryBaseOptions {
54
83
  atId: string;
@@ -44,4 +44,20 @@ export interface ListToolsOptions extends BaseOpts {
44
44
  boxId: string;
45
45
  }
46
46
  export declare function listTools(opts: ListToolsOptions): Promise<string>;
47
+ export interface InvokeToolOptions extends BaseOpts {
48
+ boxId: string;
49
+ toolId: string;
50
+ /** Optional headers to forward to the downstream tool (e.g. Authorization). */
51
+ header?: Record<string, unknown>;
52
+ /** Optional query params to forward. */
53
+ query?: Record<string, unknown>;
54
+ /** JSON body forwarded to the downstream tool. */
55
+ body?: unknown;
56
+ /** Per-call timeout in seconds; backend default applies when omitted. */
57
+ timeout?: number;
58
+ }
59
+ /** Execute a published+enabled tool through the toolbox proxy. */
60
+ export declare function executeTool(opts: InvokeToolOptions): Promise<string>;
61
+ /** Debug a tool through the toolbox proxy (works on draft/disabled tools too). */
62
+ export declare function debugTool(opts: InvokeToolOptions): Promise<string>;
47
63
  export {};
@@ -5,15 +5,24 @@ import { buildHeaders } from "./headers.js";
5
5
  // Backend endpoints under /api/agent-operator-integration/v1/tool-box.
6
6
  //
7
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)
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
13
  //
14
14
  // Verified during Task 8 e2e against the live backend (2026-04-18):
15
15
  // GET /tool-box/list?keyword=&limit=&offset= list toolboxes
16
16
  // GET /tool-box/{id}/tools/list list tools
17
+ //
18
+ // Verified live on 2026-04-23 against dip-poc.aishu.cn:
19
+ // POST /tool-box/{box}/proxy/{tool} execute tool (envelope JSON)
20
+ // POST /tool-box/{box}/tool/{tool}/debug debug tool (envelope JSON)
21
+ //
22
+ // Envelope shape required by /proxy and /debug:
23
+ // { "timeout": <s>, "header": {...}, "query": {...}, "body": {...} }
24
+ // Flat-shape requests cause the forwarder to drop downstream Authorization
25
+ // headers, which manifests as 401 "token expired" from the underlying tool.
17
26
  const PATH = "/api/agent-operator-integration/v1/tool-box";
18
27
  function url(base, suffix = "") {
19
28
  return `${base.replace(/\/+$/, "")}${PATH}${suffix}`;
@@ -88,3 +97,28 @@ export async function listTools(opts) {
88
97
  });
89
98
  return body;
90
99
  }
100
+ function buildEnvelope(opts) {
101
+ const envelope = {};
102
+ if (opts.timeout !== undefined)
103
+ envelope.timeout = opts.timeout;
104
+ envelope.header = opts.header ?? {};
105
+ envelope.query = opts.query ?? {};
106
+ envelope.body = opts.body ?? {};
107
+ return JSON.stringify(envelope);
108
+ }
109
+ async function invokeTool(opts, suffix) {
110
+ const { body } = await fetchTextOrThrow(url(opts.baseUrl, suffix), {
111
+ method: "POST",
112
+ headers: { ...buildHeaders(opts.accessToken, opts.businessDomain ?? "bd_public"), "content-type": "application/json" },
113
+ body: buildEnvelope(opts),
114
+ });
115
+ return body;
116
+ }
117
+ /** Execute a published+enabled tool through the toolbox proxy. */
118
+ export async function executeTool(opts) {
119
+ return invokeTool(opts, `/${encodeURIComponent(opts.boxId)}/proxy/${encodeURIComponent(opts.toolId)}`);
120
+ }
121
+ /** Debug a tool through the toolbox proxy (works on draft/disabled tools too). */
122
+ export async function debugTool(opts) {
123
+ return invokeTool(opts, `/${encodeURIComponent(opts.boxId)}/tool/${encodeURIComponent(opts.toolId)}/debug`);
124
+ }
package/dist/cli.js CHANGED
@@ -88,7 +88,8 @@ Usage:
88
88
  kweaver bkn object-type list|get|create|update|delete|query|properties <kn-id> ...
89
89
  kweaver bkn relation-type list|get|create|update|delete <kn-id> ...
90
90
  kweaver bkn subgraph <kn-id> <body-json>
91
- kweaver bkn action-type list|query|execute <kn-id> ... [--wait] [--no-wait] [--timeout N]
91
+ kweaver bkn action-type list|query|inputs|execute <kn-id> ... [--wait] [--no-wait] [--timeout N]
92
+ kweaver bkn action-type execute <kn-id> <at-id> [<envelope-json>|--dynamic-params '<json>' --instance '<json>' --trigger-type <v>]
92
93
  kweaver bkn action-execution get <kn-id> <execution-id>
93
94
  kweaver bkn action-log list|get|cancel <kn-id> ...
94
95
 
@@ -110,6 +111,9 @@ Usage:
110
111
  kweaver tool upload --toolbox <box-id> <openapi-spec-path> [--metadata-type openapi]
111
112
  kweaver tool list --toolbox <box-id> [-bd value]
112
113
  kweaver tool enable|disable --toolbox <box-id> <tool-id>... [-bd value]
114
+ kweaver tool execute|debug --toolbox <box-id> <tool-id>
115
+ [--body '<json>'|--body-file <path>]
116
+ [--header '<json>'] [--query '<json>'] [--timeout <s>]
113
117
 
114
118
  kweaver vega health|stats|inspect
115
119
  kweaver vega catalog list|get|health|test-connection|discover|resources [options]
package/dist/client.d.ts CHANGED
@@ -7,6 +7,7 @@ import { DataViewsResource } from "./resources/dataviews.js";
7
7
  import { KnowledgeNetworksResource } from "./resources/knowledge-networks.js";
8
8
  import { BknResource } from "./resources/bkn.js";
9
9
  import { SkillsResource } from "./resources/skills.js";
10
+ import { ToolboxesResource } from "./resources/toolboxes.js";
10
11
  import { VegaResource } from "./resources/vega.js";
11
12
  /**
12
13
  * Shared credentials passed to every resource method.
@@ -102,6 +103,8 @@ export declare class KWeaverClient implements ClientContext {
102
103
  readonly vega: VegaResource;
103
104
  /** ADP/KWeaver skill registry, market, progressive read, and install helpers. */
104
105
  readonly skills: SkillsResource;
106
+ /** Toolbox / tool management plus execute & debug invocation. */
107
+ readonly toolboxes: ToolboxesResource;
105
108
  constructor(opts?: KWeaverClientOptions);
106
109
  /**
107
110
  * Async factory that auto-refreshes expired or revoked tokens.
package/dist/client.js CHANGED
@@ -12,6 +12,7 @@ import { DataViewsResource } from "./resources/dataviews.js";
12
12
  import { KnowledgeNetworksResource } from "./resources/knowledge-networks.js";
13
13
  import { BknResource } from "./resources/bkn.js";
14
14
  import { SkillsResource } from "./resources/skills.js";
15
+ import { ToolboxesResource } from "./resources/toolboxes.js";
15
16
  import { VegaResource } from "./resources/vega.js";
16
17
  // ── KWeaverClient ─────────────────────────────────────────────────────────────
17
18
  /**
@@ -64,6 +65,8 @@ export class KWeaverClient {
64
65
  vega;
65
66
  /** ADP/KWeaver skill registry, market, progressive read, and install helpers. */
66
67
  skills;
68
+ /** Toolbox / tool management plus execute & debug invocation. */
69
+ toolboxes;
67
70
  constructor(opts = {}) {
68
71
  const envDomain = process.env.KWEAVER_BUSINESS_DOMAIN;
69
72
  if (opts.auth === false && opts.config) {
@@ -97,6 +100,7 @@ export class KWeaverClient {
97
100
  this.dataviews = new DataViewsResource(this);
98
101
  this.vega = new VegaResource(this);
99
102
  this.skills = new SkillsResource(this);
103
+ this.toolboxes = new ToolboxesResource(this);
100
104
  return;
101
105
  }
102
106
  if (opts.config) {
@@ -151,6 +155,7 @@ export class KWeaverClient {
151
155
  this.dataviews = new DataViewsResource(this);
152
156
  this.vega = new VegaResource(this);
153
157
  this.skills = new SkillsResource(this);
158
+ this.toolboxes = new ToolboxesResource(this);
154
159
  }
155
160
  /**
156
161
  * Async factory that auto-refreshes expired or revoked tokens.
@@ -95,6 +95,33 @@ export interface KnActionTypeExecuteOptions {
95
95
  timeout: number;
96
96
  }
97
97
  export declare function parseKnActionTypeExecuteArgs(args: string[]): KnActionTypeExecuteOptions;
98
+ /**
99
+ * Assemble the action-type execute envelope from CLI flags. Each flag is
100
+ * parsed as JSON; instance entries must be JSON objects; dynamic_params must
101
+ * be a JSON object. The shape produced is the contract documented in
102
+ * skills/kweaver-core/references/bkn.md.
103
+ */
104
+ export declare function buildExecuteEnvelope(opts: {
105
+ triggerType: string;
106
+ dynamicParamsJson?: string;
107
+ instanceJsons: string[];
108
+ }): string;
109
+ export interface InputParameterSummary {
110
+ name: string;
111
+ type?: string;
112
+ source?: string;
113
+ required?: boolean;
114
+ description?: string;
115
+ }
116
+ /**
117
+ * Walk a getActionType response and collect parameters where
118
+ * `value_from === "input"`. The exact response shape varies (sometimes the
119
+ * action-type is at the root, sometimes nested under data/result/...), so we
120
+ * search a few likely locations.
121
+ */
122
+ export declare function extractInputParameters(rawJson: string): InputParameterSummary[];
123
+ export declare function buildDynamicParamsTemplate(inputs: InputParameterSummary[]): Record<string, unknown>;
124
+ export declare function renderInputsTable(atId: string, inputs: InputParameterSummary[]): string;
98
125
  /** Parse relation-type create args: --name --source --target [--mapping src:tgt ...] */
99
126
  export declare function parseRelationTypeCreateArgs(args: string[]): {
100
127
  knId: string;
@@ -562,6 +562,9 @@ export function parseKnActionTypeExecuteArgs(args) {
562
562
  let businessDomain = "";
563
563
  let wait = true;
564
564
  let timeout = 300;
565
+ let dynamicParamsJson;
566
+ let triggerType;
567
+ const instanceJsons = [];
565
568
  const positional = [];
566
569
  for (let i = 0; i < args.length; i += 1) {
567
570
  const arg = args[i];
@@ -592,11 +595,41 @@ export function parseKnActionTypeExecuteArgs(args) {
592
595
  i += 1;
593
596
  continue;
594
597
  }
598
+ if (arg === "--dynamic-params" && args[i + 1]) {
599
+ dynamicParamsJson = args[++i];
600
+ continue;
601
+ }
602
+ if (arg === "--instance" && args[i + 1]) {
603
+ instanceJsons.push(args[++i]);
604
+ continue;
605
+ }
606
+ if (arg === "--trigger-type" && args[i + 1]) {
607
+ triggerType = args[++i];
608
+ continue;
609
+ }
595
610
  positional.push(arg);
596
611
  }
597
- const [knId, atId, body] = positional;
598
- if (!knId || !atId || !body) {
599
- throw new Error("Missing kn-id, at-id, or body. Usage: kweaver bkn action-type execute <kn-id> <at-id> '<json>' [options]");
612
+ const usingFlags = dynamicParamsJson !== undefined || instanceJsons.length > 0 || triggerType !== undefined;
613
+ const [knId, atId, positionalBody] = positional;
614
+ if (!knId || !atId) {
615
+ throw new Error("Missing kn-id or at-id. Usage: kweaver bkn action-type execute <kn-id> <at-id> [<json>|--dynamic-params '<json>' --instance '<json>'] [options]");
616
+ }
617
+ if (positionalBody && usingFlags) {
618
+ throw new Error("Positional body and --dynamic-params/--instance/--trigger-type are mutually exclusive. Use one form.");
619
+ }
620
+ if (!positionalBody && !usingFlags) {
621
+ throw new Error("Missing body. Provide a positional JSON envelope, or use --dynamic-params / --instance / --trigger-type.");
622
+ }
623
+ let body;
624
+ if (positionalBody) {
625
+ body = positionalBody;
626
+ }
627
+ else {
628
+ body = buildExecuteEnvelope({
629
+ triggerType: triggerType ?? "manual",
630
+ dynamicParamsJson,
631
+ instanceJsons,
632
+ });
600
633
  }
601
634
  if (!businessDomain)
602
635
  businessDomain = resolveBusinessDomain();
@@ -610,6 +643,143 @@ export function parseKnActionTypeExecuteArgs(args) {
610
643
  timeout,
611
644
  };
612
645
  }
646
+ /**
647
+ * Assemble the action-type execute envelope from CLI flags. Each flag is
648
+ * parsed as JSON; instance entries must be JSON objects; dynamic_params must
649
+ * be a JSON object. The shape produced is the contract documented in
650
+ * skills/kweaver-core/references/bkn.md.
651
+ */
652
+ export function buildExecuteEnvelope(opts) {
653
+ const envelope = {
654
+ trigger_type: opts.triggerType,
655
+ _instance_identities: opts.instanceJsons.map((s, idx) => {
656
+ let parsed;
657
+ try {
658
+ parsed = JSON.parse(s);
659
+ }
660
+ catch (e) {
661
+ throw new Error(`--instance #${idx + 1} is not valid JSON: ${e.message}`);
662
+ }
663
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
664
+ throw new Error(`--instance #${idx + 1} must be a JSON object, got ${Array.isArray(parsed) ? "array" : typeof parsed}`);
665
+ }
666
+ return parsed;
667
+ }),
668
+ };
669
+ if (opts.dynamicParamsJson !== undefined) {
670
+ let parsed;
671
+ try {
672
+ parsed = JSON.parse(opts.dynamicParamsJson);
673
+ }
674
+ catch (e) {
675
+ throw new Error(`--dynamic-params is not valid JSON: ${e.message}`);
676
+ }
677
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
678
+ throw new Error(`--dynamic-params must be a JSON object, got ${Array.isArray(parsed) ? "array" : typeof parsed}`);
679
+ }
680
+ envelope.dynamic_params = parsed;
681
+ }
682
+ else {
683
+ envelope.dynamic_params = {};
684
+ }
685
+ return JSON.stringify(envelope);
686
+ }
687
+ /**
688
+ * Walk a getActionType response and collect parameters where
689
+ * `value_from === "input"`. The exact response shape varies (sometimes the
690
+ * action-type is at the root, sometimes nested under data/result/...), so we
691
+ * search a few likely locations.
692
+ */
693
+ export function extractInputParameters(rawJson) {
694
+ let root;
695
+ try {
696
+ root = JSON.parse(rawJson);
697
+ }
698
+ catch {
699
+ return [];
700
+ }
701
+ const candidates = collectParameterArrays(root);
702
+ const seen = new Set();
703
+ const out = [];
704
+ for (const params of candidates) {
705
+ for (const p of params) {
706
+ if (!p || typeof p !== "object")
707
+ continue;
708
+ const obj = p;
709
+ if (obj.value_from !== "input")
710
+ continue;
711
+ const name = typeof obj.name === "string" ? obj.name : "";
712
+ if (!name || seen.has(name))
713
+ continue;
714
+ seen.add(name);
715
+ out.push({
716
+ name,
717
+ type: typeof obj.type === "string" ? obj.type : undefined,
718
+ source: typeof obj.source === "string" ? obj.source : undefined,
719
+ required: typeof obj.required === "boolean" ? obj.required : undefined,
720
+ description: typeof obj.description === "string" ? obj.description : undefined,
721
+ });
722
+ }
723
+ }
724
+ return out;
725
+ }
726
+ function collectParameterArrays(node, acc = []) {
727
+ if (!node)
728
+ return acc;
729
+ if (Array.isArray(node)) {
730
+ for (const item of node)
731
+ collectParameterArrays(item, acc);
732
+ return acc;
733
+ }
734
+ if (typeof node !== "object")
735
+ return acc;
736
+ const obj = node;
737
+ if (Array.isArray(obj.parameters))
738
+ acc.push(obj.parameters);
739
+ for (const v of Object.values(obj))
740
+ collectParameterArrays(v, acc);
741
+ return acc;
742
+ }
743
+ export function buildDynamicParamsTemplate(inputs) {
744
+ const tpl = {};
745
+ for (const p of inputs) {
746
+ tpl[p.name] = placeholderForType(p);
747
+ }
748
+ return tpl;
749
+ }
750
+ function placeholderForType(p) {
751
+ const hint = p.description ? ` (${p.description})` : "";
752
+ const t = (p.type ?? "").toLowerCase();
753
+ if (t === "int" || t === "integer" || t === "long" || t === "number" || t === "float" || t === "double")
754
+ return 0;
755
+ if (t === "bool" || t === "boolean")
756
+ return false;
757
+ if (t === "array" || t === "list")
758
+ return [];
759
+ if (t === "object" || t === "dict" || t === "map")
760
+ return {};
761
+ return `<${p.type ?? "string"}${p.required === false ? "?" : ""}>${hint}`;
762
+ }
763
+ export function renderInputsTable(atId, inputs) {
764
+ if (inputs.length === 0) {
765
+ return `Action type ${atId} has no parameters with value_from=input. dynamic_params can be {}.`;
766
+ }
767
+ const rows = inputs.map(p => [
768
+ p.name,
769
+ p.type ?? "-",
770
+ p.source ?? "-",
771
+ p.required === undefined ? "-" : p.required ? "yes" : "no",
772
+ truncate(p.description ?? "", 60),
773
+ ]);
774
+ const header = ["NAME", "TYPE", "SOURCE", "REQUIRED", "DESCRIPTION"];
775
+ const widths = header.map((h, i) => Math.max(h.length, ...rows.map(r => r[i].length)));
776
+ const fmt = (cols) => cols.map((c, i) => c.padEnd(widths[i])).join(" ");
777
+ const lines = [fmt(header), fmt(widths.map(w => "-".repeat(w))), ...rows.map(fmt)];
778
+ return `Action type ${atId} input parameters (value_from=input):\n${lines.join("\n")}`;
779
+ }
780
+ function truncate(s, n) {
781
+ return s.length <= n ? s : s.slice(0, n - 1) + "…";
782
+ }
613
783
  // ── Action-type execute helpers ────────────────────────────────────────────────
614
784
  const TERMINAL_STATUSES = ["SUCCESS", "FAILED", "CANCELLED"];
615
785
  function extractExecutionId(body) {
@@ -1123,17 +1293,30 @@ kweaver bkn action-type create <kn-id> '<json>' [--pretty] [-bd value]
1123
1293
  kweaver bkn action-type update <kn-id> <at-id> '<json>' [--pretty] [-bd value]
1124
1294
  kweaver bkn action-type delete <kn-id> <at-ids> [-y] [--pretty] [-bd value]
1125
1295
  kweaver bkn action-type query <kn-id> <at-id> '<json>' [--pretty] [-bd value]
1126
- kweaver bkn action-type execute <kn-id> <at-id> '<json>' [--pretty] [-bd value] [--wait|--no-wait] [--timeout n]
1296
+ kweaver bkn action-type inputs <kn-id> <at-id> [--json|--template] [-bd value]
1297
+ kweaver bkn action-type execute <kn-id> <at-id> [<json>|--dynamic-params '<json>' --instance '<json>' --trigger-type <v>] [--pretty] [-bd value] [--wait|--no-wait] [--timeout n]
1127
1298
 
1128
1299
  list: List action types (schema) from ontology-manager.
1129
1300
  get: Get a single action type by ID.
1130
1301
  create: Create action type(s) (POST JSON body).
1131
1302
  update: Update an action type (PUT JSON body).
1132
1303
  delete: Delete action type(s) by ID(s).
1133
- query/execute: Query or execute actions. execute has side effects - only use when explicitly requested.
1304
+ query: Query actions backing this action type.
1305
+ inputs: List parameters with value_from=input that the caller MUST supply.
1306
+ Default prints a table + a starter dynamic_params template.
1307
+ --json dump filtered parameters as raw JSON
1308
+ --template print only the dynamic_params template object
1309
+ execute: Run an action (has side effects - only use when explicitly requested).
1310
+ Body forms (mutually exclusive):
1311
+ 1. Positional envelope JSON: '{"trigger_type":"manual","_instance_identities":[],"dynamic_params":{...}}'
1312
+ 2. Flag form (CLI assembles the envelope):
1313
+ --dynamic-params '<json object>' parameters with value_from=input
1314
+ --instance '<json object>' repeatable; one per identity
1315
+ --trigger-type <value> defaults to "manual"
1134
1316
  --wait (default) Poll until execution completes
1135
1317
  --no-wait Return immediately after starting execution
1136
- --timeout <seconds> Max wait time when --wait (default: 300)`);
1318
+ --timeout <seconds> Max wait time when --wait (default: 300)
1319
+ See skills/kweaver-core/references/bkn.md for the full payload contract.`);
1137
1320
  return 0;
1138
1321
  }
1139
1322
  if (action === "list") {
@@ -1283,6 +1466,48 @@ query/execute: Query or execute actions. execute has side effects - only use whe
1283
1466
  return 1;
1284
1467
  }
1285
1468
  }
1469
+ if (action === "inputs") {
1470
+ const parsed = parseOntologyQueryFlags(rest);
1471
+ const flags = new Set(parsed.filteredArgs.filter(a => a.startsWith("--")));
1472
+ const positional = parsed.filteredArgs.filter(a => !a.startsWith("--"));
1473
+ const [knId, atId] = positional;
1474
+ if (!knId || !atId) {
1475
+ console.error("Usage: kweaver bkn action-type inputs <kn-id> <at-id> [--json|--template]");
1476
+ return 1;
1477
+ }
1478
+ if (flags.has("--json") && flags.has("--template")) {
1479
+ console.error("--json and --template are mutually exclusive.");
1480
+ return 1;
1481
+ }
1482
+ try {
1483
+ const token = await ensureValidToken();
1484
+ const raw = await getActionType({
1485
+ baseUrl: token.baseUrl,
1486
+ accessToken: token.accessToken,
1487
+ knId,
1488
+ atId,
1489
+ businessDomain: parsed.businessDomain,
1490
+ });
1491
+ const inputs = extractInputParameters(raw);
1492
+ if (flags.has("--json")) {
1493
+ console.log(formatCallOutput(JSON.stringify(inputs), parsed.pretty));
1494
+ return 0;
1495
+ }
1496
+ const template = buildDynamicParamsTemplate(inputs);
1497
+ if (flags.has("--template")) {
1498
+ console.log(JSON.stringify(template, null, 2));
1499
+ return 0;
1500
+ }
1501
+ console.log(renderInputsTable(atId, inputs));
1502
+ console.log("\n# Starter dynamic_params (fill in real values, then pass via --dynamic-params):");
1503
+ console.log(JSON.stringify(template, null, 2));
1504
+ return 0;
1505
+ }
1506
+ catch (error) {
1507
+ console.error(formatHttpError(error));
1508
+ return 1;
1509
+ }
1510
+ }
1286
1511
  if (action === "execute") {
1287
1512
  let options;
1288
1513
  try {
@@ -1349,7 +1574,7 @@ query/execute: Query or execute actions. execute has side effects - only use whe
1349
1574
  return 1;
1350
1575
  }
1351
1576
  }
1352
- console.error(`Unknown action-type action: ${action}. Use list, get, create, update, delete, query, or execute.`);
1577
+ console.error(`Unknown action-type action: ${action}. Use list, get, create, update, delete, query, inputs, or execute.`);
1353
1578
  return 1;
1354
1579
  }
1355
1580
  export function parseConceptGroupArgs(args) {
@@ -393,7 +393,8 @@ Subcommands:
393
393
  action-type update <kn-id> <at-id> '<json>' Update action type
394
394
  action-type delete <kn-id> <at-ids> [-y] Delete action type(s)
395
395
  action-type query <kn-id> <at-id> '<json>' Query action info
396
- action-type execute <kn-id> <at-id> '<json>' Execute action (has side effects)
396
+ action-type inputs <kn-id> <at-id> List value_from=input params + dynamic_params template
397
+ action-type execute <kn-id> <at-id> '<envelope-json>' | --dynamic-params '<json>' [--instance '<json>']... [--trigger-type <v>] Execute action (has side effects)
397
398
  action-execution get <kn-id> <execution-id> Get execution status
398
399
  action-log list <kn-id> [options] List action execution logs
399
400
  action-log get <kn-id> <log-id> Get single execution log
@@ -1,11 +1,11 @@
1
- import { ensureValidToken, formatHttpError, with401RefreshRetry } from "../auth/oauth.js";
1
+ import { ensureValidToken, formatHttpError, resolveActivePlatform, with401RefreshRetry } from "../auth/oauth.js";
2
2
  import { knSearch, knSchemaSearch, queryObjectInstance, queryInstanceSubgraph, getLogicPropertiesValues, getActionInfo, listTools, listResources, readResource, listResourceTemplates, listPrompts, getPrompt, } from "../api/context-loader.js";
3
- import { addContextLoaderEntry, getCurrentContextLoaderKn, getCurrentPlatform, loadContextLoaderConfig, removeContextLoaderEntry, setCurrentContextLoader, } from "../config/store.js";
3
+ import { addContextLoaderEntry, getCurrentContextLoaderKn, loadContextLoaderConfig, removeContextLoaderEntry, setCurrentContextLoader, } from "../config/store.js";
4
4
  const MCP_NOT_CONFIGURED = "Context-loader MCP is not configured. Run: kweaver context-loader config set --kn-id <kn-id>";
5
5
  function ensureContextLoaderConfig() {
6
- const platform = getCurrentPlatform();
7
- if (!platform) {
8
- throw new Error("No platform selected. Run: kweaver auth <platform-url>");
6
+ const active = resolveActivePlatform();
7
+ if (!active) {
8
+ throw new Error("No platform selected. Set KWEAVER_BASE_URL or run: kweaver auth <platform-url>");
9
9
  }
10
10
  const kn = getCurrentContextLoaderKn();
11
11
  if (!kn) {
@@ -118,11 +118,12 @@ Subcommands:
118
118
  show Show current config (knId + mcpUrl)`);
119
119
  return 0;
120
120
  }
121
- const platform = getCurrentPlatform();
122
- if (!platform) {
123
- console.error("No platform selected. Run: kweaver auth <platform-url>");
121
+ const active = resolveActivePlatform();
122
+ if (!active) {
123
+ console.error("No platform selected. Set KWEAVER_BASE_URL or run: kweaver auth <platform-url>");
124
124
  return 1;
125
125
  }
126
+ const platform = active.url;
126
127
  if (action === "show") {
127
128
  const kn = getCurrentContextLoaderKn();
128
129
  if (!kn) {
@@ -14,3 +14,15 @@ export interface ToolStatusOptions {
14
14
  businessDomain: string;
15
15
  }
16
16
  export declare function parseToolStatusArgs(args: string[], status: "enabled" | "disabled"): ToolStatusOptions;
17
+ export interface ToolInvokeOptions {
18
+ boxId: string;
19
+ toolId: string;
20
+ header?: Record<string, unknown>;
21
+ query?: Record<string, unknown>;
22
+ body?: unknown;
23
+ bodyFile?: string;
24
+ timeout?: number;
25
+ businessDomain: string;
26
+ pretty: boolean;
27
+ }
28
+ export declare function parseToolInvokeArgs(args: string[]): ToolInvokeOptions;
@@ -1,18 +1,29 @@
1
- import { access } from "node:fs/promises";
1
+ import { access, readFile } from "node:fs/promises";
2
2
  import { ensureValidToken, formatHttpError, with401RefreshRetry } from "../auth/oauth.js";
3
- import { listTools, setToolStatuses, uploadTool } from "../api/toolboxes.js";
3
+ import { debugTool, executeTool, listTools, setToolStatuses, uploadTool } from "../api/toolboxes.js";
4
4
  import { formatCallOutput } from "./call.js";
5
5
  import { resolveBusinessDomain } from "../config/store.js";
6
6
  const HELP = `kweaver tool
7
7
 
8
8
  Subcommands:
9
9
  upload --toolbox <box-id> <openapi-spec-path> [--metadata-type openapi]
10
- Upload an OpenAPI spec file as a tool
11
- list --toolbox <box-id> List tools in a toolbox
12
- enable --toolbox <box-id> <tool-id>... Enable one or more tools
13
- disable --toolbox <box-id> <tool-id>... Disable one or more tools
10
+ Upload an OpenAPI spec file as a tool
11
+ list --toolbox <box-id> List tools in a toolbox
12
+ enable --toolbox <box-id> <tool-id>... Enable one or more tools
13
+ disable --toolbox <box-id> <tool-id>... Disable one or more tools
14
+ execute --toolbox <box-id> <tool-id> [--body '<json>'|--body-file <path>]
15
+ Invoke a published+enabled tool
16
+ debug --toolbox <box-id> <tool-id> [--body '<json>'|--body-file <path>]
17
+ Invoke a tool (works on draft/disabled too)
14
18
 
15
- Options:
19
+ Options for execute/debug:
20
+ --header '<json>' Headers map forwarded to the downstream tool
21
+ (Authorization is auto-injected from current session
22
+ when --header omits it; pass {} to send none)
23
+ --query '<json>' Query params map forwarded to the downstream tool
24
+ --timeout <seconds> Per-call timeout (backend default applies when omitted)
25
+
26
+ Common options:
16
27
  -bd, --biz-domain <s> Business domain (default: bd_public)
17
28
  --pretty Pretty-print JSON (default)
18
29
  --compact Single-line JSON (pipeline-friendly)`;
@@ -31,6 +42,10 @@ export async function runToolCommand(args) {
31
42
  return runToolStatus(rest, "enabled");
32
43
  if (subcommand === "disable")
33
44
  return runToolStatus(rest, "disabled");
45
+ if (subcommand === "execute")
46
+ return runToolInvoke(rest, "execute");
47
+ if (subcommand === "debug")
48
+ return runToolInvoke(rest, "debug");
34
49
  return Promise.resolve(-1);
35
50
  };
36
51
  try {
@@ -206,3 +221,158 @@ async function runToolStatus(args, status) {
206
221
  console.error(`${status === "enabled" ? "Enabled" : "Disabled"} ${opts.toolIds.length} tool(s) in toolbox ${opts.boxId}`);
207
222
  return 0;
208
223
  }
224
+ function parseJsonOption(name, raw) {
225
+ let value;
226
+ try {
227
+ value = JSON.parse(raw);
228
+ }
229
+ catch (e) {
230
+ throw new Error(`${name} must be valid JSON: ${e.message}`);
231
+ }
232
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
233
+ throw new Error(`${name} must be a JSON object`);
234
+ }
235
+ return value;
236
+ }
237
+ export function parseToolInvokeArgs(args) {
238
+ let boxId = "";
239
+ let toolId = "";
240
+ let businessDomain = "";
241
+ let pretty = true;
242
+ let header;
243
+ let query;
244
+ let body;
245
+ let bodyProvided = false;
246
+ let bodyFile;
247
+ let timeout;
248
+ for (let i = 0; i < args.length; i += 1) {
249
+ const a = args[i];
250
+ if (a === "--toolbox" && args[i + 1]) {
251
+ boxId = args[++i];
252
+ continue;
253
+ }
254
+ if (a === "--header" && args[i + 1]) {
255
+ header = parseJsonOption("--header", args[++i]);
256
+ continue;
257
+ }
258
+ if (a === "--query" && args[i + 1]) {
259
+ query = parseJsonOption("--query", args[++i]);
260
+ continue;
261
+ }
262
+ if (a === "--body" && args[i + 1]) {
263
+ const raw = args[++i];
264
+ try {
265
+ body = JSON.parse(raw);
266
+ }
267
+ catch (e) {
268
+ throw new Error(`--body must be valid JSON: ${e.message}`);
269
+ }
270
+ bodyProvided = true;
271
+ continue;
272
+ }
273
+ if (a === "--body-file" && args[i + 1]) {
274
+ bodyFile = args[++i];
275
+ bodyProvided = true;
276
+ continue;
277
+ }
278
+ if (a === "--timeout" && args[i + 1]) {
279
+ const t = Number(args[++i]);
280
+ if (!Number.isFinite(t) || t <= 0)
281
+ throw new Error("--timeout must be a positive number");
282
+ timeout = t;
283
+ continue;
284
+ }
285
+ if ((a === "-bd" || a === "--biz-domain") && args[i + 1]) {
286
+ businessDomain = args[++i];
287
+ continue;
288
+ }
289
+ if (a === "--pretty") {
290
+ pretty = true;
291
+ continue;
292
+ }
293
+ if (a === "--compact") {
294
+ pretty = false;
295
+ continue;
296
+ }
297
+ if (!a.startsWith("-") && !toolId) {
298
+ toolId = a;
299
+ continue;
300
+ }
301
+ }
302
+ if (!boxId)
303
+ throw new Error("Missing required flag: --toolbox");
304
+ if (!toolId)
305
+ throw new Error("Missing required positional argument: <tool-id>");
306
+ if (bodyFile && body !== undefined)
307
+ throw new Error("--body and --body-file are mutually exclusive");
308
+ if (!businessDomain)
309
+ businessDomain = resolveBusinessDomain();
310
+ return {
311
+ boxId,
312
+ toolId,
313
+ header,
314
+ query,
315
+ body: bodyProvided ? body : undefined,
316
+ bodyFile,
317
+ timeout,
318
+ businessDomain,
319
+ pretty,
320
+ };
321
+ }
322
+ async function loadBodyFile(path) {
323
+ let raw;
324
+ try {
325
+ raw = await readFile(path, "utf8");
326
+ }
327
+ catch (e) {
328
+ throw new Error(`Cannot read --body-file ${path}: ${e.message}`);
329
+ }
330
+ try {
331
+ return JSON.parse(raw);
332
+ }
333
+ catch (e) {
334
+ throw new Error(`--body-file ${path} is not valid JSON: ${e.message}`);
335
+ }
336
+ }
337
+ async function runToolInvoke(args, action) {
338
+ let opts;
339
+ try {
340
+ opts = parseToolInvokeArgs(args);
341
+ }
342
+ catch (e) {
343
+ console.error(e instanceof Error ? e.message : String(e));
344
+ return 1;
345
+ }
346
+ let body = opts.body;
347
+ if (opts.bodyFile !== undefined) {
348
+ try {
349
+ body = await loadBodyFile(opts.bodyFile);
350
+ }
351
+ catch (e) {
352
+ console.error(e instanceof Error ? e.message : String(e));
353
+ return 1;
354
+ }
355
+ }
356
+ const token = await ensureValidToken();
357
+ // Auto-inject Authorization unless caller already provided one — most tools
358
+ // declare an `Authorization` header parameter and would otherwise be called
359
+ // anonymously, which the downstream tool answers with 401 token expired.
360
+ const header = { ...(opts.header ?? {}) };
361
+ const hasAuth = Object.keys(header).some((k) => k.toLowerCase() === "authorization");
362
+ if (!hasAuth)
363
+ header.Authorization = `Bearer ${token.accessToken}`;
364
+ const fn = action === "execute" ? executeTool : debugTool;
365
+ const responseBody = await fn({
366
+ baseUrl: token.baseUrl,
367
+ accessToken: token.accessToken,
368
+ businessDomain: opts.businessDomain,
369
+ boxId: opts.boxId,
370
+ toolId: opts.toolId,
371
+ header,
372
+ query: opts.query,
373
+ body,
374
+ timeout: opts.timeout,
375
+ });
376
+ console.log(formatCallOutput(responseBody, opts.pretty));
377
+ return 0;
378
+ }
package/dist/index.d.ts CHANGED
@@ -50,6 +50,8 @@ export { BknResource } from "./resources/bkn.js";
50
50
  export { ConversationsResource } from "./resources/conversations.js";
51
51
  export { ContextLoaderResource } from "./resources/context-loader.js";
52
52
  export { SkillsResource } from "./resources/skills.js";
53
+ export { ToolboxesResource } from "./resources/toolboxes.js";
54
+ export type { InvokeToolArgs } from "./resources/toolboxes.js";
53
55
  export type { SkillStatus, SkillSummary, SkillInfo, SkillFileSummary, SkillContentIndex, SkillFileReadResult, RegisterSkillResult, DeleteSkillResult, UpdateSkillStatusResult, SkillListResult, ListSkillsOptions, ListSkillMarketOptions, GetSkillOptions, RegisterSkillContentOptions, RegisterSkillZipOptions, UpdateSkillStatusOptions, ReadSkillFileOptions, DownloadSkillOptions, DownloadedSkillArchive, } from "./api/skills.js";
54
56
  export { listSkills, listSkillMarket, getSkill, deleteSkill, updateSkillStatus, registerSkillContent, registerSkillZip, getSkillContentIndex, fetchSkillContent, readSkillFile, fetchSkillFile, downloadSkill, installSkillArchive, } from "./api/skills.js";
55
57
  export type { ViewField, DataView, CreateDataViewOptions, GetDataViewOptions, ListDataViewsOptions, DeleteDataViewOptions, FindDataViewOptions, QueryDataViewOptions, DataViewQueryResult, } from "./api/dataviews.js";
@@ -57,6 +59,8 @@ export { parseDataView, createDataView, getDataView, listDataViews, deleteDataVi
57
59
  export { DataViewsResource } from "./resources/dataviews.js";
58
60
  export type { BusinessDomain, ListBusinessDomainsOptions } from "./api/business-domains.js";
59
61
  export { listBusinessDomains } from "./api/business-domains.js";
62
+ export type { CreateToolboxOptions, DeleteToolboxOptions, SetToolboxStatusOptions, UploadToolOptions, SetToolStatusesOptions, ListToolboxesOptions, ListToolsOptions, InvokeToolOptions, } from "./api/toolboxes.js";
63
+ export { createToolbox, deleteToolbox, setToolboxStatus, uploadTool, setToolStatuses, listToolboxes, listTools, executeTool, debugTool, } from "./api/toolboxes.js";
60
64
  export { HttpError, NetworkRequestError, fetchTextOrThrow } from "./utils/http.js";
61
65
  export type { TokenConfig, ContextLoaderEntry, ContextLoaderConfig, } from "./config/store.js";
62
66
  export type { UserProfile } from "./config/store.js";
package/dist/index.js CHANGED
@@ -40,10 +40,12 @@ export { BknResource } from "./resources/bkn.js";
40
40
  export { ConversationsResource } from "./resources/conversations.js";
41
41
  export { ContextLoaderResource } from "./resources/context-loader.js";
42
42
  export { SkillsResource } from "./resources/skills.js";
43
+ export { ToolboxesResource } from "./resources/toolboxes.js";
43
44
  export { listSkills, listSkillMarket, getSkill, deleteSkill, updateSkillStatus, registerSkillContent, registerSkillZip, getSkillContentIndex, fetchSkillContent, readSkillFile, fetchSkillFile, downloadSkill, installSkillArchive, } from "./api/skills.js";
44
45
  export { parseDataView, createDataView, getDataView, listDataViews, deleteDataView, findDataView, queryDataView, } from "./api/dataviews.js";
45
46
  export { DataViewsResource } from "./resources/dataviews.js";
46
47
  export { listBusinessDomains } from "./api/business-domains.js";
48
+ export { createToolbox, deleteToolbox, setToolboxStatus, uploadTool, setToolStatuses, listToolboxes, listTools, executeTool, debugTool, } from "./api/toolboxes.js";
47
49
  // ── HTTP utilities ────────────────────────────────────────────────────────────
48
50
  export { HttpError, NetworkRequestError, fetchTextOrThrow } from "./utils/http.js";
49
51
  export { NO_AUTH_TOKEN, isNoAuth, saveNoAuthPlatform, autoSelectBusinessDomain, getConfigDir, getCurrentPlatform, getActiveUser, setActiveUser, listUsers, listUserProfiles, resolveUserId, extractUserId, } from "./config/store.js";
@@ -11,11 +11,25 @@ export class AgentsResource {
11
11
  const { keyword, ...rest } = opts;
12
12
  const raw = await listAgents({ ...this.ctx.base(), name: keyword, ...rest });
13
13
  const parsed = JSON.parse(raw);
14
- const items = parsed && typeof parsed === "object" && "data" in parsed
15
- ? parsed.data?.records ?? []
16
- : Array.isArray(parsed)
17
- ? parsed
18
- : [];
14
+ const items = (() => {
15
+ if (Array.isArray(parsed))
16
+ return parsed;
17
+ if (!parsed || typeof parsed !== "object")
18
+ return [];
19
+ const obj = parsed;
20
+ if (Array.isArray(obj.entries))
21
+ return obj.entries;
22
+ if (Array.isArray(obj.data))
23
+ return obj.data;
24
+ if (obj.data && typeof obj.data === "object") {
25
+ const dataObj = obj.data;
26
+ if (Array.isArray(dataObj.records))
27
+ return dataObj.records;
28
+ if (Array.isArray(dataObj.entries))
29
+ return dataObj.entries;
30
+ }
31
+ return [];
32
+ })();
19
33
  return items;
20
34
  }
21
35
  // ── Get by ID ────────────────────────────────────────────────────────────
@@ -0,0 +1,39 @@
1
+ import type { ClientContext } from "../client.js";
2
+ export interface InvokeToolArgs {
3
+ /** Optional headers to forward to the downstream tool. Authorization is
4
+ * auto-injected from the client's access token when omitted; pass `{}` to
5
+ * send no headers. */
6
+ header?: Record<string, unknown>;
7
+ query?: Record<string, unknown>;
8
+ body?: unknown;
9
+ /** Per-call timeout in seconds (backend default applies when omitted). */
10
+ timeout?: number;
11
+ }
12
+ /** Toolbox / tool management on the agent-operator-integration service. */
13
+ export declare class ToolboxesResource {
14
+ private readonly ctx;
15
+ constructor(ctx: ClientContext);
16
+ list(opts?: {
17
+ keyword?: string;
18
+ limit?: number;
19
+ offset?: number;
20
+ }): Promise<string>;
21
+ listToolsIn(boxId: string): Promise<string>;
22
+ uploadTool(opts: {
23
+ boxId: string;
24
+ filePath: string;
25
+ metadataType?: "openapi";
26
+ }): Promise<string>;
27
+ setToolStatuses(opts: {
28
+ boxId: string;
29
+ updates: Array<{
30
+ toolId: string;
31
+ status: "enabled" | "disabled";
32
+ }>;
33
+ }): Promise<void>;
34
+ /** Execute a published+enabled tool through the toolbox proxy. */
35
+ execute(boxId: string, toolId: string, args?: InvokeToolArgs): Promise<string>;
36
+ /** Debug a tool through the toolbox proxy (works on draft/disabled tools too). */
37
+ debug(boxId: string, toolId: string, args?: InvokeToolArgs): Promise<string>;
38
+ private injectAuth;
39
+ }
@@ -0,0 +1,54 @@
1
+ import { debugTool, executeTool, listTools, listToolboxes, setToolStatuses, uploadTool, } from "../api/toolboxes.js";
2
+ /** Toolbox / tool management on the agent-operator-integration service. */
3
+ export class ToolboxesResource {
4
+ ctx;
5
+ constructor(ctx) {
6
+ this.ctx = ctx;
7
+ }
8
+ async list(opts = {}) {
9
+ return listToolboxes({ ...this.ctx.base(), ...opts });
10
+ }
11
+ async listToolsIn(boxId) {
12
+ return listTools({ ...this.ctx.base(), boxId });
13
+ }
14
+ async uploadTool(opts) {
15
+ return uploadTool({
16
+ ...this.ctx.base(),
17
+ boxId: opts.boxId,
18
+ filePath: opts.filePath,
19
+ metadataType: opts.metadataType,
20
+ });
21
+ }
22
+ async setToolStatuses(opts) {
23
+ await setToolStatuses({ ...this.ctx.base(), ...opts });
24
+ }
25
+ /** Execute a published+enabled tool through the toolbox proxy. */
26
+ async execute(boxId, toolId, args = {}) {
27
+ return executeTool({
28
+ ...this.ctx.base(),
29
+ boxId,
30
+ toolId,
31
+ ...this.injectAuth(args),
32
+ });
33
+ }
34
+ /** Debug a tool through the toolbox proxy (works on draft/disabled tools too). */
35
+ async debug(boxId, toolId, args = {}) {
36
+ return debugTool({
37
+ ...this.ctx.base(),
38
+ boxId,
39
+ toolId,
40
+ ...this.injectAuth(args),
41
+ });
42
+ }
43
+ // The forwarder requires every header the downstream tool expects to be set
44
+ // explicitly under `header`; most published tools declare an Authorization
45
+ // parameter and would otherwise see no token. Auto-inject the active
46
+ // session token unless the caller already provided one.
47
+ injectAuth(args) {
48
+ const header = { ...(args.header ?? {}) };
49
+ const hasAuth = Object.keys(header).some((k) => k.toLowerCase() === "authorization");
50
+ if (!hasAuth)
51
+ header.Authorization = `Bearer ${this.ctx.base().accessToken}`;
52
+ return { ...args, header };
53
+ }
54
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kweaver-ai/kweaver-sdk",
3
- "version": "0.6.8",
3
+ "version": "0.6.10",
4
4
  "description": "KWeaver TypeScript SDK — CLI tool and programmatic API for knowledge networks and Decision Agents.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",