@blade-hq/agent-client 2610.0.0-beta.26 → 2610.0.0-beta.28
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 +3 -1
- package/dist/blade-client.d.ts +0 -2
- package/dist/index.js +65 -15
- package/dist/index.js.map +1 -1
- package/dist/resources/sessions.d.ts +3 -1
- package/dist/schemas/projection.d.ts +2 -0
- package/dist/schemas/session.d.ts +3 -1
- package/dist/session/agent-session.d.ts +1 -1
- package/dist/types/socket-events.d.ts +2 -4
- package/package.json +1 -1
- package/public-api.md +5 -2
package/README.md
CHANGED
|
@@ -82,10 +82,12 @@ new BladeClient({
|
|
|
82
82
|
baseUrl: "https://blade.example.com", // 后端地址;同域部署可传 ""
|
|
83
83
|
token: "sk-blade-xxx", // 可选:PAT。不传则用 cookie 或 login()
|
|
84
84
|
tokenStorage: "local", // 可选:login() 的令牌存哪("local" 默认 / "memory")
|
|
85
|
-
streamTokens: false, // 可选:只接收完成态内容,不订阅逐 token 增量
|
|
86
85
|
})
|
|
87
86
|
```
|
|
88
87
|
|
|
88
|
+
SDK 会固定订阅普通聊天所需的完整实时事件。产品内置 Web 的精简/开发者展示模式不属于
|
|
89
|
+
公共 SDK 契约,也没有对应的构造参数或 Socket.IO 字段。
|
|
90
|
+
|
|
89
91
|
> **`baseUrl` 填哪个地址?** 必须是 Blade Agent 后端的地址(形如 `http://<主机>:8020`),只要域名和端口、不带路径。
|
|
90
92
|
> 注意别填成你平时打开的 Blade OS 地址(同主机的 `:80`)—— 那是另一套接口,SDK 连不上。
|
|
91
93
|
|
package/dist/blade-client.d.ts
CHANGED
|
@@ -23,8 +23,6 @@ export interface BladeClientOptions {
|
|
|
23
23
|
tokenStorage?: TokenStorageMode;
|
|
24
24
|
fetchImpl?: typeof fetch;
|
|
25
25
|
onRefreshSuccess?: () => void | Promise<void>;
|
|
26
|
-
/** 是否订阅逐 token 增量,默认 true。关闭后仍接收完整消息和语义事件。 */
|
|
27
|
-
streamTokens?: boolean;
|
|
28
26
|
}
|
|
29
27
|
export declare class BladeClient {
|
|
30
28
|
private refreshPromise;
|
package/dist/index.js
CHANGED
|
@@ -352,8 +352,7 @@ var HeadlessResource = class {
|
|
|
352
352
|
socket.on("system:error", onSystemError);
|
|
353
353
|
socket.emit("session:subscribe", {
|
|
354
354
|
session_id,
|
|
355
|
-
event_format: "raw"
|
|
356
|
-
stream_tokens: this.client.options.streamTokens !== false
|
|
355
|
+
event_format: "raw"
|
|
357
356
|
});
|
|
358
357
|
socket.emit(
|
|
359
358
|
"chat:send",
|
|
@@ -473,6 +472,7 @@ var SessionInfo = type({
|
|
|
473
472
|
"disable_tools?": "string[]",
|
|
474
473
|
"runtime_type?": "string | null",
|
|
475
474
|
"daemon_id?": "string | null",
|
|
475
|
+
"agent_runtime_id?": "string | null",
|
|
476
476
|
"workspace_path?": "string | null",
|
|
477
477
|
"match?": "unknown"
|
|
478
478
|
});
|
|
@@ -1027,12 +1027,14 @@ function toolStatusFromResult(result) {
|
|
|
1027
1027
|
var BUILTIN_CONTEXT_TITLES = {
|
|
1028
1028
|
"agent-instructions": "\u9879\u76EE\u8BF4\u660E",
|
|
1029
1029
|
"skill-catalog": "\u53EF\u7528\u80FD\u529B",
|
|
1030
|
-
"runtime-context": "\u5F53\u524D\u5DE5\u4F5C\u73AF\u5883"
|
|
1030
|
+
"runtime-context": "\u5F53\u524D\u5DE5\u4F5C\u73AF\u5883",
|
|
1031
|
+
"workspace-context": "\u5F53\u524D\u5DE5\u4F5C\u533A\u73AF\u5883"
|
|
1031
1032
|
};
|
|
1032
1033
|
var BUILTIN_CONTEXT_DETAILS = {
|
|
1033
1034
|
"agent-instructions": "\u8FD9\u4E9B\u8BF4\u660E\u4F1A\u5E2E\u52A9\u667A\u80FD\u4F53\u7406\u89E3\u5F53\u524D\u9879\u76EE\u548C\u5DE5\u4F5C\u8981\u6C42\u3002",
|
|
1034
1035
|
"skill-catalog": "\u8FD9\u4E9B\u80FD\u529B\u4F1A\u5E2E\u52A9\u667A\u80FD\u4F53\u9009\u62E9\u5408\u9002\u7684\u65B9\u5F0F\u5B8C\u6210\u4EFB\u52A1\u3002",
|
|
1035
|
-
"runtime-context": "\u8FD9\u4E9B\u4FE1\u606F\u4F1A\u5E2E\u52A9\u667A\u80FD\u4F53\u4E86\u89E3\u5F53\u524D\u6587\u4EF6\u5939\u548C\u8FD0\u884C\u6761\u4EF6\u3002"
|
|
1036
|
+
"runtime-context": "\u8FD9\u4E9B\u4FE1\u606F\u4F1A\u5E2E\u52A9\u667A\u80FD\u4F53\u4E86\u89E3\u5F53\u524D\u6587\u4EF6\u5939\u548C\u8FD0\u884C\u6761\u4EF6\u3002",
|
|
1037
|
+
"workspace-context": "\u8FD9\u4E9B\u4FE1\u606F\u4F1A\u5E2E\u52A9\u667A\u80FD\u4F53\u4E86\u89E3\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3001\u6587\u4EF6\u548C\u8FD0\u884C\u73AF\u5883\u3002"
|
|
1036
1038
|
};
|
|
1037
1039
|
function nonEmptyString(value) {
|
|
1038
1040
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
@@ -1060,7 +1062,7 @@ function contextProjectionData(fields) {
|
|
|
1060
1062
|
function getContextDisplayState(context) {
|
|
1061
1063
|
const title = BUILTIN_CONTEXT_TITLES[context.context_kind] ?? nonEmptyString(context.display_title) ?? "\u5BF9\u8BDD\u80CC\u666F";
|
|
1062
1064
|
const isRemoved = context.context_action === "removed";
|
|
1063
|
-
const summary = nonEmptyString(context.display_summary) ?? (isRemoved ? "\u5DF2\u505C\u6B62\u7528\u4E8E\u540E\u7EED\u5BF9\u8BDD" : context.context_action === "retained" ? "\u7EE7\u7EED\u7528\u4E8E\u540E\u7EED\u5BF9\u8BDD" : context.context_kind === "agent-instructions" ? "\u5DF2\u66F4\u65B0\u672C\u6B21\u5BF9\u8BDD\u4F7F\u7528\u7684\u9879\u76EE\u8BF4\u660E" : context.context_kind === "skill-catalog" ? "\u5DF2\u66F4\u65B0\u672C\u6B21\u53EF\u7528\u80FD\u529B" : context.context_kind === "runtime-context" ? "\u5DF2\u66F4\u65B0\u672C\u6B21\u5DE5\u4F5C\u73AF\u5883" : "\u5DF2\u66F4\u65B0\u672C\u6B21\u5BF9\u8BDD\u80CC\u666F");
|
|
1065
|
+
const summary = nonEmptyString(context.display_summary) ?? (isRemoved ? "\u5DF2\u505C\u6B62\u7528\u4E8E\u540E\u7EED\u5BF9\u8BDD" : context.context_action === "retained" ? "\u7EE7\u7EED\u7528\u4E8E\u540E\u7EED\u5BF9\u8BDD" : context.context_kind === "agent-instructions" ? "\u5DF2\u66F4\u65B0\u672C\u6B21\u5BF9\u8BDD\u4F7F\u7528\u7684\u9879\u76EE\u8BF4\u660E" : context.context_kind === "skill-catalog" ? "\u5DF2\u66F4\u65B0\u672C\u6B21\u53EF\u7528\u80FD\u529B" : context.context_kind === "runtime-context" ? "\u5DF2\u66F4\u65B0\u672C\u6B21\u5DE5\u4F5C\u73AF\u5883" : context.context_kind === "workspace-context" ? "\u5DF2\u66F4\u65B0\u672C\u6B21\u5DE5\u4F5C\u533A\u73AF\u5883" : "\u5DF2\u66F4\u65B0\u672C\u6B21\u5BF9\u8BDD\u80CC\u666F");
|
|
1064
1066
|
const detail = isRemoved ? `${title}\u5DF2\u4E0D\u518D\u7528\u4E8E\u540E\u7EED\u5BF9\u8BDD\u3002` : BUILTIN_CONTEXT_DETAILS[context.context_kind] ?? "\u8FD9\u4E9B\u4FE1\u606F\u4F1A\u5E2E\u52A9\u667A\u80FD\u4F53\u7406\u89E3\u5F53\u524D\u4EFB\u52A1\u3002";
|
|
1065
1067
|
return { title, summary, detail, isRemoved };
|
|
1066
1068
|
}
|
|
@@ -1074,6 +1076,7 @@ function buildContextTurn(entry, sequence) {
|
|
|
1074
1076
|
return null;
|
|
1075
1077
|
}
|
|
1076
1078
|
const display = isRecord2(entry.data.display) ? entry.data.display : {};
|
|
1079
|
+
const message = isRecord2(entry.message) ? entry.message : {};
|
|
1077
1080
|
const context = contextProjectionData({
|
|
1078
1081
|
context_kind: typeof entry.source.kind === "string" ? entry.source.kind : null,
|
|
1079
1082
|
context_key: typeof entry.source.key === "string" ? entry.source.key : null,
|
|
@@ -1100,6 +1103,7 @@ function buildContextTurn(entry, sequence) {
|
|
|
1100
1103
|
model: null,
|
|
1101
1104
|
usage: null,
|
|
1102
1105
|
duration_ms: 0,
|
|
1106
|
+
context_content: Object.hasOwn(message, "content") ? message.content : null,
|
|
1103
1107
|
...context
|
|
1104
1108
|
};
|
|
1105
1109
|
}
|
|
@@ -1563,7 +1567,10 @@ var ClientProjectionBuilder = class {
|
|
|
1563
1567
|
);
|
|
1564
1568
|
}
|
|
1565
1569
|
}
|
|
1566
|
-
|
|
1570
|
+
const isNativeProviderResponse = typeof payload.provider === "string" && payload.provider !== "";
|
|
1571
|
+
if (state.toolCalls.length === 0 || isNativeProviderResponse && state.toolCalls.every(
|
|
1572
|
+
(toolCall) => toolCall.status !== "pending" && toolCall.status !== "awaiting_answer"
|
|
1573
|
+
)) {
|
|
1567
1574
|
return this.finalize(loopId, "completed");
|
|
1568
1575
|
}
|
|
1569
1576
|
return this.syncPatch(state);
|
|
@@ -1577,7 +1584,8 @@ var ClientProjectionBuilder = class {
|
|
|
1577
1584
|
const durationMs = typeof rawDuration === "number" && rawDuration >= 0 ? Math.round(rawDuration) : null;
|
|
1578
1585
|
const sl = sourceLoopFor(state.loopId, this.loopDescriptions);
|
|
1579
1586
|
applyToolResult(state, toolCallId, content, status, durationMs, sl);
|
|
1580
|
-
|
|
1587
|
+
const isNativeProviderResult = typeof payload.provider === "string" && payload.provider !== "";
|
|
1588
|
+
if (!isNativeProviderResult && this.shouldFinalizeAfterToolResults(state)) {
|
|
1581
1589
|
return this.finalize(loopId, "completed");
|
|
1582
1590
|
}
|
|
1583
1591
|
return this.syncPatch(state);
|
|
@@ -1618,6 +1626,11 @@ var ClientProjectionBuilder = class {
|
|
|
1618
1626
|
const toolName = String(payload.tool_name ?? "");
|
|
1619
1627
|
const displayName = this.displayNameResolver(toolName);
|
|
1620
1628
|
upsertToolCall(state, toolCallId, toolName, displayName, "");
|
|
1629
|
+
const relatedToolCallId = String(payload.related_tool_call_id ?? "");
|
|
1630
|
+
if (relatedToolCallId && relatedToolCallId !== toolCallId) {
|
|
1631
|
+
const related = state.toolCalls.find((toolCall) => toolCall.id === relatedToolCallId);
|
|
1632
|
+
if (related) related.status = "awaiting_answer";
|
|
1633
|
+
}
|
|
1621
1634
|
return this.syncPatch(state);
|
|
1622
1635
|
}
|
|
1623
1636
|
onChildPause(state, loopId, payload) {
|
|
@@ -1874,6 +1887,7 @@ function projectHistory(entries) {
|
|
|
1874
1887
|
const latestAssistantByLoop = /* @__PURE__ */ new Map();
|
|
1875
1888
|
const pendingChildPauses = /* @__PURE__ */ new Map();
|
|
1876
1889
|
const answeredToolCallIds = /* @__PURE__ */ new Set();
|
|
1890
|
+
const nativeToolTurns = /* @__PURE__ */ new Set();
|
|
1877
1891
|
let latestRootMessage = null;
|
|
1878
1892
|
let latestRootAssistant = null;
|
|
1879
1893
|
let sequence = 0;
|
|
@@ -1933,10 +1947,27 @@ function projectHistory(entries) {
|
|
|
1933
1947
|
duration_ms: numberOrZero(message._duration_ms),
|
|
1934
1948
|
started_at: typeof entry.timestamp === "string" ? entry.timestamp : void 0
|
|
1935
1949
|
};
|
|
1950
|
+
const isNativeToolEntry = role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.some(
|
|
1951
|
+
(toolCall) => isRecord4(toolCall) && typeof toolCall.provider === "string"
|
|
1952
|
+
);
|
|
1953
|
+
const previousTurn = turns[turns.length - 1];
|
|
1954
|
+
if (role === "assistant" && previousTurn?.role === "assistant" && previousTurn.loop_id === loopId && nativeToolTurns.has(previousTurn)) {
|
|
1955
|
+
previousTurn.blocks.push(...turn.blocks);
|
|
1956
|
+
previousTurn.tool_calls.push(...turn.tool_calls);
|
|
1957
|
+
previousTurn.status = turn.status;
|
|
1958
|
+
previousTurn.model = turn.model ?? previousTurn.model;
|
|
1959
|
+
previousTurn.usage = turn.usage ?? previousTurn.usage;
|
|
1960
|
+
previousTurn.duration_ms = turn.duration_ms || previousTurn.duration_ms;
|
|
1961
|
+
if (turn.started_at) previousTurn.started_at = turn.started_at;
|
|
1962
|
+
if (loopId === "root") latestRootMessage = previousTurn;
|
|
1963
|
+
latestAssistantByLoop.set(loopId, previousTurn);
|
|
1964
|
+
continue;
|
|
1965
|
+
}
|
|
1936
1966
|
if (loopId === "root" && (role === "user" || role === "assistant")) {
|
|
1937
1967
|
latestRootMessage = turn;
|
|
1938
1968
|
}
|
|
1939
1969
|
turns.push(turn);
|
|
1970
|
+
if (isNativeToolEntry) nativeToolTurns.add(turn);
|
|
1940
1971
|
if (role === "assistant") latestAssistantByLoop.set(loopId, turn);
|
|
1941
1972
|
if (loopId === "root") {
|
|
1942
1973
|
if (role === "assistant") latestRootAssistant = turn;
|
|
@@ -1945,6 +1976,21 @@ function projectHistory(entries) {
|
|
|
1945
1976
|
for (const toolCall of toolCalls) toolOwners.set(toolCall.id, turn);
|
|
1946
1977
|
continue;
|
|
1947
1978
|
}
|
|
1979
|
+
if (kind === "tool_result") {
|
|
1980
|
+
const data = entry.data ?? {};
|
|
1981
|
+
const toolCallId = String(data.tool_call_id ?? "");
|
|
1982
|
+
const owner = toolOwners.get(toolCallId) ?? findLatestAssistant(turns, loopId);
|
|
1983
|
+
if (owner && toolCallId) {
|
|
1984
|
+
const rawContent = data.content;
|
|
1985
|
+
const content = typeof rawContent === "string" ? rawContent : Array.isArray(rawContent) ? rawContent : String(rawContent ?? "");
|
|
1986
|
+
const status = data.is_error === true ? "error" : inferToolStatus(typeof content === "string" ? content : JSON.stringify(content));
|
|
1987
|
+
setToolCallStatus(owner, toolCallId, status, content, null);
|
|
1988
|
+
if (!owner.blocks.some((block) => block.type === "tool_result" && block.tool_call_id === toolCallId)) {
|
|
1989
|
+
owner.blocks.push({ type: "tool_result", content, tool_call_id: toolCallId });
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
continue;
|
|
1993
|
+
}
|
|
1948
1994
|
if (kind === "mode_change") {
|
|
1949
1995
|
turns.push(markerTurn(id, ++sequence, loopId, "mode_change", entry.data ?? {}));
|
|
1950
1996
|
} else if (kind === "workspace_change") {
|
|
@@ -2193,7 +2239,8 @@ function toCreateSessionPayload(request) {
|
|
|
2193
2239
|
solution_snapshot_session_id: request.solution_snapshot_session_id ?? null,
|
|
2194
2240
|
compaction_ratio: request.compaction_ratio ?? null,
|
|
2195
2241
|
...request.runtime_type ? { runtime_type: request.runtime_type } : {},
|
|
2196
|
-
...request.daemon_id ? { daemon_id: request.daemon_id } : {}
|
|
2242
|
+
...request.daemon_id ? { daemon_id: request.daemon_id } : {},
|
|
2243
|
+
...request.agent_runtime_id ? { agent_runtime_id: request.agent_runtime_id } : {}
|
|
2197
2244
|
};
|
|
2198
2245
|
}
|
|
2199
2246
|
var builtinSolutionIds = /* @__PURE__ */ new Set([
|
|
@@ -3516,6 +3563,7 @@ var AgentSession = class _AgentSession {
|
|
|
3516
3563
|
replayQueue = Promise.resolve();
|
|
3517
3564
|
pendingReplayMessage = null;
|
|
3518
3565
|
pendingReplayMode;
|
|
3566
|
+
pendingReplayKbIds;
|
|
3519
3567
|
recentChatEndAt = 0;
|
|
3520
3568
|
disposed = false;
|
|
3521
3569
|
getAppContext = null;
|
|
@@ -3540,7 +3588,6 @@ var AgentSession = class _AgentSession {
|
|
|
3540
3588
|
const session = new _AgentSession(
|
|
3541
3589
|
sessionId,
|
|
3542
3590
|
{
|
|
3543
|
-
streamTokens: false,
|
|
3544
3591
|
emitEvent: readonlyError,
|
|
3545
3592
|
emitWithAck: async () => readonlyError(),
|
|
3546
3593
|
ensureConnected: readonlyError,
|
|
@@ -3685,6 +3732,7 @@ var AgentSession = class _AgentSession {
|
|
|
3685
3732
|
if (!options.replayDecision) {
|
|
3686
3733
|
this.pendingReplayMessage = content;
|
|
3687
3734
|
this.pendingReplayMode = options.mode;
|
|
3735
|
+
this.pendingReplayKbIds = options.kbIds;
|
|
3688
3736
|
}
|
|
3689
3737
|
const payload = {
|
|
3690
3738
|
session_id: this.sessionId,
|
|
@@ -3732,6 +3780,7 @@ var AgentSession = class _AgentSession {
|
|
|
3732
3780
|
rollbackOptimisticSend(optimisticTurnId, askUserAnswer, optimisticAskAnswer, previousAskAnswer, message) {
|
|
3733
3781
|
this.pendingReplayMessage = null;
|
|
3734
3782
|
this.pendingReplayMode = void 0;
|
|
3783
|
+
this.pendingReplayKbIds = void 0;
|
|
3735
3784
|
this.update((current) => {
|
|
3736
3785
|
let next = optimisticTurnId ? withTurns(
|
|
3737
3786
|
current,
|
|
@@ -3913,7 +3962,7 @@ var AgentSession = class _AgentSession {
|
|
|
3913
3962
|
_handleTurnEvents(events) {
|
|
3914
3963
|
if (!events.length) return;
|
|
3915
3964
|
const terminalChatEndStatus = extractTerminalChatEndStatus(events);
|
|
3916
|
-
if (!terminalChatEndStatus && hasChatRunEvent2(events)) {
|
|
3965
|
+
if (!terminalChatEndStatus && hasChatRunEvent2(events) && this.state.status !== "waiting_for_input") {
|
|
3917
3966
|
this.markRunningIfIdle();
|
|
3918
3967
|
}
|
|
3919
3968
|
if (this.state.turns.length) {
|
|
@@ -3985,8 +4034,10 @@ var AgentSession = class _AgentSession {
|
|
|
3985
4034
|
_handleReplayMismatch(data) {
|
|
3986
4035
|
const message = this.pendingReplayMessage ?? data.actual_message ?? "";
|
|
3987
4036
|
const mode = this.pendingReplayMode;
|
|
4037
|
+
const kbIds = this.pendingReplayKbIds;
|
|
3988
4038
|
this.pendingReplayMessage = null;
|
|
3989
4039
|
this.pendingReplayMode = void 0;
|
|
4040
|
+
this.pendingReplayKbIds = void 0;
|
|
3990
4041
|
const respond = (decision) => {
|
|
3991
4042
|
void this.runtime.emitWithAck(
|
|
3992
4043
|
"chat:send",
|
|
@@ -3994,7 +4045,8 @@ var AgentSession = class _AgentSession {
|
|
|
3994
4045
|
session_id: this.sessionId,
|
|
3995
4046
|
message,
|
|
3996
4047
|
mode,
|
|
3997
|
-
replay_decision: decision
|
|
4048
|
+
replay_decision: decision,
|
|
4049
|
+
kb_ids: kbIds && kbIds.length > 0 ? kbIds : void 0
|
|
3998
4050
|
},
|
|
3999
4051
|
3e4
|
|
4000
4052
|
).then((response) => {
|
|
@@ -4273,8 +4325,7 @@ var AgentSession = class _AgentSession {
|
|
|
4273
4325
|
{
|
|
4274
4326
|
session_id: this.sessionId,
|
|
4275
4327
|
event_format: "raw",
|
|
4276
|
-
resume: true
|
|
4277
|
-
stream_tokens: this.runtime.streamTokens
|
|
4328
|
+
resume: true
|
|
4278
4329
|
},
|
|
4279
4330
|
5e3
|
|
4280
4331
|
).then((response) => {
|
|
@@ -4411,7 +4462,6 @@ var SessionHub = class {
|
|
|
4411
4462
|
}
|
|
4412
4463
|
runtimeFor() {
|
|
4413
4464
|
return {
|
|
4414
|
-
streamTokens: this.client.options?.streamTokens !== false,
|
|
4415
4465
|
emitEvent: (event, data) => {
|
|
4416
4466
|
;
|
|
4417
4467
|
this.client.socket().emit(event, data);
|
|
@@ -4651,7 +4701,7 @@ function resolveAuthToken(options) {
|
|
|
4651
4701
|
|
|
4652
4702
|
// src/version.ts
|
|
4653
4703
|
var SDK_NAME = "agent-client";
|
|
4654
|
-
var SDK_VERSION = true ? "2610.0.0-beta.
|
|
4704
|
+
var SDK_VERSION = true ? "2610.0.0-beta.28" : "1.1.1";
|
|
4655
4705
|
|
|
4656
4706
|
// src/socket.ts
|
|
4657
4707
|
function withSdkIdentity(auth) {
|