@kweaver-ai/kweaver-sdk 0.7.2 → 0.7.4
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 +35 -1
- package/README.zh.md +26 -0
- package/bin/kweaver.js +12 -11
- package/dist/api/bkn-backend.d.ts +1 -0
- package/dist/api/bkn-backend.js +1 -1
- package/dist/api/bkn-metrics.d.ts +59 -0
- package/dist/api/bkn-metrics.js +129 -0
- package/dist/api/conversations.d.ts +47 -2
- package/dist/api/conversations.js +113 -17
- package/dist/api/datasources.d.ts +7 -0
- package/dist/api/datasources.js +51 -6
- package/dist/api/model-invocation.d.ts +58 -0
- package/dist/api/model-invocation.js +203 -0
- package/dist/api/models.d.ts +79 -0
- package/dist/api/models.js +183 -0
- package/dist/api/ontology-query-metrics.d.ts +14 -0
- package/dist/api/ontology-query-metrics.js +30 -0
- package/dist/api/toolboxes.d.ts +2 -0
- package/dist/api/toolboxes.js +2 -1
- package/dist/bundled-model-templates.d.ts +17 -0
- package/dist/bundled-model-templates.js +24 -0
- package/dist/cli.js +28 -2
- package/dist/client.d.ts +3 -0
- package/dist/client.js +5 -0
- package/dist/commands/agent.d.ts +7 -1
- package/dist/commands/agent.js +75 -21
- package/dist/commands/auth.js +42 -7
- package/dist/commands/bkn-metric.d.ts +1 -0
- package/dist/commands/bkn-metric.js +406 -0
- package/dist/commands/bkn-ops.d.ts +2 -1
- package/dist/commands/bkn-ops.js +75 -34
- package/dist/commands/bkn-utils.d.ts +55 -2
- package/dist/commands/bkn-utils.js +103 -9
- package/dist/commands/bkn.js +4 -0
- package/dist/commands/dataflow.js +194 -20
- package/dist/commands/ds.d.ts +0 -1
- package/dist/commands/ds.js +26 -10
- package/dist/commands/explore-chat.js +2 -2
- package/dist/commands/import-csv.d.ts +0 -2
- package/dist/commands/import-csv.js +2 -4
- package/dist/commands/model.d.ts +72 -0
- package/dist/commands/model.js +1315 -0
- package/dist/commands/tool.d.ts +1 -0
- package/dist/commands/tool.js +12 -0
- package/dist/config/store.d.ts +1 -0
- package/dist/config/store.js +17 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +5 -0
- package/dist/resources/models.d.ts +40 -0
- package/dist/resources/models.js +88 -0
- package/dist/resources/toolboxes.d.ts +2 -0
- package/dist/templates/bkn/document/manifest.json +12 -0
- package/dist/templates/bkn/document/template.json +757 -0
- package/dist/templates/dataflow/unstructured/manifest.json +11 -0
- package/dist/templates/dataflow/unstructured/template.json +63 -0
- package/dist/templates/dataset/document/manifest.json +10 -0
- package/dist/templates/dataset/document/template.json +23 -0
- package/dist/templates/dataset/document-content/manifest.json +10 -0
- package/dist/templates/dataset/document-content/template.json +29 -0
- package/dist/templates/dataset/document-element/manifest.json +10 -0
- package/dist/templates/dataset/document-element/template.json +21 -0
- package/dist/templates/model/llm-basic.json +13 -0
- package/dist/templates/model/manifest.json +16 -0
- package/dist/templates/model/small-basic.json +6 -0
- package/dist/utils/template-loader.d.ts +40 -0
- package/dist/utils/template-loader.js +129 -0
- package/dist/utils/trace-views.d.ts +44 -0
- package/dist/utils/trace-views.js +425 -0
- package/package.json +3 -3
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export declare const MF_MODEL_API_PATH_PREFIX = "/api/mf-model-api/v1";
|
|
2
|
+
export interface MfApiBaseOptions {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
accessToken: string;
|
|
5
|
+
businessDomain?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Replace platform origin for mf-model-api (still appends `/api/mf-model-api/v1`).
|
|
8
|
+
* Overrides `KWEAVER_MF_MODEL_API_URL` when set.
|
|
9
|
+
*/
|
|
10
|
+
mfApiBaseUrl?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ChatMessage {
|
|
13
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
14
|
+
content: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ModelChatCompletionsOptions extends MfApiBaseOptions {
|
|
17
|
+
/** Platform LLM config id (snowflake); always sent as `model_id`. */
|
|
18
|
+
modelId: string;
|
|
19
|
+
/**
|
|
20
|
+
* Registry **`model_name`** for the OpenAI-style **`model`** field in the request body.
|
|
21
|
+
* When omitted, **`model`** defaults to **`modelId`** (historical CLI behaviour).
|
|
22
|
+
* Some gateways resolve routing via display name and reject numeric-only **`model`**.
|
|
23
|
+
*/
|
|
24
|
+
modelName?: string;
|
|
25
|
+
messages: ChatMessage[];
|
|
26
|
+
stream?: boolean;
|
|
27
|
+
temperature?: number;
|
|
28
|
+
maxTokens?: number;
|
|
29
|
+
topP?: number;
|
|
30
|
+
topK?: number;
|
|
31
|
+
presencePenalty?: number;
|
|
32
|
+
frequencyPenalty?: number;
|
|
33
|
+
cache?: boolean;
|
|
34
|
+
verbose?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface ModelChatResult {
|
|
37
|
+
text: string;
|
|
38
|
+
raw?: unknown;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Consume an OpenAI-style SSE stream (`data: {...}` / `data: [DONE]`).
|
|
42
|
+
*/
|
|
43
|
+
export declare function consumeOpenAiSseText(response: Response, verbose?: boolean): Promise<string>;
|
|
44
|
+
export declare function modelChatCompletions(options: ModelChatCompletionsOptions): Promise<ModelChatResult>;
|
|
45
|
+
export interface ModelEmbeddingOptions extends MfApiBaseOptions {
|
|
46
|
+
modelId?: string;
|
|
47
|
+
modelName?: string;
|
|
48
|
+
input: string[];
|
|
49
|
+
}
|
|
50
|
+
export declare function modelEmbedding(options: ModelEmbeddingOptions): Promise<unknown>;
|
|
51
|
+
export declare function modelEmbeddings(options: ModelEmbeddingOptions): Promise<unknown>;
|
|
52
|
+
export interface ModelRerankOptions extends MfApiBaseOptions {
|
|
53
|
+
modelId?: string;
|
|
54
|
+
modelName?: string;
|
|
55
|
+
query: string;
|
|
56
|
+
documents: string[];
|
|
57
|
+
}
|
|
58
|
+
export declare function modelRerank(options: ModelRerankOptions): Promise<unknown>;
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { buildHeaders } from "./headers.js";
|
|
2
|
+
import { HttpError } from "../utils/http.js";
|
|
3
|
+
export const MF_MODEL_API_PATH_PREFIX = "/api/mf-model-api/v1";
|
|
4
|
+
function resolveApiOrigin(options) {
|
|
5
|
+
const env = process.env.KWEAVER_MF_MODEL_API_URL;
|
|
6
|
+
const raw = options.mfApiBaseUrl ?? (env && env.length > 0 ? env : undefined) ?? options.baseUrl;
|
|
7
|
+
return raw.replace(/\/+$/, "");
|
|
8
|
+
}
|
|
9
|
+
function apiEndpoint(options, relPath) {
|
|
10
|
+
const origin = resolveApiOrigin(options);
|
|
11
|
+
const path = relPath.startsWith("/") ? relPath : `/${relPath}`;
|
|
12
|
+
return `${origin}${MF_MODEL_API_PATH_PREFIX}${path}`;
|
|
13
|
+
}
|
|
14
|
+
function buildChatBody(options) {
|
|
15
|
+
const { modelId, modelName, messages, stream = false, temperature, maxTokens, topP, topK, presencePenalty, frequencyPenalty, cache, } = options;
|
|
16
|
+
const trimmedName = typeof modelName === "string" ? modelName.trim() : "";
|
|
17
|
+
const modelField = trimmedName.length > 0 ? trimmedName : modelId;
|
|
18
|
+
const body = {
|
|
19
|
+
model: modelField,
|
|
20
|
+
model_id: modelId,
|
|
21
|
+
messages,
|
|
22
|
+
stream,
|
|
23
|
+
};
|
|
24
|
+
if (temperature !== undefined)
|
|
25
|
+
body.temperature = temperature;
|
|
26
|
+
if (maxTokens !== undefined)
|
|
27
|
+
body.max_tokens = maxTokens;
|
|
28
|
+
if (topP !== undefined)
|
|
29
|
+
body.top_p = topP;
|
|
30
|
+
if (topK !== undefined)
|
|
31
|
+
body.top_k = topK;
|
|
32
|
+
if (presencePenalty !== undefined)
|
|
33
|
+
body.presence_penalty = presencePenalty;
|
|
34
|
+
if (frequencyPenalty !== undefined)
|
|
35
|
+
body.frequency_penalty = frequencyPenalty;
|
|
36
|
+
if (cache !== undefined)
|
|
37
|
+
body.cache = cache;
|
|
38
|
+
return body;
|
|
39
|
+
}
|
|
40
|
+
function extractOpenAiCompletionText(json) {
|
|
41
|
+
const choices = json.choices;
|
|
42
|
+
const msg = choices?.[0]?.message;
|
|
43
|
+
const content = msg?.content;
|
|
44
|
+
if (typeof content === "string")
|
|
45
|
+
return content;
|
|
46
|
+
return "";
|
|
47
|
+
}
|
|
48
|
+
function extractOpenAiDeltaChunk(chunk) {
|
|
49
|
+
const choices = chunk.choices;
|
|
50
|
+
if (!choices?.[0])
|
|
51
|
+
return "";
|
|
52
|
+
const delta = choices[0].delta;
|
|
53
|
+
const c = delta?.content;
|
|
54
|
+
if (typeof c === "string")
|
|
55
|
+
return c;
|
|
56
|
+
return "";
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Consume an OpenAI-style SSE stream (`data: {...}` / `data: [DONE]`).
|
|
60
|
+
*/
|
|
61
|
+
export async function consumeOpenAiSseText(response, verbose) {
|
|
62
|
+
const reader = response.body?.getReader();
|
|
63
|
+
if (!reader)
|
|
64
|
+
throw new Error("No response body for stream");
|
|
65
|
+
const decoder = new TextDecoder();
|
|
66
|
+
let buffer = "";
|
|
67
|
+
let out = "";
|
|
68
|
+
const processLine = (line) => {
|
|
69
|
+
const trimmed = line.trimEnd();
|
|
70
|
+
if (!trimmed.startsWith("data:"))
|
|
71
|
+
return;
|
|
72
|
+
const payload = trimmed.slice(5).trim();
|
|
73
|
+
if (payload === "[DONE]")
|
|
74
|
+
return;
|
|
75
|
+
try {
|
|
76
|
+
const chunk = JSON.parse(payload);
|
|
77
|
+
out += extractOpenAiDeltaChunk(chunk);
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
if (verbose) {
|
|
81
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
82
|
+
console.error(`SSE parse skip: ${msg} payload=${payload.slice(0, 120)}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
while (true) {
|
|
87
|
+
const { done, value } = await reader.read();
|
|
88
|
+
if (done)
|
|
89
|
+
break;
|
|
90
|
+
buffer += decoder.decode(value, { stream: true });
|
|
91
|
+
const lines = buffer.split("\n");
|
|
92
|
+
buffer = lines.pop() ?? "";
|
|
93
|
+
for (const ln of lines) {
|
|
94
|
+
processLine(ln);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (buffer.trim())
|
|
98
|
+
processLine(buffer);
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
export async function modelChatCompletions(options) {
|
|
102
|
+
const { accessToken, businessDomain = "bd_public", stream = false, verbose } = options;
|
|
103
|
+
const url = apiEndpoint(options, "/chat/completions");
|
|
104
|
+
const body = buildChatBody({ ...options, stream });
|
|
105
|
+
const response = await fetch(url, {
|
|
106
|
+
method: "POST",
|
|
107
|
+
headers: {
|
|
108
|
+
...buildHeaders(accessToken, businessDomain),
|
|
109
|
+
"content-type": "application/json",
|
|
110
|
+
accept: stream ? "text/event-stream" : "application/json",
|
|
111
|
+
},
|
|
112
|
+
body: JSON.stringify(body),
|
|
113
|
+
});
|
|
114
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
115
|
+
if (!response.ok) {
|
|
116
|
+
const text = await response.text();
|
|
117
|
+
throw new HttpError(response.status, response.statusText, text);
|
|
118
|
+
}
|
|
119
|
+
if (stream && contentType.includes("text/event-stream")) {
|
|
120
|
+
const text = await consumeOpenAiSseText(response, verbose);
|
|
121
|
+
return { text };
|
|
122
|
+
}
|
|
123
|
+
const text = await response.text();
|
|
124
|
+
const json = JSON.parse(text);
|
|
125
|
+
return { text: extractOpenAiCompletionText(json), raw: json };
|
|
126
|
+
}
|
|
127
|
+
// ── Small model invocation (mf-model-api) ───────────────────────────────────
|
|
128
|
+
/** OpenAI-style **`model`** for small-model routes: registry name when set, else **`model_id`** (matches chat completions). */
|
|
129
|
+
function resolveSmallInvokeModelField(modelName, modelId) {
|
|
130
|
+
const trimmedName = typeof modelName === "string" ? modelName.trim() : "";
|
|
131
|
+
if (trimmedName.length > 0)
|
|
132
|
+
return trimmedName;
|
|
133
|
+
const id = typeof modelId === "string" ? modelId.trim() : "";
|
|
134
|
+
if (id.length > 0)
|
|
135
|
+
return id;
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
export async function modelEmbedding(options) {
|
|
139
|
+
const { accessToken, businessDomain = "bd_public", modelId, modelName, input } = options;
|
|
140
|
+
const url = apiEndpoint(options, "/small-model/embedding");
|
|
141
|
+
const body = { input };
|
|
142
|
+
if (modelId)
|
|
143
|
+
body.model_id = modelId;
|
|
144
|
+
const modelField = resolveSmallInvokeModelField(modelName, modelId);
|
|
145
|
+
if (modelField !== undefined)
|
|
146
|
+
body.model = modelField;
|
|
147
|
+
const response = await fetch(url, {
|
|
148
|
+
method: "POST",
|
|
149
|
+
headers: {
|
|
150
|
+
...buildHeaders(accessToken, businessDomain),
|
|
151
|
+
"content-type": "application/json",
|
|
152
|
+
},
|
|
153
|
+
body: JSON.stringify(body),
|
|
154
|
+
});
|
|
155
|
+
const text = await response.text();
|
|
156
|
+
if (!response.ok)
|
|
157
|
+
throw new HttpError(response.status, response.statusText, text);
|
|
158
|
+
return text ? JSON.parse(text) : null;
|
|
159
|
+
}
|
|
160
|
+
export async function modelEmbeddings(options) {
|
|
161
|
+
const { accessToken, businessDomain = "bd_public", modelId, modelName, input } = options;
|
|
162
|
+
const url = apiEndpoint(options, "/small-model/embeddings");
|
|
163
|
+
const body = { input };
|
|
164
|
+
if (modelId)
|
|
165
|
+
body.model_id = modelId;
|
|
166
|
+
const modelField = resolveSmallInvokeModelField(modelName, modelId);
|
|
167
|
+
if (modelField !== undefined)
|
|
168
|
+
body.model = modelField;
|
|
169
|
+
const response = await fetch(url, {
|
|
170
|
+
method: "POST",
|
|
171
|
+
headers: {
|
|
172
|
+
...buildHeaders(accessToken, businessDomain),
|
|
173
|
+
"content-type": "application/json",
|
|
174
|
+
},
|
|
175
|
+
body: JSON.stringify(body),
|
|
176
|
+
});
|
|
177
|
+
const text = await response.text();
|
|
178
|
+
if (!response.ok)
|
|
179
|
+
throw new HttpError(response.status, response.statusText, text);
|
|
180
|
+
return text ? JSON.parse(text) : null;
|
|
181
|
+
}
|
|
182
|
+
export async function modelRerank(options) {
|
|
183
|
+
const { accessToken, businessDomain = "bd_public", modelId, modelName, query, documents } = options;
|
|
184
|
+
const url = apiEndpoint(options, "/small-model/reranker");
|
|
185
|
+
const body = { query, documents };
|
|
186
|
+
if (modelId)
|
|
187
|
+
body.model_id = modelId;
|
|
188
|
+
const modelField = resolveSmallInvokeModelField(modelName, modelId);
|
|
189
|
+
if (modelField !== undefined)
|
|
190
|
+
body.model = modelField;
|
|
191
|
+
const response = await fetch(url, {
|
|
192
|
+
method: "POST",
|
|
193
|
+
headers: {
|
|
194
|
+
...buildHeaders(accessToken, businessDomain),
|
|
195
|
+
"content-type": "application/json",
|
|
196
|
+
},
|
|
197
|
+
body: JSON.stringify(body),
|
|
198
|
+
});
|
|
199
|
+
const text = await response.text();
|
|
200
|
+
if (!response.ok)
|
|
201
|
+
throw new HttpError(response.status, response.statusText, text);
|
|
202
|
+
return text ? JSON.parse(text) : null;
|
|
203
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export declare const MF_MODEL_MANAGER_PATH_PREFIX = "/api/mf-model-manager/v1";
|
|
2
|
+
export interface MfManagerBaseOptions {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
accessToken: string;
|
|
5
|
+
businessDomain?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Replace platform origin for mf-model-manager (still appends `/api/mf-model-manager/v1`).
|
|
8
|
+
* Overrides `KWEAVER_MF_MODEL_MANAGER_URL` when set.
|
|
9
|
+
*/
|
|
10
|
+
mfManagerBaseUrl?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Ensure small-model request bodies do not combine direct `model_config` with adapter mode.
|
|
14
|
+
*/
|
|
15
|
+
export declare function assertSmallModelConfigAdapterExclusive(body: Record<string, unknown>): void;
|
|
16
|
+
/** For edit: validate mutual exclusion only when config or adapter fields are present. */
|
|
17
|
+
export declare function assertSmallModelEditBody(body: Record<string, unknown>): void;
|
|
18
|
+
export interface ListLlmModelsOptions extends MfManagerBaseOptions {
|
|
19
|
+
page: number;
|
|
20
|
+
size: number;
|
|
21
|
+
order?: string;
|
|
22
|
+
rule?: string;
|
|
23
|
+
series?: string;
|
|
24
|
+
name?: string;
|
|
25
|
+
apiModel?: string;
|
|
26
|
+
modelType?: string;
|
|
27
|
+
quota?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function listLlmModels(options: ListLlmModelsOptions): Promise<unknown>;
|
|
30
|
+
export interface GetLlmModelOptions extends MfManagerBaseOptions {
|
|
31
|
+
modelId: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function getLlmModel(options: GetLlmModelOptions): Promise<unknown>;
|
|
34
|
+
export interface AddLlmModelOptions extends MfManagerBaseOptions {
|
|
35
|
+
body: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
export declare function addLlmModel(options: AddLlmModelOptions): Promise<unknown>;
|
|
38
|
+
export interface EditLlmModelOptions extends MfManagerBaseOptions {
|
|
39
|
+
body: Record<string, unknown>;
|
|
40
|
+
}
|
|
41
|
+
export declare function editLlmModel(options: EditLlmModelOptions): Promise<unknown>;
|
|
42
|
+
export interface DeleteLlmModelsOptions extends MfManagerBaseOptions {
|
|
43
|
+
modelIds: string[];
|
|
44
|
+
}
|
|
45
|
+
export declare function deleteLlmModels(options: DeleteLlmModelsOptions): Promise<unknown>;
|
|
46
|
+
export interface TestLlmModelOptions extends MfManagerBaseOptions {
|
|
47
|
+
body: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
export declare function testLlmModel(options: TestLlmModelOptions): Promise<unknown>;
|
|
50
|
+
export interface ListSmallModelsOptions extends MfManagerBaseOptions {
|
|
51
|
+
page: number;
|
|
52
|
+
size: number;
|
|
53
|
+
order?: string;
|
|
54
|
+
rule?: string;
|
|
55
|
+
modelName?: string;
|
|
56
|
+
modelType?: string;
|
|
57
|
+
modelSeries?: string;
|
|
58
|
+
}
|
|
59
|
+
export declare function listSmallModels(options: ListSmallModelsOptions): Promise<unknown>;
|
|
60
|
+
export interface GetSmallModelOptions extends MfManagerBaseOptions {
|
|
61
|
+
modelId: string;
|
|
62
|
+
}
|
|
63
|
+
export declare function getSmallModel(options: GetSmallModelOptions): Promise<unknown>;
|
|
64
|
+
export interface AddSmallModelOptions extends MfManagerBaseOptions {
|
|
65
|
+
body: Record<string, unknown>;
|
|
66
|
+
}
|
|
67
|
+
export declare function addSmallModel(options: AddSmallModelOptions): Promise<unknown>;
|
|
68
|
+
export interface EditSmallModelOptions extends MfManagerBaseOptions {
|
|
69
|
+
body: Record<string, unknown>;
|
|
70
|
+
}
|
|
71
|
+
export declare function editSmallModel(options: EditSmallModelOptions): Promise<unknown>;
|
|
72
|
+
export interface DeleteSmallModelsOptions extends MfManagerBaseOptions {
|
|
73
|
+
modelIds: string[];
|
|
74
|
+
}
|
|
75
|
+
export declare function deleteSmallModels(options: DeleteSmallModelsOptions): Promise<unknown>;
|
|
76
|
+
export interface TestSmallModelOptions extends MfManagerBaseOptions {
|
|
77
|
+
body: Record<string, unknown>;
|
|
78
|
+
}
|
|
79
|
+
export declare function testSmallModel(options: TestSmallModelOptions): Promise<unknown>;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { buildHeaders } from "./headers.js";
|
|
2
|
+
import { HttpError } from "../utils/http.js";
|
|
3
|
+
export const MF_MODEL_MANAGER_PATH_PREFIX = "/api/mf-model-manager/v1";
|
|
4
|
+
function resolveManagerOrigin(options) {
|
|
5
|
+
const env = process.env.KWEAVER_MF_MODEL_MANAGER_URL;
|
|
6
|
+
const raw = options.mfManagerBaseUrl ?? (env && env.length > 0 ? env : undefined) ?? options.baseUrl;
|
|
7
|
+
return raw.replace(/\/+$/, "");
|
|
8
|
+
}
|
|
9
|
+
function managerEndpoint(options, relPath) {
|
|
10
|
+
const origin = resolveManagerOrigin(options);
|
|
11
|
+
const path = relPath.startsWith("/") ? relPath : `/${relPath}`;
|
|
12
|
+
return `${origin}${MF_MODEL_MANAGER_PATH_PREFIX}${path}`;
|
|
13
|
+
}
|
|
14
|
+
async function fetchJson(url, accessToken, businessDomain, init) {
|
|
15
|
+
const headers = {
|
|
16
|
+
...buildHeaders(accessToken, businessDomain),
|
|
17
|
+
...(init.headers ?? {}),
|
|
18
|
+
};
|
|
19
|
+
const response = await fetch(url, { ...init, headers });
|
|
20
|
+
const text = await response.text();
|
|
21
|
+
if (!response.ok) {
|
|
22
|
+
throw new HttpError(response.status, response.statusText, text);
|
|
23
|
+
}
|
|
24
|
+
if (!text.trim())
|
|
25
|
+
return null;
|
|
26
|
+
return JSON.parse(text);
|
|
27
|
+
}
|
|
28
|
+
// ── Client-side validation (mirrors mf-model-manager mutual exclusion) ─────
|
|
29
|
+
/**
|
|
30
|
+
* Ensure small-model request bodies do not combine direct `model_config` with adapter mode.
|
|
31
|
+
*/
|
|
32
|
+
export function assertSmallModelConfigAdapterExclusive(body) {
|
|
33
|
+
const cfg = body.model_config;
|
|
34
|
+
const hasConfig = cfg != null &&
|
|
35
|
+
typeof cfg === "object" &&
|
|
36
|
+
!Array.isArray(cfg) &&
|
|
37
|
+
Object.keys(cfg).length > 0;
|
|
38
|
+
const adapter = body.adapter === true;
|
|
39
|
+
const code = typeof body.adapter_code === "string" && body.adapter_code.length > 0;
|
|
40
|
+
if (hasConfig && (adapter
|
|
41
|
+
|| code)) {
|
|
42
|
+
throw new Error("model_config cannot be combined with adapter or adapter_code.");
|
|
43
|
+
}
|
|
44
|
+
if (!hasConfig && (!adapter
|
|
45
|
+
|| !code)) {
|
|
46
|
+
throw new Error("Either model_config (non-empty) or adapter=true with adapter_code is required.");
|
|
47
|
+
}
|
|
48
|
+
if (adapter && !code) {
|
|
49
|
+
throw new Error("adapter=true requires adapter_code.");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** For edit: validate mutual exclusion only when config or adapter fields are present. */
|
|
53
|
+
export function assertSmallModelEditBody(body) {
|
|
54
|
+
const cfg = body.model_config;
|
|
55
|
+
const hasConfig = cfg != null &&
|
|
56
|
+
typeof cfg === "object" &&
|
|
57
|
+
!Array.isArray(cfg) &&
|
|
58
|
+
Object.keys(cfg).length > 0;
|
|
59
|
+
const adapter = body.adapter === true;
|
|
60
|
+
const code = typeof body.adapter_code === "string" && body.adapter_code.length > 0;
|
|
61
|
+
if (!hasConfig && !adapter && !code) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
assertSmallModelConfigAdapterExclusive(body);
|
|
65
|
+
}
|
|
66
|
+
export async function listLlmModels(options) {
|
|
67
|
+
const { accessToken, businessDomain = "bd_public", page, size, order = "desc", rule = "update_time", series = "all", name = "", apiModel = "", modelType = "", quota, } = options;
|
|
68
|
+
const params = new URLSearchParams({
|
|
69
|
+
page: String(page),
|
|
70
|
+
size: String(size),
|
|
71
|
+
order,
|
|
72
|
+
rule,
|
|
73
|
+
series,
|
|
74
|
+
name,
|
|
75
|
+
api_model: apiModel,
|
|
76
|
+
model_type: modelType,
|
|
77
|
+
});
|
|
78
|
+
if (quota !== undefined) {
|
|
79
|
+
params.set("quota", String(quota));
|
|
80
|
+
}
|
|
81
|
+
const url = `${managerEndpoint(options, "/llm/list")}?${params.toString()}`;
|
|
82
|
+
return fetchJson(url, accessToken, businessDomain, { method: "GET" });
|
|
83
|
+
}
|
|
84
|
+
export async function getLlmModel(options) {
|
|
85
|
+
const { accessToken, businessDomain = "bd_public", modelId } = options;
|
|
86
|
+
const params = new URLSearchParams({ model_id: modelId });
|
|
87
|
+
const url = `${managerEndpoint(options, "/llm/get")}?${params.toString()}`;
|
|
88
|
+
return fetchJson(url, accessToken, businessDomain, { method: "GET" });
|
|
89
|
+
}
|
|
90
|
+
export async function addLlmModel(options) {
|
|
91
|
+
const { accessToken, businessDomain = "bd_public", body } = options;
|
|
92
|
+
const url = managerEndpoint(options, "/llm/add");
|
|
93
|
+
return fetchJson(url, accessToken, businessDomain, {
|
|
94
|
+
method: "POST",
|
|
95
|
+
headers: { "content-type": "application/json" },
|
|
96
|
+
body: JSON.stringify(body),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
export async function editLlmModel(options) {
|
|
100
|
+
const { accessToken, businessDomain = "bd_public", body } = options;
|
|
101
|
+
const url = managerEndpoint(options, "/llm/edit");
|
|
102
|
+
return fetchJson(url, accessToken, businessDomain, {
|
|
103
|
+
method: "POST",
|
|
104
|
+
headers: { "content-type": "application/json" },
|
|
105
|
+
body: JSON.stringify(body),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
export async function deleteLlmModels(options) {
|
|
109
|
+
const { accessToken, businessDomain = "bd_public", modelIds } = options;
|
|
110
|
+
const url = managerEndpoint(options, "/llm/delete");
|
|
111
|
+
return fetchJson(url, accessToken, businessDomain, {
|
|
112
|
+
method: "POST",
|
|
113
|
+
headers: { "content-type": "application/json" },
|
|
114
|
+
body: JSON.stringify({ model_ids: modelIds }),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
export async function testLlmModel(options) {
|
|
118
|
+
const { accessToken, businessDomain = "bd_public", body } = options;
|
|
119
|
+
const url = managerEndpoint(options, "/llm/test");
|
|
120
|
+
return fetchJson(url, accessToken, businessDomain, {
|
|
121
|
+
method: "POST",
|
|
122
|
+
headers: { "content-type": "application/json" },
|
|
123
|
+
body: JSON.stringify(body),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
export async function listSmallModels(options) {
|
|
127
|
+
const { accessToken, businessDomain = "bd_public", page, size, order = "desc", rule = "update_time", modelName = "", modelType = "", modelSeries = "", } = options;
|
|
128
|
+
const params = new URLSearchParams({
|
|
129
|
+
order,
|
|
130
|
+
rule,
|
|
131
|
+
page: String(page),
|
|
132
|
+
size: String(size),
|
|
133
|
+
model_name: modelName,
|
|
134
|
+
model_type: modelType,
|
|
135
|
+
model_series: modelSeries,
|
|
136
|
+
});
|
|
137
|
+
const url = `${managerEndpoint(options, "/small-model/list")}?${params.toString()}`;
|
|
138
|
+
return fetchJson(url, accessToken, businessDomain, { method: "GET" });
|
|
139
|
+
}
|
|
140
|
+
export async function getSmallModel(options) {
|
|
141
|
+
const { accessToken, businessDomain = "bd_public", modelId } = options;
|
|
142
|
+
const params = new URLSearchParams({ model_id: modelId });
|
|
143
|
+
const url = `${managerEndpoint(options, "/small-model/get")}?${params.toString()}`;
|
|
144
|
+
return fetchJson(url, accessToken, businessDomain, { method: "GET" });
|
|
145
|
+
}
|
|
146
|
+
export async function addSmallModel(options) {
|
|
147
|
+
assertSmallModelConfigAdapterExclusive(options.body);
|
|
148
|
+
const { accessToken, businessDomain = "bd_public", body } = options;
|
|
149
|
+
const url = managerEndpoint(options, "/small-model/add");
|
|
150
|
+
return fetchJson(url, accessToken, businessDomain, {
|
|
151
|
+
method: "POST",
|
|
152
|
+
headers: { "content-type": "application/json" },
|
|
153
|
+
body: JSON.stringify(body),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
export async function editSmallModel(options) {
|
|
157
|
+
assertSmallModelEditBody(options.body);
|
|
158
|
+
const { accessToken, businessDomain = "bd_public", body } = options;
|
|
159
|
+
const url = managerEndpoint(options, "/small-model/edit");
|
|
160
|
+
return fetchJson(url, accessToken, businessDomain, {
|
|
161
|
+
method: "POST",
|
|
162
|
+
headers: { "content-type": "application/json" },
|
|
163
|
+
body: JSON.stringify(body),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
export async function deleteSmallModels(options) {
|
|
167
|
+
const { accessToken, businessDomain = "bd_public", modelIds } = options;
|
|
168
|
+
const url = managerEndpoint(options, "/small-model/delete");
|
|
169
|
+
return fetchJson(url, accessToken, businessDomain, {
|
|
170
|
+
method: "POST",
|
|
171
|
+
headers: { "content-type": "application/json" },
|
|
172
|
+
body: JSON.stringify({ model_ids: modelIds }),
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
export async function testSmallModel(options) {
|
|
176
|
+
const { accessToken, businessDomain = "bd_public", body } = options;
|
|
177
|
+
const url = managerEndpoint(options, "/small-model/test");
|
|
178
|
+
return fetchJson(url, accessToken, businessDomain, {
|
|
179
|
+
method: "POST",
|
|
180
|
+
headers: { "content-type": "application/json" },
|
|
181
|
+
body: JSON.stringify(body),
|
|
182
|
+
});
|
|
183
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { OntologyQueryBaseOptions } from "./ontology-query.js";
|
|
2
|
+
export interface MetricQueryDataOptions extends OntologyQueryBaseOptions {
|
|
3
|
+
metricId: string;
|
|
4
|
+
body: string;
|
|
5
|
+
branch?: string;
|
|
6
|
+
fillNull?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface MetricDryRunOptions extends OntologyQueryBaseOptions {
|
|
9
|
+
body: string;
|
|
10
|
+
branch?: string;
|
|
11
|
+
fillNull?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function metricQueryData(options: MetricQueryDataOptions): Promise<string>;
|
|
14
|
+
export declare function metricDryRun(options: MetricDryRunOptions): Promise<string>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { fetchWithRetry } from "./ontology-query.js";
|
|
2
|
+
import { buildHeaders } from "./headers.js";
|
|
3
|
+
function appendMetricQueryParams(url, branch, fillNull) {
|
|
4
|
+
if (branch !== undefined)
|
|
5
|
+
url.searchParams.set("branch", branch);
|
|
6
|
+
if (fillNull !== undefined)
|
|
7
|
+
url.searchParams.set("fill_null", String(fillNull));
|
|
8
|
+
}
|
|
9
|
+
export async function metricQueryData(options) {
|
|
10
|
+
const { baseUrl, accessToken, knId, metricId, body, businessDomain = "bd_public", branch, fillNull, } = options;
|
|
11
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
12
|
+
const url = new URL(`${base}/api/ontology-query/v1/knowledge-networks/${encodeURIComponent(knId)}/metrics/${encodeURIComponent(metricId)}/data`);
|
|
13
|
+
appendMetricQueryParams(url, branch, fillNull);
|
|
14
|
+
const headers = {
|
|
15
|
+
...buildHeaders(accessToken, businessDomain),
|
|
16
|
+
"content-type": "application/json",
|
|
17
|
+
};
|
|
18
|
+
return fetchWithRetry(url.toString(), { method: "POST", headers, body });
|
|
19
|
+
}
|
|
20
|
+
export async function metricDryRun(options) {
|
|
21
|
+
const { baseUrl, accessToken, knId, body, businessDomain = "bd_public", branch, fillNull, } = options;
|
|
22
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
23
|
+
const url = new URL(`${base}/api/ontology-query/v1/knowledge-networks/${encodeURIComponent(knId)}/metrics/dry-run`);
|
|
24
|
+
appendMetricQueryParams(url, branch, fillNull);
|
|
25
|
+
const headers = {
|
|
26
|
+
...buildHeaders(accessToken, businessDomain),
|
|
27
|
+
"content-type": "application/json",
|
|
28
|
+
};
|
|
29
|
+
return fetchWithRetry(url.toString(), { method: "POST", headers, body });
|
|
30
|
+
}
|
package/dist/api/toolboxes.d.ts
CHANGED
|
@@ -63,6 +63,8 @@ export interface InvokeToolOptions extends BaseOpts {
|
|
|
63
63
|
header?: Record<string, unknown>;
|
|
64
64
|
/** Optional query params to forward. */
|
|
65
65
|
query?: Record<string, unknown>;
|
|
66
|
+
/** Path parameter map for OpenAPI `{param}` placeholders (e.g. `{ id: "<uuid>" }`). */
|
|
67
|
+
path?: Record<string, unknown>;
|
|
66
68
|
/** JSON body forwarded to the downstream tool. */
|
|
67
69
|
body?: unknown;
|
|
68
70
|
/** Per-call timeout in seconds; backend default applies when omitted. */
|
package/dist/api/toolboxes.js
CHANGED
|
@@ -20,7 +20,7 @@ import { buildHeaders } from "./headers.js";
|
|
|
20
20
|
// POST /tool-box/{box}/tool/{tool}/debug debug tool (envelope JSON)
|
|
21
21
|
//
|
|
22
22
|
// Envelope shape required by /proxy and /debug:
|
|
23
|
-
// { "timeout": <s>, "header": {...}, "query": {...}, "body": {...} }
|
|
23
|
+
// { "timeout": <s>, "header": {...}, "query": {...}, "body": {...}, "path": {...} }
|
|
24
24
|
// Flat-shape requests cause the forwarder to drop downstream Authorization
|
|
25
25
|
// headers, which manifests as 401 "token expired" from the underlying tool.
|
|
26
26
|
const PATH = "/api/agent-operator-integration/v1/tool-box";
|
|
@@ -145,6 +145,7 @@ function buildEnvelope(opts) {
|
|
|
145
145
|
envelope.timeout = opts.timeout;
|
|
146
146
|
envelope.header = opts.header ?? {};
|
|
147
147
|
envelope.query = opts.query ?? {};
|
|
148
|
+
envelope.path = opts.path ?? {};
|
|
148
149
|
envelope.body = opts.body ?? {};
|
|
149
150
|
return JSON.stringify(envelope);
|
|
150
151
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static JSON templates shipped with the CLI under ``src/templates/model`` (copied to ``dist/templates/model``).
|
|
3
|
+
* Read-only convenience until mf-model-manager exposes template APIs.
|
|
4
|
+
*/
|
|
5
|
+
export interface BundledModelTemplateEntry {
|
|
6
|
+
id: string;
|
|
7
|
+
file: string;
|
|
8
|
+
summary: string;
|
|
9
|
+
}
|
|
10
|
+
export interface BundledModelTemplateManifest {
|
|
11
|
+
llm: BundledModelTemplateEntry[];
|
|
12
|
+
small: BundledModelTemplateEntry[];
|
|
13
|
+
}
|
|
14
|
+
/** Resolve ``…/dist/templates/model`` (or ``…/src/templates/model`` when running via tsx from src). */
|
|
15
|
+
export declare function bundledModelTemplatesDir(): string;
|
|
16
|
+
export declare function loadBundledModelTemplateManifest(): Promise<BundledModelTemplateManifest>;
|
|
17
|
+
export declare function readBundledModelTemplateFile(branch: "llm" | "small", templateId: string): Promise<string>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static JSON templates shipped with the CLI under ``src/templates/model`` (copied to ``dist/templates/model``).
|
|
3
|
+
* Read-only convenience until mf-model-manager exposes template APIs.
|
|
4
|
+
*/
|
|
5
|
+
import { readFile } from "node:fs/promises";
|
|
6
|
+
import { dirname, join } from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
/** Resolve ``…/dist/templates/model`` (or ``…/src/templates/model`` when running via tsx from src). */
|
|
9
|
+
export function bundledModelTemplatesDir() {
|
|
10
|
+
return join(dirname(fileURLToPath(import.meta.url)), "templates", "model");
|
|
11
|
+
}
|
|
12
|
+
export async function loadBundledModelTemplateManifest() {
|
|
13
|
+
const raw = await readFile(join(bundledModelTemplatesDir(), "manifest.json"), "utf-8");
|
|
14
|
+
return JSON.parse(raw);
|
|
15
|
+
}
|
|
16
|
+
export async function readBundledModelTemplateFile(branch, templateId) {
|
|
17
|
+
const manifest = await loadBundledModelTemplateManifest();
|
|
18
|
+
const entries = branch === "llm" ? manifest.llm : manifest.small;
|
|
19
|
+
const hit = entries.find((e) => e.id === templateId);
|
|
20
|
+
if (!hit) {
|
|
21
|
+
throw new Error(`Unknown bundled template "${templateId}". Run: kweaver model ${branch} --template`);
|
|
22
|
+
}
|
|
23
|
+
return readFile(join(bundledModelTemplatesDir(), hit.file), "utf-8");
|
|
24
|
+
}
|