@blade-hq/agent-client 2608.0.5-beta.0 → 2608.0.5
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 +5 -137
- package/dist/blade-client.d.ts +0 -2
- package/dist/index.d.ts +8 -10
- package/dist/index.js +65 -291
- package/dist/index.js.map +1 -1
- package/dist/resources/auth.d.ts +0 -26
- package/dist/resources/models.d.ts +0 -22
- package/dist/resources/sessions.d.ts +3 -45
- package/dist/schemas/message-utils.d.ts +1 -11
- package/dist/schemas/projection.d.ts +0 -14
- package/dist/schemas/session.d.ts +1 -18
- package/dist/session/agent-session.d.ts +1 -23
- package/dist/session/state.d.ts +1 -14
- package/dist/shared/projection/builder.d.ts +0 -5
- package/dist/shared/projection/helpers.d.ts +0 -10
- package/dist/shared/projection/index.d.ts +1 -1
- package/dist/types/socket-events.d.ts +0 -6
- package/package.json +1 -1
- package/public-api.md +4 -179
- package/dist/schemas/projection-utils.d.ts +0 -3
package/dist/index.js
CHANGED
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
function isAuthCallbackMessage(value) {
|
|
3
3
|
return typeof value === "object" && value !== null && value.type === "blade-agent:sdk-auth";
|
|
4
4
|
}
|
|
5
|
-
var AUTH_ERROR_HINTS = {
|
|
6
|
-
pat_unavailable: "\u6CA1\u80FD\u4E3A\u4F60\u51C6\u5907\u8BBF\u95EE\u51ED\u636E\u3002\u8BF7\u9000\u51FA\u540E\u91CD\u65B0\u767B\u5F55 Blade \u518D\u8BD5\u4E00\u6B21\uFF1B\u82E5\u4ECD\u7136\u5931\u8D25\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u3002"
|
|
7
|
-
};
|
|
8
5
|
function randomState() {
|
|
9
6
|
const bytes = new Uint8Array(24);
|
|
10
7
|
crypto.getRandomValues(bytes);
|
|
@@ -82,22 +79,18 @@ async function loginWithPopup(client, options = {}) {
|
|
|
82
79
|
if (event.data.state !== state) return;
|
|
83
80
|
const message = event.data;
|
|
84
81
|
stopCloseWatch();
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
};
|
|
82
|
+
try {
|
|
83
|
+
popup.close();
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
91
86
|
if (message.status === "denied") {
|
|
92
|
-
closePopup();
|
|
93
87
|
settle(() => reject(new Error("\u4F60\u53D6\u6D88\u4E86\u6388\u6743\uFF0C\u672A\u5B8C\u6210\u767B\u5F55\u3002")));
|
|
94
88
|
return;
|
|
95
89
|
}
|
|
96
90
|
if (message.status !== "success" || !message.code) {
|
|
97
|
-
settle(() => reject(new Error(
|
|
91
|
+
settle(() => reject(new Error(message.error || "\u767B\u5F55\u5931\u8D25\uFF0C\u672A\u53D6\u5F97\u6388\u6743\u7801\u3002")));
|
|
98
92
|
return;
|
|
99
93
|
}
|
|
100
|
-
closePopup();
|
|
101
94
|
client.json("POST", "/api/auth/sdk/token", {
|
|
102
95
|
code: message.code,
|
|
103
96
|
state,
|
|
@@ -181,24 +174,6 @@ var AuthResource = class {
|
|
|
181
174
|
login(options) {
|
|
182
175
|
return this.client.login(options);
|
|
183
176
|
}
|
|
184
|
-
/**
|
|
185
|
-
* 用一次性 code 换 PAT。给**服务端**用:浏览器把 code 交给你自己的后端,
|
|
186
|
-
* 后端换到的 PAT 不进浏览器。浏览器里直接用 `login()` 就够了。
|
|
187
|
-
*
|
|
188
|
-
* 服务端调用时会自己补上 `Origin` 头(浏览器会自动带,服务端不会,缺了
|
|
189
|
-
* 后端报 `missing_request_origin`)。
|
|
190
|
-
*/
|
|
191
|
-
exchangeCode(params) {
|
|
192
|
-
return this.client.jsonFromInit("/api/auth/sdk/token", {
|
|
193
|
-
method: "POST",
|
|
194
|
-
headers: { Origin: params.clientOrigin },
|
|
195
|
-
body: JSON.stringify({
|
|
196
|
-
code: params.code,
|
|
197
|
-
state: params.state,
|
|
198
|
-
client_origin: params.clientOrigin
|
|
199
|
-
})
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
177
|
/** 清除 login() 存储的令牌。 */
|
|
203
178
|
logoutToken() {
|
|
204
179
|
this.client.logoutToken();
|
|
@@ -350,11 +325,7 @@ var HeadlessResource = class {
|
|
|
350
325
|
socket.on("chat:start", onChatStart);
|
|
351
326
|
socket.on("chat:end", onChatEnd);
|
|
352
327
|
socket.on("system:error", onSystemError);
|
|
353
|
-
socket.emit("session:subscribe", {
|
|
354
|
-
session_id,
|
|
355
|
-
event_format: "raw",
|
|
356
|
-
stream_tokens: this.client.options.streamTokens !== false
|
|
357
|
-
});
|
|
328
|
+
socket.emit("session:subscribe", { session_id, event_format: "raw" });
|
|
358
329
|
socket.emit(
|
|
359
330
|
"chat:send",
|
|
360
331
|
{
|
|
@@ -436,47 +407,6 @@ var ModelsResource = class {
|
|
|
436
407
|
}
|
|
437
408
|
};
|
|
438
409
|
|
|
439
|
-
// src/schemas/session.ts
|
|
440
|
-
import { type } from "arktype";
|
|
441
|
-
var SessionStatus = type(
|
|
442
|
-
"'created' | 'running' | 'completed' | 'failed' | 'interrupted' | 'waiting_for_input'"
|
|
443
|
-
);
|
|
444
|
-
var DEFAULT_REPLAY_SPEED = 5;
|
|
445
|
-
var SessionInfo = type({
|
|
446
|
-
id: "string",
|
|
447
|
-
intent: "string",
|
|
448
|
-
status: SessionStatus,
|
|
449
|
-
created_at: "string",
|
|
450
|
-
updated_at: "string",
|
|
451
|
-
"shared?": "boolean",
|
|
452
|
-
"memory_enabled?": "boolean",
|
|
453
|
-
"is_persistent?": "boolean",
|
|
454
|
-
"is_headless?": "boolean",
|
|
455
|
-
"viewer_role?": "'owner' | 'viewer'",
|
|
456
|
-
"template_id?": "string | null",
|
|
457
|
-
"model?": "string | null",
|
|
458
|
-
"enable_thinking?": "boolean | null",
|
|
459
|
-
"solution_id?": "string | null",
|
|
460
|
-
"solution_ref?": "unknown",
|
|
461
|
-
"biz_role_id?": "string | null",
|
|
462
|
-
"solution?": "unknown",
|
|
463
|
-
"plan_summary?": "string | null",
|
|
464
|
-
"primary_skill_id?": "string | null",
|
|
465
|
-
// ship-attack v2:后端 engine.set_bound_skill 写入的"绑定 skill id"。
|
|
466
|
-
// 未绑定 / 非 ship-attack session 为 null。
|
|
467
|
-
"bound_skill_id?": "string | null",
|
|
468
|
-
"replay_state?": "unknown",
|
|
469
|
-
"is_pinned?": "boolean",
|
|
470
|
-
"pinned_at?": "string | null",
|
|
471
|
-
"is_example?": "boolean",
|
|
472
|
-
"ports?": "unknown",
|
|
473
|
-
"disable_tools?": "string[]",
|
|
474
|
-
"runtime_type?": "string | null",
|
|
475
|
-
"daemon_id?": "string | null",
|
|
476
|
-
"workspace_path?": "string | null",
|
|
477
|
-
"match?": "unknown"
|
|
478
|
-
});
|
|
479
|
-
|
|
480
410
|
// src/session/definition.ts
|
|
481
411
|
var SessionSetupError = class extends Error {
|
|
482
412
|
constructor(message, stage, sessionId, options) {
|
|
@@ -897,28 +827,6 @@ function sourceLoopFor(loopId, loopDescriptions) {
|
|
|
897
827
|
if (!description) return null;
|
|
898
828
|
return { loop_name: loopId, description };
|
|
899
829
|
}
|
|
900
|
-
var MAX_FINAL_ARTIFACTS = 20;
|
|
901
|
-
function normalizeFinalArtifacts(raw) {
|
|
902
|
-
if (!Array.isArray(raw)) return [];
|
|
903
|
-
const artifacts = [];
|
|
904
|
-
const seen = /* @__PURE__ */ new Set();
|
|
905
|
-
for (const item of raw) {
|
|
906
|
-
if (typeof item !== "object" || item === null) continue;
|
|
907
|
-
const record = item;
|
|
908
|
-
const target = String(record.target ?? "").trim();
|
|
909
|
-
if (!target || seen.has(target)) continue;
|
|
910
|
-
const isLink = /^https?:\/\//i.test(target);
|
|
911
|
-
if (!isLink && target.split("/").includes("..")) continue;
|
|
912
|
-
seen.add(target);
|
|
913
|
-
artifacts.push({
|
|
914
|
-
kind: isLink ? "link" : "file",
|
|
915
|
-
target,
|
|
916
|
-
label: String(record.label ?? "").trim()
|
|
917
|
-
});
|
|
918
|
-
if (artifacts.length === MAX_FINAL_ARTIFACTS) break;
|
|
919
|
-
}
|
|
920
|
-
return artifacts;
|
|
921
|
-
}
|
|
922
830
|
function normalizePostChatFollowup(data, assistantEntryId) {
|
|
923
831
|
const raw = data.suggestions;
|
|
924
832
|
const suggestions = [];
|
|
@@ -930,17 +838,11 @@ function normalizePostChatFollowup(data, assistantEntryId) {
|
|
|
930
838
|
}
|
|
931
839
|
}
|
|
932
840
|
const recaption = String(data.recaption ?? "");
|
|
933
|
-
|
|
934
|
-
const feedbackEligible = data.feedback_eligible === true;
|
|
935
|
-
if (suggestions.length === 0 && !recaption && finalArtifacts.length === 0 && !feedbackEligible)
|
|
936
|
-
return null;
|
|
841
|
+
if (suggestions.length === 0 && !recaption) return null;
|
|
937
842
|
return {
|
|
938
843
|
assistant_entry_id: assistantEntryId,
|
|
939
844
|
recaption,
|
|
940
|
-
suggestions: suggestions.slice(0, 3)
|
|
941
|
-
final_artifacts: finalArtifacts,
|
|
942
|
-
feedback_eligible: feedbackEligible,
|
|
943
|
-
feedback_scope: "latest_result"
|
|
845
|
+
suggestions: suggestions.slice(0, 3)
|
|
944
846
|
};
|
|
945
847
|
}
|
|
946
848
|
function normalizeChildPause(pausePayload) {
|
|
@@ -1024,60 +926,11 @@ function toolStatusFromResult(result) {
|
|
|
1024
926
|
}
|
|
1025
927
|
|
|
1026
928
|
// src/shared/projection/builder.ts
|
|
1027
|
-
function hasChatRunEvent(events) {
|
|
1028
|
-
return events.some(
|
|
1029
|
-
(event) => event.type !== "session:post_chat_followup" && !event.type.startsWith("compaction:")
|
|
1030
|
-
);
|
|
1031
|
-
}
|
|
1032
|
-
function acceptedPostChatFollowupCompletesLatestRun(events, updates) {
|
|
1033
|
-
const acceptedAssistantEntryIds = new Set(
|
|
1034
|
-
updates.flatMap((update) => {
|
|
1035
|
-
if (update.kind !== "upsert") return [];
|
|
1036
|
-
const followup = update.turn.post_chat_followup;
|
|
1037
|
-
return followup?.assistant_entry_id ? [followup.assistant_entry_id] : [];
|
|
1038
|
-
})
|
|
1039
|
-
);
|
|
1040
|
-
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
1041
|
-
const event = events[index];
|
|
1042
|
-
if (event?.type !== "session:post_chat_followup") continue;
|
|
1043
|
-
const assistantEntryId = String(event.payload.assistant_entry_id ?? "");
|
|
1044
|
-
return acceptedAssistantEntryIds.has(assistantEntryId) && !hasChatRunEvent(events.slice(index + 1));
|
|
1045
|
-
}
|
|
1046
|
-
return false;
|
|
1047
|
-
}
|
|
1048
929
|
function isConversationTurn(turn) {
|
|
1049
930
|
return (turn.role === "user" || turn.role === "assistant") && (turn.kind ?? "message") === "message" && !turn.blocks.some(
|
|
1050
931
|
(block) => block.type === "mode_change" || block.type === "plan_status" || block.type === "ask_user_answer"
|
|
1051
932
|
);
|
|
1052
933
|
}
|
|
1053
|
-
function completedResponseText(content) {
|
|
1054
|
-
if (typeof content === "string") return content;
|
|
1055
|
-
if (!Array.isArray(content)) return content == null ? "" : String(content);
|
|
1056
|
-
return content.filter(
|
|
1057
|
-
(part) => typeof part === "object" && part !== null && !Array.isArray(part)
|
|
1058
|
-
).filter((part) => part.type === "text").map((part) => String(part.text ?? "")).join("");
|
|
1059
|
-
}
|
|
1060
|
-
function replaceTextContent(state, content) {
|
|
1061
|
-
if (state.blocks.some((block) => block.type === "text")) return;
|
|
1062
|
-
const replacement = { type: "text", content };
|
|
1063
|
-
const blocks = [];
|
|
1064
|
-
let inserted = false;
|
|
1065
|
-
for (const block of state.blocks) {
|
|
1066
|
-
if (block.type === "text") {
|
|
1067
|
-
if (content && !inserted) {
|
|
1068
|
-
blocks.push(replacement);
|
|
1069
|
-
inserted = true;
|
|
1070
|
-
}
|
|
1071
|
-
continue;
|
|
1072
|
-
}
|
|
1073
|
-
blocks.push(block);
|
|
1074
|
-
}
|
|
1075
|
-
if (content && !inserted) {
|
|
1076
|
-
const toolIndex = blocks.findIndex((block) => block.type === "tool_use");
|
|
1077
|
-
blocks.splice(toolIndex < 0 ? blocks.length : toolIndex, 0, replacement);
|
|
1078
|
-
}
|
|
1079
|
-
state.blocks = blocks;
|
|
1080
|
-
}
|
|
1081
934
|
var ClientProjectionBuilder = class {
|
|
1082
935
|
activeTurns = /* @__PURE__ */ new Map();
|
|
1083
936
|
lastTurnIds = /* @__PURE__ */ new Map();
|
|
@@ -1160,9 +1013,6 @@ var ClientProjectionBuilder = class {
|
|
|
1160
1013
|
return this.onDelta(state, "thinking", "", String(payload.content ?? ""));
|
|
1161
1014
|
case "llm:content:delta":
|
|
1162
1015
|
return this.onDelta(state, "text", "", String(payload.content ?? ""));
|
|
1163
|
-
case "llm:content:complete":
|
|
1164
|
-
replaceTextContent(state, String(payload.content ?? ""));
|
|
1165
|
-
return this.syncPatch(state);
|
|
1166
1016
|
case "llm:tool_call:created":
|
|
1167
1017
|
return this.onToolCallCreated(state, payload);
|
|
1168
1018
|
case "llm:response:done":
|
|
@@ -1452,9 +1302,6 @@ var ClientProjectionBuilder = class {
|
|
|
1452
1302
|
if (typeof payload.usage === "object" && payload.usage !== null) {
|
|
1453
1303
|
state.usage = { ...payload.usage };
|
|
1454
1304
|
}
|
|
1455
|
-
if ("content" in payload) {
|
|
1456
|
-
replaceTextContent(state, completedResponseText(payload.content));
|
|
1457
|
-
}
|
|
1458
1305
|
const toolCalls = payload.tool_calls;
|
|
1459
1306
|
if (Array.isArray(toolCalls)) {
|
|
1460
1307
|
for (const raw of toolCalls) {
|
|
@@ -2258,11 +2105,6 @@ var SessionsResource = class {
|
|
|
2258
2105
|
listSessionsWithSkillData() {
|
|
2259
2106
|
return this.client.json("GET", "/api/sessions/with-skill-data");
|
|
2260
2107
|
}
|
|
2261
|
-
searchOwnedContent(params) {
|
|
2262
|
-
const searchParams = new URLSearchParams({ q: params.q.trim() });
|
|
2263
|
-
if (params.limit !== void 0) searchParams.set("limit", String(params.limit));
|
|
2264
|
-
return this.client.json("GET", `/api/search?${searchParams.toString()}`);
|
|
2265
|
-
}
|
|
2266
2108
|
createSession(intent, template_id, primary_skill_id) {
|
|
2267
2109
|
return this.createSessionWithRequest({ intent, template_id, primary_skill_id });
|
|
2268
2110
|
}
|
|
@@ -2288,16 +2130,12 @@ var SessionsResource = class {
|
|
|
2288
2130
|
pinSession(sessionId, pinned) {
|
|
2289
2131
|
return this.client.json("PATCH", `/api/sessions/${sessionId}/pin`, { pinned });
|
|
2290
2132
|
}
|
|
2291
|
-
startReplaySession(sourceSessionId, speed =
|
|
2133
|
+
startReplaySession(sourceSessionId, speed = 5) {
|
|
2292
2134
|
return this.client.json("POST", `/api/sessions/${sourceSessionId}/replay`, { speed });
|
|
2293
2135
|
}
|
|
2294
2136
|
updateReplaySession(sessionId, payload) {
|
|
2295
2137
|
return this.client.json("PATCH", `/api/sessions/${sessionId}/replay`, payload);
|
|
2296
2138
|
}
|
|
2297
|
-
/** 查询会话能否作为回放来源;不支持时 reason 可直接展示,用来提前禁用入口。 */
|
|
2298
|
-
getReplayPreview(sessionId) {
|
|
2299
|
-
return this.client.json("GET", `/api/sessions/${sessionId}/replay/preview`);
|
|
2300
|
-
}
|
|
2301
2139
|
updateSharing(sessionId, shared) {
|
|
2302
2140
|
return this.client.json("PATCH", `/api/sessions/${sessionId}/sharing`, { shared });
|
|
2303
2141
|
}
|
|
@@ -2329,16 +2167,6 @@ var SessionsResource = class {
|
|
|
2329
2167
|
);
|
|
2330
2168
|
return projectHistory(entries);
|
|
2331
2169
|
}
|
|
2332
|
-
listResultFeedback(sessionId) {
|
|
2333
|
-
return this.client.json("GET", `/api/sessions/${encodeURIComponent(sessionId)}/feedback`);
|
|
2334
|
-
}
|
|
2335
|
-
putResultFeedback(sessionId, assistantEntryId, feedback) {
|
|
2336
|
-
return this.client.json(
|
|
2337
|
-
"PUT",
|
|
2338
|
-
`/api/sessions/${encodeURIComponent(sessionId)}/turns/${encodeURIComponent(assistantEntryId)}/feedback`,
|
|
2339
|
-
feedback
|
|
2340
|
-
);
|
|
2341
|
-
}
|
|
2342
2170
|
getSessionContextStats(sessionId, init) {
|
|
2343
2171
|
return this.client.jsonFromInit(`/api/sessions/${sessionId}/context-stats`, init);
|
|
2344
2172
|
}
|
|
@@ -2761,15 +2589,10 @@ function contentPreview(content, maxLen = 80) {
|
|
|
2761
2589
|
const text = getTextContent(content).trim();
|
|
2762
2590
|
return text.length > maxLen ? `${text.slice(0, maxLen)}\u2026` : text;
|
|
2763
2591
|
}
|
|
2764
|
-
function transformSlashCommand(skillName, rawInput
|
|
2592
|
+
function transformSlashCommand(skillName, rawInput) {
|
|
2765
2593
|
const prompt = rawInput.replace(`<skill>${skillName}</skill>`, "").trim();
|
|
2766
|
-
|
|
2767
|
-
return prompt ? `\u8BF7\u4F7F\u7528 ${skillName} skill \u5B8C\u6210\u4EFB\u52A1
|
|
2594
|
+
return prompt ? `\u8BF7\u4F7F\u7528 ${skillName} skill \u5B8C\u6210\u4EFB\u52A1
|
|
2768
2595
|
${prompt}` : `\u8BF7\u4F7F\u7528 ${skillName} skill \u5B8C\u6210\u4EFB\u52A1`;
|
|
2769
|
-
}
|
|
2770
|
-
const steps = installed ? `\u8BF7\u5148\u8FD0\u884C blade hub skill use ${skillName} \u52A0\u8F7D\u6280\u80FD` : `\u8BE5\u6280\u80FD\u5C1A\u672A\u5B89\u88C5\u3002\u8BF7\u5148\u8FD0\u884C blade hub skill install ${skillName} \u5B89\u88C5\uFF0C\u518D\u8FD0\u884C blade hub skill use ${skillName} \u52A0\u8F7D`;
|
|
2771
|
-
return prompt ? `${steps}\uFF0C\u7136\u540E\u5B8C\u6210\u4EFB\u52A1\uFF1A
|
|
2772
|
-
${prompt}` : `${steps}\uFF0C\u7136\u540E\u4F7F\u7528\u5B83\u5B8C\u6210\u4EFB\u52A1`;
|
|
2773
2596
|
}
|
|
2774
2597
|
var ATTACHMENT_TAG_RE = /\[附件:\s*([^\]]+)\](?:[ \t]*已上传到工作区路径:[ \t]*([^\r\n]+))?/g;
|
|
2775
2598
|
var CONTEXT_PART_RE = /^\[上下文:\s*([^\]]+)\]\n([\s\S]*)$/;
|
|
@@ -2855,14 +2678,6 @@ function groupMessagesByLoop(messages) {
|
|
|
2855
2678
|
}
|
|
2856
2679
|
|
|
2857
2680
|
// src/session/state.ts
|
|
2858
|
-
function toReplaySnapshot(raw) {
|
|
2859
|
-
if (!raw || !raw.status) return null;
|
|
2860
|
-
return {
|
|
2861
|
-
isReplay: raw.status === "replay",
|
|
2862
|
-
speed: raw.speed ?? 1,
|
|
2863
|
-
sourceSessionId: raw.source_session_id ?? null
|
|
2864
|
-
};
|
|
2865
|
-
}
|
|
2866
2681
|
function createInitialSessionState(sessionId) {
|
|
2867
2682
|
return {
|
|
2868
2683
|
sessionId,
|
|
@@ -2875,9 +2690,7 @@ function createInitialSessionState(sessionId) {
|
|
|
2875
2690
|
errorMessage: null,
|
|
2876
2691
|
askAnswers: {},
|
|
2877
2692
|
agentLoops: {},
|
|
2878
|
-
activeCompaction: null
|
|
2879
|
-
replay: null,
|
|
2880
|
-
viewerRole: null
|
|
2693
|
+
activeCompaction: null
|
|
2881
2694
|
};
|
|
2882
2695
|
}
|
|
2883
2696
|
function parseAgentDescription(argumentsJson) {
|
|
@@ -3307,7 +3120,7 @@ function extractTerminalChatEndStatus(events) {
|
|
|
3307
3120
|
}
|
|
3308
3121
|
return null;
|
|
3309
3122
|
}
|
|
3310
|
-
function
|
|
3123
|
+
function hasChatRunEvent(events) {
|
|
3311
3124
|
return events.some(
|
|
3312
3125
|
(event) => event.type !== "session:post_chat_followup" && !event.type.startsWith("compaction:")
|
|
3313
3126
|
);
|
|
@@ -3328,11 +3141,6 @@ var AgentSession = class _AgentSession {
|
|
|
3328
3141
|
patchFlushCancel = null;
|
|
3329
3142
|
joined = false;
|
|
3330
3143
|
joinPending = null;
|
|
3331
|
-
// 回放控制请求排成一条队列。连着点"5x"再点"退出回放"时,并发发出去的两个
|
|
3332
|
-
// 请求响应可能乱序回来,晚到的旧值会把已经退出的会话又显示成回放中;用
|
|
3333
|
-
// 序号丢弃过期响应又会在失败时留下中间态。串行执行就没有这些情况:每个
|
|
3334
|
-
// 响应都是当时最新的,失败也只影响自己。
|
|
3335
|
-
replayQueue = Promise.resolve();
|
|
3336
3144
|
pendingReplayMessage = null;
|
|
3337
3145
|
pendingReplayMode;
|
|
3338
3146
|
recentChatEndAt = 0;
|
|
@@ -3359,15 +3167,10 @@ var AgentSession = class _AgentSession {
|
|
|
3359
3167
|
const session = new _AgentSession(
|
|
3360
3168
|
sessionId,
|
|
3361
3169
|
{
|
|
3362
|
-
streamTokens: false,
|
|
3363
3170
|
emitEvent: readonlyError,
|
|
3364
3171
|
emitWithAck: async () => readonlyError(),
|
|
3365
3172
|
ensureConnected: readonlyError,
|
|
3366
3173
|
fetchTurns: async () => turns,
|
|
3367
|
-
// 静态历史没有回放身份可言,给个空详情即可,不要抛错——_bootstrap
|
|
3368
|
-
// 不会跑到这里,但保持只读语义一致。
|
|
3369
|
-
fetchSessionInfo: async () => ({ replay_state: null }),
|
|
3370
|
-
updateReplay: async () => readonlyError(),
|
|
3371
3174
|
listDir: async () => readonlyError(),
|
|
3372
3175
|
countFiles: async () => readonlyError(),
|
|
3373
3176
|
downloadFile: async () => readonlyError(),
|
|
@@ -3659,13 +3462,10 @@ var AgentSession = class _AgentSession {
|
|
|
3659
3462
|
this.joinPending = null;
|
|
3660
3463
|
try {
|
|
3661
3464
|
await this.ensureJoined();
|
|
3662
|
-
await
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
}),
|
|
3667
|
-
this.syncReplayFromSession()
|
|
3668
|
-
]);
|
|
3465
|
+
await this.syncTurnsFromHistory({
|
|
3466
|
+
clearOnEmpty: true,
|
|
3467
|
+
preserveChangesSince: turnsBeforeRejoin
|
|
3468
|
+
});
|
|
3669
3469
|
} catch {
|
|
3670
3470
|
}
|
|
3671
3471
|
}
|
|
@@ -3673,40 +3473,6 @@ var AgentSession = class _AgentSession {
|
|
|
3673
3473
|
async _bootstrap() {
|
|
3674
3474
|
await this.syncTurnsFromHistory({ suppressErrors: false });
|
|
3675
3475
|
await this.ensureJoined();
|
|
3676
|
-
await this.syncReplayFromSession();
|
|
3677
|
-
}
|
|
3678
|
-
/** 改回放是 owner 专属(服务端 PATCH 走 _get_owned_session)。 */
|
|
3679
|
-
get canControlReplay() {
|
|
3680
|
-
return this.state.viewerRole !== "viewer";
|
|
3681
|
-
}
|
|
3682
|
-
/** 拉一次会话详情,填回放状态和只读身份;失败按非回放会话处理,不挡启动。 */
|
|
3683
|
-
async syncReplayFromSession() {
|
|
3684
|
-
try {
|
|
3685
|
-
const info = await this.runtime.fetchSessionInfo(this.sessionId);
|
|
3686
|
-
const replay = toReplaySnapshot(info.replay_state);
|
|
3687
|
-
const viewerRole = info.viewer_role ?? null;
|
|
3688
|
-
this.update((s) => ({ ...s, replay, viewerRole }));
|
|
3689
|
-
} catch {
|
|
3690
|
-
}
|
|
3691
|
-
}
|
|
3692
|
-
/** 调整回放倍速;不是回放会话、或只读身份时什么都不做。 */
|
|
3693
|
-
async setReplaySpeed(speed) {
|
|
3694
|
-
if (!this.state.replay?.isReplay || !this.canControlReplay) return;
|
|
3695
|
-
await this.applyReplayControl({ speed });
|
|
3696
|
-
}
|
|
3697
|
-
/** 退出回放,之后的对话交给真实模型运行;不是回放会话、或只读身份时什么都不做。 */
|
|
3698
|
-
async exitReplay() {
|
|
3699
|
-
if (!this.state.replay?.isReplay || !this.canControlReplay) return;
|
|
3700
|
-
await this.applyReplayControl({ status: "autonomous" });
|
|
3701
|
-
}
|
|
3702
|
-
/** 把一次回放控制请求排进队列;前一个完成后才发出,响应直接安装。 */
|
|
3703
|
-
applyReplayControl(payload) {
|
|
3704
|
-
const run = this.replayQueue.then(async () => {
|
|
3705
|
-
const result = await this.runtime.updateReplay(this.sessionId, payload);
|
|
3706
|
-
this.update((s) => ({ ...s, replay: toReplaySnapshot(result) }));
|
|
3707
|
-
});
|
|
3708
|
-
this.replayQueue = run.catch(() => void 0);
|
|
3709
|
-
return run;
|
|
3710
3476
|
}
|
|
3711
3477
|
/** @internal */
|
|
3712
3478
|
_handleTurnStart(turn) {
|
|
@@ -3733,7 +3499,7 @@ var AgentSession = class _AgentSession {
|
|
|
3733
3499
|
_handleTurnEvents(events) {
|
|
3734
3500
|
if (!events.length) return;
|
|
3735
3501
|
const terminalChatEndStatus = extractTerminalChatEndStatus(events);
|
|
3736
|
-
if (!terminalChatEndStatus &&
|
|
3502
|
+
if (!terminalChatEndStatus && hasChatRunEvent(events)) {
|
|
3737
3503
|
this.markRunningIfIdle();
|
|
3738
3504
|
}
|
|
3739
3505
|
if (this.state.turns.length) {
|
|
@@ -3747,8 +3513,8 @@ var AgentSession = class _AgentSession {
|
|
|
3747
3513
|
this.emitter.emit("workspaceChanged", {});
|
|
3748
3514
|
}
|
|
3749
3515
|
}
|
|
3750
|
-
if (terminalChatEndStatus
|
|
3751
|
-
this.
|
|
3516
|
+
if (terminalChatEndStatus) {
|
|
3517
|
+
this.finishStreaming(terminalChatEndStatus);
|
|
3752
3518
|
}
|
|
3753
3519
|
}
|
|
3754
3520
|
/** @internal */
|
|
@@ -3758,7 +3524,10 @@ var AgentSession = class _AgentSession {
|
|
|
3758
3524
|
/** @internal */
|
|
3759
3525
|
_handleChatEnd(status) {
|
|
3760
3526
|
this.flushPatches();
|
|
3761
|
-
this.
|
|
3527
|
+
this.finishStreaming(status);
|
|
3528
|
+
this.recentChatEndAt = Date.now();
|
|
3529
|
+
void this.syncTurnsFromHistory();
|
|
3530
|
+
this.emitter.emit("chatEnd", { status });
|
|
3762
3531
|
}
|
|
3763
3532
|
/** @internal */
|
|
3764
3533
|
_handleSystemError(message) {
|
|
@@ -3783,10 +3552,6 @@ var AgentSession = class _AgentSession {
|
|
|
3783
3552
|
if (data.status) {
|
|
3784
3553
|
this.update((s) => ({ ...s, status: data.status ?? s.status }));
|
|
3785
3554
|
}
|
|
3786
|
-
if (data.replay_state !== void 0) {
|
|
3787
|
-
const replay = toReplaySnapshot(data.replay_state);
|
|
3788
|
-
this.update((s) => ({ ...s, replay }));
|
|
3789
|
-
}
|
|
3790
3555
|
this.emitter.emit("sessionUpdated", {
|
|
3791
3556
|
intent: data.intent,
|
|
3792
3557
|
status: data.status,
|
|
@@ -3902,12 +3667,6 @@ var AgentSession = class _AgentSession {
|
|
|
3902
3667
|
return next;
|
|
3903
3668
|
});
|
|
3904
3669
|
}
|
|
3905
|
-
completeChat(status) {
|
|
3906
|
-
this.finishStreaming(status);
|
|
3907
|
-
this.recentChatEndAt = Date.now();
|
|
3908
|
-
void this.syncTurnsFromHistory();
|
|
3909
|
-
this.emitter.emit("chatEnd", { status });
|
|
3910
|
-
}
|
|
3911
3670
|
applyTurn(turn) {
|
|
3912
3671
|
this.flushPatches();
|
|
3913
3672
|
const previous = this.state;
|
|
@@ -4090,12 +3849,7 @@ var AgentSession = class _AgentSession {
|
|
|
4090
3849
|
if (this.joinPending) return this.joinPending;
|
|
4091
3850
|
const join = this.runtime.emitWithAck(
|
|
4092
3851
|
"session:subscribe",
|
|
4093
|
-
{
|
|
4094
|
-
session_id: this.sessionId,
|
|
4095
|
-
event_format: "raw",
|
|
4096
|
-
resume: true,
|
|
4097
|
-
stream_tokens: this.runtime.streamTokens
|
|
4098
|
-
},
|
|
3852
|
+
{ session_id: this.sessionId, event_format: "raw", resume: true },
|
|
4099
3853
|
5e3
|
|
4100
3854
|
).then((response) => {
|
|
4101
3855
|
if (response && response.ok === false) {
|
|
@@ -4231,7 +3985,6 @@ var SessionHub = class {
|
|
|
4231
3985
|
}
|
|
4232
3986
|
runtimeFor() {
|
|
4233
3987
|
return {
|
|
4234
|
-
streamTokens: this.client.options?.streamTokens !== false,
|
|
4235
3988
|
emitEvent: (event, data) => {
|
|
4236
3989
|
;
|
|
4237
3990
|
this.client.socket().emit(event, data);
|
|
@@ -4248,8 +4001,6 @@ var SessionHub = class {
|
|
|
4248
4001
|
}),
|
|
4249
4002
|
ensureConnected: () => this.ensureConnected(),
|
|
4250
4003
|
fetchTurns: (sessionId) => this.client.sessions.getSessionTurns(sessionId),
|
|
4251
|
-
fetchSessionInfo: (sessionId) => this.client.sessions.getSession(sessionId),
|
|
4252
|
-
updateReplay: (sessionId, payload) => this.client.sessions.updateReplaySession(sessionId, payload).then((result) => result.replay_state ?? null),
|
|
4253
4004
|
listDir: (sessionId, dirPath) => this.client.sessions.listDir(sessionId, dirPath),
|
|
4254
4005
|
countFiles: (sessionId, dirPath) => this.client.sessions.countFiles(sessionId, dirPath),
|
|
4255
4006
|
downloadFile: (sessionId, filePath, downloadName) => this.client.sessions.downloadFile(sessionId, filePath, downloadName),
|
|
@@ -4471,7 +4222,7 @@ function resolveAuthToken(options) {
|
|
|
4471
4222
|
|
|
4472
4223
|
// src/version.ts
|
|
4473
4224
|
var SDK_NAME = "agent-client";
|
|
4474
|
-
var SDK_VERSION = true ? "2608.0.5
|
|
4225
|
+
var SDK_VERSION = true ? "2608.0.5" : "1.1.1";
|
|
4475
4226
|
|
|
4476
4227
|
// src/socket.ts
|
|
4477
4228
|
function withSdkIdentity(auth) {
|
|
@@ -4923,18 +4674,45 @@ function connectEmbedded(options) {
|
|
|
4923
4674
|
};
|
|
4924
4675
|
}
|
|
4925
4676
|
|
|
4926
|
-
// src/schemas/
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
4677
|
+
// src/schemas/session.ts
|
|
4678
|
+
import { type } from "arktype";
|
|
4679
|
+
var SessionStatus = type(
|
|
4680
|
+
"'created' | 'running' | 'completed' | 'failed' | 'interrupted' | 'waiting_for_input'"
|
|
4681
|
+
);
|
|
4682
|
+
var SessionInfo = type({
|
|
4683
|
+
id: "string",
|
|
4684
|
+
intent: "string",
|
|
4685
|
+
status: SessionStatus,
|
|
4686
|
+
created_at: "string",
|
|
4687
|
+
updated_at: "string",
|
|
4688
|
+
"shared?": "boolean",
|
|
4689
|
+
"memory_enabled?": "boolean",
|
|
4690
|
+
"is_persistent?": "boolean",
|
|
4691
|
+
"is_headless?": "boolean",
|
|
4692
|
+
"viewer_role?": "'owner' | 'viewer'",
|
|
4693
|
+
"template_id?": "string | null",
|
|
4694
|
+
"model?": "string | null",
|
|
4695
|
+
"enable_thinking?": "boolean | null",
|
|
4696
|
+
"solution_id?": "string | null",
|
|
4697
|
+
"solution_ref?": "unknown",
|
|
4698
|
+
"biz_role_id?": "string | null",
|
|
4699
|
+
"solution?": "unknown",
|
|
4700
|
+
"plan_summary?": "string | null",
|
|
4701
|
+
"primary_skill_id?": "string | null",
|
|
4702
|
+
// ship-attack v2:后端 engine.set_bound_skill 写入的"绑定 skill id"。
|
|
4703
|
+
// 未绑定 / 非 ship-attack session 为 null。
|
|
4704
|
+
"bound_skill_id?": "string | null",
|
|
4705
|
+
"replay_state?": "unknown",
|
|
4706
|
+
"is_pinned?": "boolean",
|
|
4707
|
+
"pinned_at?": "string | null",
|
|
4708
|
+
"is_example?": "boolean",
|
|
4709
|
+
"ports?": "unknown",
|
|
4710
|
+
"disable_tools?": "string[]",
|
|
4711
|
+
"runtime_type?": "string | null",
|
|
4712
|
+
"daemon_id?": "string | null",
|
|
4713
|
+
"workspace_path?": "string | null",
|
|
4714
|
+
"match?": "unknown"
|
|
4715
|
+
});
|
|
4938
4716
|
|
|
4939
4717
|
// src/schemas/solution.ts
|
|
4940
4718
|
var LayoutType = /* @__PURE__ */ ((LayoutType2) => {
|
|
@@ -4967,7 +4745,6 @@ export {
|
|
|
4967
4745
|
BladeApiError,
|
|
4968
4746
|
BladeClient,
|
|
4969
4747
|
ClientProjectionBuilder,
|
|
4970
|
-
DEFAULT_REPLAY_SPEED,
|
|
4971
4748
|
LayoutType,
|
|
4972
4749
|
ModelsResource,
|
|
4973
4750
|
SDK_NAME,
|
|
@@ -4978,7 +4755,6 @@ export {
|
|
|
4978
4755
|
SessionStatus,
|
|
4979
4756
|
Task,
|
|
4980
4757
|
TaskStatus,
|
|
4981
|
-
acceptedPostChatFollowupCompletesLatestRun,
|
|
4982
4758
|
buildMessageContent,
|
|
4983
4759
|
connectEmbedded,
|
|
4984
4760
|
contentPreview,
|
|
@@ -4992,9 +4768,7 @@ export {
|
|
|
4992
4768
|
isCommandEnvelope,
|
|
4993
4769
|
isHiddenInternalMessage,
|
|
4994
4770
|
isInboundEnvelope,
|
|
4995
|
-
latestPostChatFollowup,
|
|
4996
4771
|
normalizeMessageContent,
|
|
4997
|
-
toReplaySnapshot,
|
|
4998
4772
|
transformSlashCommand
|
|
4999
4773
|
};
|
|
5000
4774
|
//# sourceMappingURL=index.js.map
|