runbios-mcp 0.2.8-dev.210 → 0.2.8-dev.213
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 +8 -5
- package/dist/assistant/approval.d.ts +28 -0
- package/dist/assistant/approval.d.ts.map +1 -0
- package/dist/assistant/approval.js +85 -0
- package/dist/assistant/approval.js.map +1 -0
- package/dist/assistant/model.d.ts +63 -0
- package/dist/assistant/model.d.ts.map +1 -0
- package/dist/assistant/model.js +238 -0
- package/dist/assistant/model.js.map +1 -0
- package/dist/assistant/tool-runtime.d.ts +28 -0
- package/dist/assistant/tool-runtime.d.ts.map +1 -0
- package/dist/assistant/tool-runtime.js +140 -0
- package/dist/assistant/tool-runtime.js.map +1 -0
- package/dist/http/app.d.ts.map +1 -1
- package/dist/http/app.js +8 -2
- package/dist/http/app.js.map +1 -1
- package/dist/http/assistant.d.ts +21 -0
- package/dist/http/assistant.d.ts.map +1 -0
- package/dist/http/assistant.js +679 -0
- package/dist/http/assistant.js.map +1 -0
- package/dist/http/mcp-handler.d.ts.map +1 -1
- package/dist/http/mcp-handler.js +16 -1
- package/dist/http/mcp-handler.js.map +1 -1
- package/dist/http/store.d.ts +17 -0
- package/dist/http/store.d.ts.map +1 -1
- package/dist/http/store.js +45 -0
- package/dist/http/store.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +36 -13
- package/dist/server.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -360,11 +360,14 @@ deployed, not a roadmap item:
|
|
|
360
360
|
`/.well-known/openid-configuration` (each also under `/mcp`).
|
|
361
361
|
- Consent is granted in the console (`CONSOLE_BASE_URL`); every request
|
|
362
362
|
re-validates the bearer token and re-checks scopes and workspace membership
|
|
363
|
-
through the internal api-gateway.
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
363
|
+
through the internal api-gateway. `tools/list` is filtered to that grant and
|
|
364
|
+
the organization’s active release entitlements, so unavailable capabilities
|
|
365
|
+
are absent rather than advertised and rejected later.
|
|
366
|
+
- `chat_with_inference` and `upload_dataset` are intentionally unavailable on
|
|
367
|
+
the hosted connection. A deployment's serving key is shown exactly once and
|
|
368
|
+
is never retrievable, while a hosted process cannot read a file from the
|
|
369
|
+
client machine. Use the OpenAI-compatible inference API for chat and the
|
|
370
|
+
console’s direct upload flow for local datasets.
|
|
368
371
|
|
|
369
372
|
Any documentation still describing the hosted connector as "planned" is stale.
|
|
370
373
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { McpStore } from "../http/store.js";
|
|
2
|
+
export type AssistantToolRisk = "write" | "spend" | "destructive";
|
|
3
|
+
export interface ApprovedToolCall {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
arguments: Record<string, unknown>;
|
|
7
|
+
risk: AssistantToolRisk;
|
|
8
|
+
}
|
|
9
|
+
export interface ApprovalPayload {
|
|
10
|
+
version: 1;
|
|
11
|
+
nonce: string;
|
|
12
|
+
userId: string;
|
|
13
|
+
workspaceId: string;
|
|
14
|
+
orgId: string;
|
|
15
|
+
expiresAt: number;
|
|
16
|
+
calls: ApprovedToolCall[];
|
|
17
|
+
}
|
|
18
|
+
export declare function issueApprovalToken(store: McpStore, key: string, input: Omit<ApprovalPayload, "version" | "nonce" | "expiresAt">, now?: () => number): Promise<{
|
|
19
|
+
token: string;
|
|
20
|
+
expiresAt: number;
|
|
21
|
+
}>;
|
|
22
|
+
export declare function verifyApprovalToken(token: string, key: string, identity: {
|
|
23
|
+
userId: string;
|
|
24
|
+
workspaceId: string;
|
|
25
|
+
orgId: string;
|
|
26
|
+
}, now?: () => number): ApprovalPayload | null;
|
|
27
|
+
export declare function consumeApprovalToken(store: McpStore, payload: ApprovalPayload, decision: "approve" | "reject"): Promise<boolean>;
|
|
28
|
+
//# sourceMappingURL=approval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval.d.ts","sourceRoot":"","sources":["../../src/assistant/approval.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,GAAG,aAAa,CAAC;AAElE,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,CAAC,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AA2BD,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,QAAQ,EACf,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,OAAO,GAAG,WAAW,CAAC,EAC/D,GAAG,GAAE,MAAM,MAAiB,GAC3B,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAiB/C;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAChE,GAAG,GAAE,MAAM,MAAiB,GAC3B,eAAe,GAAG,IAAI,CAmCxB;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,SAAS,GAAG,QAAQ,GAC7B,OAAO,CAAC,OAAO,CAAC,CAOlB"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { createHash, createHmac, randomUUID, timingSafeEqual } from "node:crypto";
|
|
2
|
+
const APPROVAL_TTL_MS = 10 * 60_000;
|
|
3
|
+
const MAX_TOKEN_BYTES = 128 * 1024;
|
|
4
|
+
function digest(value) {
|
|
5
|
+
return createHash("sha256").update(value).digest("hex");
|
|
6
|
+
}
|
|
7
|
+
function signature(encoded, key) {
|
|
8
|
+
return createHmac("sha256", key).update(encoded).digest();
|
|
9
|
+
}
|
|
10
|
+
function validCall(value) {
|
|
11
|
+
if (!value || typeof value !== "object")
|
|
12
|
+
return false;
|
|
13
|
+
const call = value;
|
|
14
|
+
return typeof call.id === "string"
|
|
15
|
+
&& call.id.length > 0
|
|
16
|
+
&& call.id.length <= 256
|
|
17
|
+
&& typeof call.name === "string"
|
|
18
|
+
&& /^[A-Za-z0-9_-]{1,128}$/.test(call.name)
|
|
19
|
+
&& !!call.arguments
|
|
20
|
+
&& typeof call.arguments === "object"
|
|
21
|
+
&& !Array.isArray(call.arguments)
|
|
22
|
+
&& (call.risk === "write" || call.risk === "spend" || call.risk === "destructive");
|
|
23
|
+
}
|
|
24
|
+
export async function issueApprovalToken(store, key, input, now = Date.now) {
|
|
25
|
+
if (!key || input.calls.length === 0 || input.calls.length > 16 || !input.calls.every(validCall)) {
|
|
26
|
+
throw new Error("Approval request is invalid");
|
|
27
|
+
}
|
|
28
|
+
const nonce = randomUUID();
|
|
29
|
+
const expiresAt = now() + APPROVAL_TTL_MS;
|
|
30
|
+
const payload = { version: 1, nonce, expiresAt, ...input };
|
|
31
|
+
const encoded = Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
|
|
32
|
+
const token = `${encoded}.${signature(encoded, key).toString("base64url")}`;
|
|
33
|
+
await store.insertAssistantApproval({
|
|
34
|
+
id_hash: digest(nonce),
|
|
35
|
+
user_id: input.userId,
|
|
36
|
+
workspace_id: input.workspaceId,
|
|
37
|
+
tool_names: input.calls.map((call) => call.name),
|
|
38
|
+
expires_at: new Date(expiresAt),
|
|
39
|
+
});
|
|
40
|
+
return { token, expiresAt };
|
|
41
|
+
}
|
|
42
|
+
export function verifyApprovalToken(token, key, identity, now = Date.now) {
|
|
43
|
+
if (!key || !token || Buffer.byteLength(token, "utf8") > MAX_TOKEN_BYTES)
|
|
44
|
+
return null;
|
|
45
|
+
const parts = token.split(".");
|
|
46
|
+
if (parts.length !== 2)
|
|
47
|
+
return null;
|
|
48
|
+
const [encoded, supplied] = parts;
|
|
49
|
+
let suppliedSignature;
|
|
50
|
+
try {
|
|
51
|
+
suppliedSignature = Buffer.from(supplied, "base64url");
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const expected = signature(encoded, key);
|
|
57
|
+
if (suppliedSignature.length !== expected.length || !timingSafeEqual(suppliedSignature, expected))
|
|
58
|
+
return null;
|
|
59
|
+
let payload;
|
|
60
|
+
try {
|
|
61
|
+
payload = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
if (payload.version !== 1
|
|
67
|
+
|| typeof payload.nonce !== "string"
|
|
68
|
+
|| typeof payload.expiresAt !== "number"
|
|
69
|
+
|| payload.expiresAt <= now()
|
|
70
|
+
|| payload.expiresAt > now() + APPROVAL_TTL_MS
|
|
71
|
+
|| payload.userId !== identity.userId
|
|
72
|
+
|| payload.workspaceId !== identity.workspaceId
|
|
73
|
+
|| payload.orgId !== identity.orgId
|
|
74
|
+
|| !Array.isArray(payload.calls)
|
|
75
|
+
|| payload.calls.length === 0
|
|
76
|
+
|| payload.calls.length > 16
|
|
77
|
+
|| !payload.calls.every(validCall)) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
return payload;
|
|
81
|
+
}
|
|
82
|
+
export async function consumeApprovalToken(store, payload, decision) {
|
|
83
|
+
return store.consumeAssistantApproval(digest(payload.nonce), payload.userId, payload.workspaceId, decision);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=approval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval.js","sourceRoot":"","sources":["../../src/assistant/approval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export type AssistantContentPart = {
|
|
2
|
+
type: "text";
|
|
3
|
+
text: string;
|
|
4
|
+
} | {
|
|
5
|
+
type: "image_url";
|
|
6
|
+
image_url: {
|
|
7
|
+
url: string;
|
|
8
|
+
};
|
|
9
|
+
} | {
|
|
10
|
+
type: "video_url";
|
|
11
|
+
video_url: {
|
|
12
|
+
url: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export interface AssistantModelToolCall {
|
|
16
|
+
id: string;
|
|
17
|
+
type: "function";
|
|
18
|
+
function: {
|
|
19
|
+
name: string;
|
|
20
|
+
arguments: string;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export interface AssistantModelMessage {
|
|
24
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
25
|
+
content: string | AssistantContentPart[] | null;
|
|
26
|
+
tool_calls?: AssistantModelToolCall[];
|
|
27
|
+
tool_call_id?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface AssistantUsage {
|
|
30
|
+
prompt_tokens?: number;
|
|
31
|
+
completion_tokens?: number;
|
|
32
|
+
total_tokens?: number;
|
|
33
|
+
prompt_tokens_details?: Record<string, number> | null;
|
|
34
|
+
}
|
|
35
|
+
export interface AssistantModelResult {
|
|
36
|
+
message: AssistantModelMessage;
|
|
37
|
+
finishReason: string | null;
|
|
38
|
+
usage: AssistantUsage | null;
|
|
39
|
+
contextTransform: Record<string, unknown> | null;
|
|
40
|
+
}
|
|
41
|
+
export declare class AssistantUpstreamError extends Error {
|
|
42
|
+
readonly status: number;
|
|
43
|
+
readonly code: string;
|
|
44
|
+
constructor(status: number, code: string, message: string);
|
|
45
|
+
}
|
|
46
|
+
interface ModelStreamInput {
|
|
47
|
+
baseUrl: string;
|
|
48
|
+
authorization: string;
|
|
49
|
+
orgId: string;
|
|
50
|
+
workspaceId: string;
|
|
51
|
+
model: string;
|
|
52
|
+
effort?: string;
|
|
53
|
+
maxTokens?: number;
|
|
54
|
+
messages: AssistantModelMessage[];
|
|
55
|
+
tools: Record<string, unknown>[];
|
|
56
|
+
signal: AbortSignal;
|
|
57
|
+
fetchImpl?: typeof fetch;
|
|
58
|
+
onTextDelta?: (text: string) => void;
|
|
59
|
+
onContextTransform?: (value: Record<string, unknown>) => void;
|
|
60
|
+
}
|
|
61
|
+
export declare function streamAssistantModel(input: ModelStreamInput): Promise<AssistantModelResult>;
|
|
62
|
+
export {};
|
|
63
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/assistant/model.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAEtD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,GAAG,oBAAoB,EAAE,GAAG,IAAI,CAAC;IAChD,UAAU,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CACvD;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAClD;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAE7C,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM;gBADZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM;CAKlB;AAED,UAAU,gBAAgB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACjC,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CAC/D;AAyHD,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA+FjG"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { redactBuildIdentity } from "../redaction.js";
|
|
3
|
+
export class AssistantUpstreamError extends Error {
|
|
4
|
+
status;
|
|
5
|
+
code;
|
|
6
|
+
constructor(status, code, message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.status = status;
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.name = "AssistantUpstreamError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function upstreamError(status, raw) {
|
|
14
|
+
let message = "The assistant model could not complete this request.";
|
|
15
|
+
let code = "assistant_model_error";
|
|
16
|
+
try {
|
|
17
|
+
const parsed = JSON.parse(raw);
|
|
18
|
+
const nested = parsed.error && typeof parsed.error === "object"
|
|
19
|
+
? parsed.error
|
|
20
|
+
: {};
|
|
21
|
+
const candidate = nested.message ?? parsed.message ?? parsed.detail;
|
|
22
|
+
const candidateCode = nested.code ?? nested.type ?? parsed.code;
|
|
23
|
+
if (typeof candidate === "string" && candidate.trim())
|
|
24
|
+
message = redactBuildIdentity(candidate.trim());
|
|
25
|
+
if (typeof candidateCode === "string" && candidateCode.trim())
|
|
26
|
+
code = candidateCode.trim();
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
if (raw.trim() && raw.length <= 500 && !raw.trim().startsWith("<"))
|
|
30
|
+
message = redactBuildIdentity(raw.trim());
|
|
31
|
+
}
|
|
32
|
+
if (status === 402) {
|
|
33
|
+
code = "insufficient_funds";
|
|
34
|
+
if (!message || message === "The assistant model could not complete this request.") {
|
|
35
|
+
message = "Your wallet does not have enough available credit for this request.";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return new AssistantUpstreamError(status, code, message);
|
|
39
|
+
}
|
|
40
|
+
function mergeToolCall(calls, indexMap, raw) {
|
|
41
|
+
const fn = raw.function && typeof raw.function === "object"
|
|
42
|
+
? raw.function
|
|
43
|
+
: {};
|
|
44
|
+
const wireIndex = typeof raw.index === "number" ? raw.index : undefined;
|
|
45
|
+
const id = typeof raw.id === "string" ? raw.id : "";
|
|
46
|
+
const known = id ? calls.findIndex((call) => call.id === id) : -1;
|
|
47
|
+
let index;
|
|
48
|
+
if (known >= 0)
|
|
49
|
+
index = known;
|
|
50
|
+
else if (id && wireIndex !== undefined && calls[indexMap.get(wireIndex) ?? wireIndex]?.id)
|
|
51
|
+
index = calls.length;
|
|
52
|
+
else if (wireIndex !== undefined)
|
|
53
|
+
index = indexMap.get(wireIndex) ?? wireIndex;
|
|
54
|
+
else if (id || typeof fn.name === "string")
|
|
55
|
+
index = calls.length;
|
|
56
|
+
else
|
|
57
|
+
index = Math.max(0, calls.length - 1);
|
|
58
|
+
if (wireIndex !== undefined)
|
|
59
|
+
indexMap.set(wireIndex, index);
|
|
60
|
+
if (!calls[index]) {
|
|
61
|
+
calls[index] = { id: "", type: "function", function: { name: "", arguments: "" } };
|
|
62
|
+
}
|
|
63
|
+
if (id)
|
|
64
|
+
calls[index].id = id;
|
|
65
|
+
if (typeof fn.name === "string")
|
|
66
|
+
calls[index].function.name += fn.name;
|
|
67
|
+
if (typeof fn.arguments === "string")
|
|
68
|
+
calls[index].function.arguments += fn.arguments;
|
|
69
|
+
}
|
|
70
|
+
function consumeCompletionObject(object, state, input) {
|
|
71
|
+
if (object.error) {
|
|
72
|
+
const error = object.error;
|
|
73
|
+
const message = typeof error === "string" ? error : String(error.message ?? "The model stream failed.");
|
|
74
|
+
const code = typeof error === "object" && typeof error.code === "string" ? error.code : "assistant_model_error";
|
|
75
|
+
throw new AssistantUpstreamError(502, code, redactBuildIdentity(message));
|
|
76
|
+
}
|
|
77
|
+
if (object.usage && typeof object.usage === "object")
|
|
78
|
+
state.usage = object.usage;
|
|
79
|
+
if (object.bios_context_transform && typeof object.bios_context_transform === "object") {
|
|
80
|
+
state.contextTransform = object.bios_context_transform;
|
|
81
|
+
input.onContextTransform?.(state.contextTransform);
|
|
82
|
+
}
|
|
83
|
+
const choices = Array.isArray(object.choices) ? object.choices : [];
|
|
84
|
+
for (const rawChoice of choices) {
|
|
85
|
+
if (!rawChoice || typeof rawChoice !== "object")
|
|
86
|
+
continue;
|
|
87
|
+
const choice = rawChoice;
|
|
88
|
+
if (typeof choice.finish_reason === "string")
|
|
89
|
+
state.finishReason = choice.finish_reason;
|
|
90
|
+
const payload = choice.delta && typeof choice.delta === "object"
|
|
91
|
+
? choice.delta
|
|
92
|
+
: choice.message && typeof choice.message === "object"
|
|
93
|
+
? choice.message
|
|
94
|
+
: {};
|
|
95
|
+
if (typeof payload.content === "string" && payload.content) {
|
|
96
|
+
state.content += payload.content;
|
|
97
|
+
input.onTextDelta?.(payload.content);
|
|
98
|
+
}
|
|
99
|
+
const toolCalls = Array.isArray(payload.tool_calls) ? payload.tool_calls : [];
|
|
100
|
+
for (const call of toolCalls) {
|
|
101
|
+
if (call && typeof call === "object")
|
|
102
|
+
mergeToolCall(state.calls, state.indexMap, call);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function emitFrame(frame, consume) {
|
|
107
|
+
const data = [];
|
|
108
|
+
for (const line of frame.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n")) {
|
|
109
|
+
if (!line || line.startsWith(":"))
|
|
110
|
+
continue;
|
|
111
|
+
const colon = line.indexOf(":");
|
|
112
|
+
const field = colon < 0 ? line : line.slice(0, colon);
|
|
113
|
+
let value = colon < 0 ? "" : line.slice(colon + 1);
|
|
114
|
+
if (value.startsWith(" "))
|
|
115
|
+
value = value.slice(1);
|
|
116
|
+
if (field === "data")
|
|
117
|
+
data.push(value);
|
|
118
|
+
}
|
|
119
|
+
if (data.length === 0)
|
|
120
|
+
return false;
|
|
121
|
+
const payload = data.join("\n").trim();
|
|
122
|
+
if (payload === "[DONE]")
|
|
123
|
+
return true;
|
|
124
|
+
try {
|
|
125
|
+
const parsed = JSON.parse(payload);
|
|
126
|
+
if (parsed && typeof parsed === "object")
|
|
127
|
+
consume(parsed);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
export async function streamAssistantModel(input) {
|
|
135
|
+
const fetchImpl = input.fetchImpl ?? fetch;
|
|
136
|
+
const body = {
|
|
137
|
+
model: input.model,
|
|
138
|
+
messages: input.messages,
|
|
139
|
+
stream: true,
|
|
140
|
+
stream_options: { include_usage: true },
|
|
141
|
+
};
|
|
142
|
+
if (input.effort)
|
|
143
|
+
body.reasoning_effort = input.effort;
|
|
144
|
+
if (input.maxTokens && input.maxTokens > 0)
|
|
145
|
+
body.max_tokens = input.maxTokens;
|
|
146
|
+
if (input.tools.length > 0) {
|
|
147
|
+
body.tools = input.tools;
|
|
148
|
+
body.tool_choice = "auto";
|
|
149
|
+
}
|
|
150
|
+
const response = await fetchImpl(`${input.baseUrl.replace(/\/+$/, "")}/v1/chat/completions`, {
|
|
151
|
+
method: "POST",
|
|
152
|
+
headers: {
|
|
153
|
+
Accept: "text/event-stream",
|
|
154
|
+
Authorization: input.authorization,
|
|
155
|
+
"Content-Type": "application/json",
|
|
156
|
+
"User-Agent": "bios-assistant/1.0",
|
|
157
|
+
"X-Org-ID": input.orgId,
|
|
158
|
+
"X-Workspace-ID": input.workspaceId,
|
|
159
|
+
"X-Request-ID": randomUUID(),
|
|
160
|
+
},
|
|
161
|
+
body: JSON.stringify(body),
|
|
162
|
+
signal: input.signal,
|
|
163
|
+
});
|
|
164
|
+
if (!response.ok)
|
|
165
|
+
throw upstreamError(response.status, await response.text().catch(() => ""));
|
|
166
|
+
if (!response.body)
|
|
167
|
+
throw new AssistantUpstreamError(502, "empty_model_stream", "The assistant model returned no response stream.");
|
|
168
|
+
const state = {
|
|
169
|
+
content: "",
|
|
170
|
+
finishReason: null,
|
|
171
|
+
usage: null,
|
|
172
|
+
contextTransform: null,
|
|
173
|
+
calls: [],
|
|
174
|
+
indexMap: new Map(),
|
|
175
|
+
};
|
|
176
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
177
|
+
if (!contentType.includes("text/event-stream")) {
|
|
178
|
+
const text = await response.text();
|
|
179
|
+
let parsed;
|
|
180
|
+
try {
|
|
181
|
+
parsed = JSON.parse(text);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
throw new AssistantUpstreamError(502, "invalid_model_response", "The assistant model returned an unreadable response.");
|
|
185
|
+
}
|
|
186
|
+
if (!parsed || typeof parsed !== "object") {
|
|
187
|
+
throw new AssistantUpstreamError(502, "invalid_model_response", "The assistant model returned an empty response.");
|
|
188
|
+
}
|
|
189
|
+
consumeCompletionObject(parsed, state, input);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
const reader = response.body.getReader();
|
|
193
|
+
const decoder = new TextDecoder();
|
|
194
|
+
let buffer = "";
|
|
195
|
+
let finished = false;
|
|
196
|
+
try {
|
|
197
|
+
while (!finished) {
|
|
198
|
+
const { done, value } = await reader.read();
|
|
199
|
+
if (done)
|
|
200
|
+
break;
|
|
201
|
+
buffer += decoder.decode(value, { stream: true });
|
|
202
|
+
for (;;) {
|
|
203
|
+
const match = /\r\n\r\n|\n\n|\r\r/.exec(buffer);
|
|
204
|
+
if (!match || match.index === undefined)
|
|
205
|
+
break;
|
|
206
|
+
const frame = buffer.slice(0, match.index);
|
|
207
|
+
buffer = buffer.slice(match.index + match[0].length);
|
|
208
|
+
if (emitFrame(frame, (object) => consumeCompletionObject(object, state, input))) {
|
|
209
|
+
finished = true;
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
buffer += decoder.decode();
|
|
215
|
+
if (!finished && buffer.trim())
|
|
216
|
+
emitFrame(buffer, (object) => consumeCompletionObject(object, state, input));
|
|
217
|
+
}
|
|
218
|
+
finally {
|
|
219
|
+
await reader.cancel().catch(() => undefined);
|
|
220
|
+
reader.releaseLock();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const calls = state.calls.filter((call) => call?.function.name).map((call, index) => ({
|
|
224
|
+
...call,
|
|
225
|
+
id: call.id || `call_${index}_${randomUUID().slice(0, 8)}`,
|
|
226
|
+
}));
|
|
227
|
+
return {
|
|
228
|
+
message: {
|
|
229
|
+
role: "assistant",
|
|
230
|
+
content: state.content || null,
|
|
231
|
+
...(calls.length > 0 ? { tool_calls: calls } : {}),
|
|
232
|
+
},
|
|
233
|
+
finishReason: state.finishReason,
|
|
234
|
+
usage: state.usage,
|
|
235
|
+
contextTransform: state.contextTransform,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/assistant/model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { BiosClient } from "../api-client.js";
|
|
2
|
+
import type { LaunchGates } from "../config.js";
|
|
3
|
+
import { type ServerHooks } from "../server.js";
|
|
4
|
+
import type { AssistantToolRisk } from "./approval.js";
|
|
5
|
+
export interface AssistantToolDefinition {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
inputSchema: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export interface AssistantToolResult {
|
|
11
|
+
ok: boolean;
|
|
12
|
+
text: string;
|
|
13
|
+
}
|
|
14
|
+
export interface AssistantToolRuntime {
|
|
15
|
+
tools: AssistantToolDefinition[];
|
|
16
|
+
call(name: string, args: Record<string, unknown>): Promise<AssistantToolResult>;
|
|
17
|
+
close(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export declare function toolRisk(name: string): "read" | AssistantToolRisk;
|
|
20
|
+
export declare function rankTools(tools: AssistantToolDefinition[], query: string, limit?: number): AssistantToolDefinition[];
|
|
21
|
+
export declare function openAITool(tool: AssistantToolDefinition): Record<string, unknown>;
|
|
22
|
+
export declare function createAssistantToolRuntime(input: {
|
|
23
|
+
client: BiosClient;
|
|
24
|
+
launchGates: LaunchGates;
|
|
25
|
+
allowedTools: ReadonlySet<string>;
|
|
26
|
+
hooks?: ServerHooks;
|
|
27
|
+
}): Promise<AssistantToolRuntime>;
|
|
28
|
+
//# sourceMappingURL=tool-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-runtime.d.ts","sourceRoot":"","sources":["../../src/assistant/tool-runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,uBAAuB,EAAE,CAAC;IACjC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAChF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAqBD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,iBAAiB,CAKjE;AA4BD,wBAAgB,SAAS,CACvB,KAAK,EAAE,uBAAuB,EAAE,EAChC,KAAK,EAAE,MAAM,EACb,KAAK,SAAK,GACT,uBAAuB,EAAE,CA6B3B;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASjF;AAED,wBAAsB,0BAA0B,CAAC,KAAK,EAAE;IACtD,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAyChC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
3
|
+
import { createBiosMcpServer } from "../server.js";
|
|
4
|
+
const SPEND_TOOLS = new Set([
|
|
5
|
+
"create_inference",
|
|
6
|
+
"create_training_job",
|
|
7
|
+
"resume_inference",
|
|
8
|
+
"restart_inference",
|
|
9
|
+
"resume_training_job",
|
|
10
|
+
"update_inference_policy",
|
|
11
|
+
"loop_consent_training_rule",
|
|
12
|
+
"loop_run_training_rule",
|
|
13
|
+
"loop_promote_training_run",
|
|
14
|
+
"loop_enable_agent",
|
|
15
|
+
"loop_create_sample_run",
|
|
16
|
+
"loop_start_judge_run",
|
|
17
|
+
"loop_update_agent_settings",
|
|
18
|
+
]);
|
|
19
|
+
const READ_PREFIXES = ["get_", "list_", "search_", "preview_", "preflight_", "recommend_", "introspect_"];
|
|
20
|
+
const DESTRUCTIVE_PREFIXES = ["delete_", "remove_", "stop_", "cancel_", "reject_", "rollback_", "abort_", "disconnect_"];
|
|
21
|
+
export function toolRisk(name) {
|
|
22
|
+
if (SPEND_TOOLS.has(name))
|
|
23
|
+
return "spend";
|
|
24
|
+
if (DESTRUCTIVE_PREFIXES.some((prefix) => name.startsWith(prefix)))
|
|
25
|
+
return "destructive";
|
|
26
|
+
if (READ_PREFIXES.some((prefix) => name.startsWith(prefix)))
|
|
27
|
+
return "read";
|
|
28
|
+
return "write";
|
|
29
|
+
}
|
|
30
|
+
function words(value) {
|
|
31
|
+
return value.toLowerCase().split(/[^a-z0-9]+/).filter((word) => word.length > 1);
|
|
32
|
+
}
|
|
33
|
+
function expandedQuery(query) {
|
|
34
|
+
const tokens = new Set(words(query));
|
|
35
|
+
const expansions = {
|
|
36
|
+
deploy: ["deployment", "inference"],
|
|
37
|
+
deployment: ["deploy", "inference"],
|
|
38
|
+
train: ["training", "job"],
|
|
39
|
+
training: ["train", "job"],
|
|
40
|
+
data: ["dataset"],
|
|
41
|
+
dataset: ["data"],
|
|
42
|
+
cost: ["wallet", "pricing", "billing"],
|
|
43
|
+
price: ["wallet", "pricing", "billing"],
|
|
44
|
+
model: ["models", "catalog"],
|
|
45
|
+
endpoint: ["inference", "deployment"],
|
|
46
|
+
checkpoint: ["training", "checkpoint"],
|
|
47
|
+
monitor: ["status", "metrics", "logs"],
|
|
48
|
+
};
|
|
49
|
+
for (const token of [...tokens]) {
|
|
50
|
+
for (const expansion of expansions[token] ?? [])
|
|
51
|
+
tokens.add(expansion);
|
|
52
|
+
}
|
|
53
|
+
return tokens;
|
|
54
|
+
}
|
|
55
|
+
export function rankTools(tools, query, limit = 24) {
|
|
56
|
+
const queryText = query.toLowerCase();
|
|
57
|
+
const queryWords = expandedQuery(query);
|
|
58
|
+
const scored = tools.map((tool, index) => {
|
|
59
|
+
const name = tool.name.toLowerCase();
|
|
60
|
+
const description = tool.description.toLowerCase();
|
|
61
|
+
const toolWords = new Set([...words(name), ...words(description)]);
|
|
62
|
+
let score = 0;
|
|
63
|
+
if (queryText.includes(name.replaceAll("_", " ")))
|
|
64
|
+
score += 30;
|
|
65
|
+
for (const word of queryWords) {
|
|
66
|
+
if (name.split("_").includes(word))
|
|
67
|
+
score += 8;
|
|
68
|
+
else if (name.includes(word))
|
|
69
|
+
score += 4;
|
|
70
|
+
if (toolWords.has(word))
|
|
71
|
+
score += 2;
|
|
72
|
+
else if (description.includes(word))
|
|
73
|
+
score += 1;
|
|
74
|
+
}
|
|
75
|
+
if (name === "introspect_api_key")
|
|
76
|
+
score += 1;
|
|
77
|
+
if (name === "get_wallet_balance" && /cost|price|spend|wallet|balance|train|deploy/.test(queryText))
|
|
78
|
+
score += 6;
|
|
79
|
+
return { tool, score, index };
|
|
80
|
+
});
|
|
81
|
+
scored.sort((a, b) => b.score - a.score || a.index - b.index);
|
|
82
|
+
const positive = scored.filter((entry) => entry.score > 0).slice(0, limit).map((entry) => entry.tool);
|
|
83
|
+
if (positive.length >= Math.min(6, tools.length))
|
|
84
|
+
return positive;
|
|
85
|
+
const selected = new Set(positive.map((tool) => tool.name));
|
|
86
|
+
for (const entry of scored) {
|
|
87
|
+
if (positive.length >= Math.min(limit, 8) || selected.has(entry.tool.name))
|
|
88
|
+
continue;
|
|
89
|
+
positive.push(entry.tool);
|
|
90
|
+
selected.add(entry.tool.name);
|
|
91
|
+
}
|
|
92
|
+
return positive;
|
|
93
|
+
}
|
|
94
|
+
export function openAITool(tool) {
|
|
95
|
+
return {
|
|
96
|
+
type: "function",
|
|
97
|
+
function: {
|
|
98
|
+
name: tool.name,
|
|
99
|
+
description: tool.description,
|
|
100
|
+
parameters: tool.inputSchema,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export async function createAssistantToolRuntime(input) {
|
|
105
|
+
const server = createBiosMcpServer(input.client, input.hooks, undefined, input.launchGates, input.allowedTools);
|
|
106
|
+
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
107
|
+
const client = new Client({ name: "runbios-assistant", version: "1.0.0" });
|
|
108
|
+
try {
|
|
109
|
+
await Promise.all([server.connect(serverTransport), client.connect(clientTransport)]);
|
|
110
|
+
const listed = await client.listTools();
|
|
111
|
+
const tools = listed.tools.map((tool) => ({
|
|
112
|
+
name: tool.name,
|
|
113
|
+
description: tool.description ?? "",
|
|
114
|
+
inputSchema: (tool.inputSchema ?? { type: "object", properties: {} }),
|
|
115
|
+
}));
|
|
116
|
+
return {
|
|
117
|
+
tools,
|
|
118
|
+
async call(name, args) {
|
|
119
|
+
const response = await client.callTool({ name, arguments: args });
|
|
120
|
+
const content = Array.isArray(response.content) ? response.content : [];
|
|
121
|
+
const text = content
|
|
122
|
+
.filter((part) => part?.type === "text" && typeof part.text === "string")
|
|
123
|
+
.map((part) => part.text)
|
|
124
|
+
.join("\n");
|
|
125
|
+
const fallback = response.structuredContent == null ? "" : JSON.stringify(response.structuredContent);
|
|
126
|
+
return { ok: response.isError !== true, text: text || fallback || "{}" };
|
|
127
|
+
},
|
|
128
|
+
async close() {
|
|
129
|
+
await client.close().catch(() => undefined);
|
|
130
|
+
await server.close().catch(() => undefined);
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
await client.close().catch(() => undefined);
|
|
136
|
+
await server.close().catch(() => undefined);
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=tool-runtime.js.map
|