@yushaw/sanqian-sdk 0.3.26 → 0.3.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 +38 -0
- package/dist/index.browser.d.mts +53 -1
- package/dist/index.browser.d.ts +53 -1
- package/dist/index.browser.js +89 -7
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.mjs +89 -7
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.d.mts +53 -5
- package/dist/index.d.ts +53 -5
- package/dist/index.js +98 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +98 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -341,6 +341,25 @@ const response = await sdk.chat('agent', messages, {
|
|
|
341
341
|
})
|
|
342
342
|
```
|
|
343
343
|
|
|
344
|
+
### Local file ingest
|
|
345
|
+
|
|
346
|
+
For same-machine deployments where the Sanqian backend can read a local path directly, use `uploadFile()` first, then pass the returned `file.path` into `chat()`:
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
const uploaded = await sdk.uploadFile('/absolute/path/report.pdf', {
|
|
350
|
+
conversationId,
|
|
351
|
+
autoIndex: true,
|
|
352
|
+
asyncProcess: true,
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
const response = await sdk.chat('agent', messages, {
|
|
356
|
+
conversationId: uploaded.conversationId,
|
|
357
|
+
filePaths: [uploaded.file.path],
|
|
358
|
+
})
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
`uploadFile(localPath)` is not a remote file transfer protocol. For remote/backend-on-another-machine cases, continue using explicit byte upload APIs.
|
|
362
|
+
|
|
344
363
|
---
|
|
345
364
|
|
|
346
365
|
## Human-in-the-Loop (HITL)
|
|
@@ -1328,6 +1347,25 @@ const response = await sdk.chat('agent', messages, {
|
|
|
1328
1347
|
})
|
|
1329
1348
|
```
|
|
1330
1349
|
|
|
1350
|
+
### 本地文件导入
|
|
1351
|
+
|
|
1352
|
+
对于 Sanqian 后端与调用方在同一台机器、且后端能直接读取本地路径的场景,先调用 `uploadFile()`,再把返回的 `file.path` 传给 `chat()`:
|
|
1353
|
+
|
|
1354
|
+
```typescript
|
|
1355
|
+
const uploaded = await sdk.uploadFile('/absolute/path/report.pdf', {
|
|
1356
|
+
conversationId,
|
|
1357
|
+
autoIndex: true,
|
|
1358
|
+
asyncProcess: true,
|
|
1359
|
+
})
|
|
1360
|
+
|
|
1361
|
+
const response = await sdk.chat('agent', messages, {
|
|
1362
|
+
conversationId: uploaded.conversationId,
|
|
1363
|
+
filePaths: [uploaded.file.path],
|
|
1364
|
+
})
|
|
1365
|
+
```
|
|
1366
|
+
|
|
1367
|
+
`uploadFile(localPath)` 不是远程文件传输协议。对于远程 backend 或不同机器场景,仍应使用显式字节上传能力。
|
|
1368
|
+
|
|
1331
1369
|
---
|
|
1332
1370
|
|
|
1333
1371
|
## 人机协作 (HITL)
|
package/dist/index.browser.d.mts
CHANGED
|
@@ -297,6 +297,30 @@ interface ChatStreamEvent {
|
|
|
297
297
|
result?: unknown;
|
|
298
298
|
/** Whether tool execution succeeded (for "tool_result" event) */
|
|
299
299
|
success?: boolean;
|
|
300
|
+
/** Normalized tool execution status (for "tool_result" event) */
|
|
301
|
+
status?: "running" | "completed" | "error" | "cancelled";
|
|
302
|
+
/** Structured action required hint (for "tool_result" event) */
|
|
303
|
+
action_required?: string;
|
|
304
|
+
/** Optional settings deep link target (for "tool_result" event) */
|
|
305
|
+
settings_tab?: string;
|
|
306
|
+
/** Optional settings deep link sub-target (for "tool_result" event) */
|
|
307
|
+
settings_sub_tab?: string;
|
|
308
|
+
/** Structured SDK tool failure marker (for "tool_result" event) */
|
|
309
|
+
sdk_tool_error?: boolean;
|
|
310
|
+
/** App name that emitted the SDK tool failure (for "tool_result" event) */
|
|
311
|
+
sdk_tool_app?: string;
|
|
312
|
+
/** Failure domain for structured tool errors (for "tool_result" event) */
|
|
313
|
+
tool_failure_domain?: string;
|
|
314
|
+
/** App identifier for structured tool errors (for "tool_result" event) */
|
|
315
|
+
tool_failure_app?: string;
|
|
316
|
+
/** Failure kind for structured tool errors (for "tool_result" event) */
|
|
317
|
+
tool_failure_kind?: string;
|
|
318
|
+
/** Whether the tool reported a rollback during failure handling (for "tool_result" event) */
|
|
319
|
+
tool_failure_rolled_back?: boolean;
|
|
320
|
+
/** Human-readable failure message for structured tool errors (for "tool_result" event) */
|
|
321
|
+
tool_failure_error?: string;
|
|
322
|
+
/** Stable target key for structured tool errors (for "tool_result" event) */
|
|
323
|
+
tool_failure_target_key?: string;
|
|
300
324
|
/** Conversation ID (for "done" event) */
|
|
301
325
|
conversationId?: string;
|
|
302
326
|
/** Conversation title (for "done" event) */
|
|
@@ -519,6 +543,27 @@ interface ConversationHistoryResult {
|
|
|
519
543
|
user_loaded_tools?: string[];
|
|
520
544
|
user_loaded_subagents?: string[];
|
|
521
545
|
}
|
|
546
|
+
interface UploadFileOptions {
|
|
547
|
+
conversationId?: string;
|
|
548
|
+
autoIndex?: boolean;
|
|
549
|
+
asyncProcess?: boolean;
|
|
550
|
+
}
|
|
551
|
+
interface UploadedFileInfo {
|
|
552
|
+
id?: number | null;
|
|
553
|
+
path: string;
|
|
554
|
+
name: string;
|
|
555
|
+
size: number;
|
|
556
|
+
mimeType?: string | null;
|
|
557
|
+
extension?: string | null;
|
|
558
|
+
source?: string | null;
|
|
559
|
+
processStatus?: string | null;
|
|
560
|
+
resourceUri?: string | null;
|
|
561
|
+
resourceStatus?: string | null;
|
|
562
|
+
}
|
|
563
|
+
interface UploadFileResult {
|
|
564
|
+
conversationId: string;
|
|
565
|
+
file: UploadedFileInfo;
|
|
566
|
+
}
|
|
522
567
|
/** Agent update configuration (all fields optional except agent_id) */
|
|
523
568
|
interface AgentUpdateConfig {
|
|
524
569
|
/** Agent ID to update */
|
|
@@ -998,7 +1043,9 @@ declare abstract class SanqianSDKBase {
|
|
|
998
1043
|
private resolvePendingStartIndex;
|
|
999
1044
|
private getActiveConnectionInfo;
|
|
1000
1045
|
private getHttpBaseUrl;
|
|
1001
|
-
getHttpAuthHeaders(
|
|
1046
|
+
getHttpAuthHeaders(options?: {
|
|
1047
|
+
includeAppIdentity?: boolean;
|
|
1048
|
+
}): Record<string, string>;
|
|
1002
1049
|
/**
|
|
1003
1050
|
* Centralized HTTP request method.
|
|
1004
1051
|
* Automatically injects X-App-Token auth header and standardizes error handling.
|
|
@@ -1156,6 +1203,11 @@ declare abstract class SanqianSDKBase {
|
|
|
1156
1203
|
* Delete a conversation
|
|
1157
1204
|
*/
|
|
1158
1205
|
deleteConversation(conversationId: string): Promise<void>;
|
|
1206
|
+
/**
|
|
1207
|
+
* Prepare a local file for chat attachment via the backend ingest-local route.
|
|
1208
|
+
* This is intended for same-machine deployments where the backend can read localPath directly.
|
|
1209
|
+
*/
|
|
1210
|
+
uploadFile(localPath: string, options?: UploadFileOptions): Promise<UploadFileResult>;
|
|
1159
1211
|
/**
|
|
1160
1212
|
* Send a chat message to an agent (non-streaming)
|
|
1161
1213
|
*/
|
package/dist/index.browser.d.ts
CHANGED
|
@@ -297,6 +297,30 @@ interface ChatStreamEvent {
|
|
|
297
297
|
result?: unknown;
|
|
298
298
|
/** Whether tool execution succeeded (for "tool_result" event) */
|
|
299
299
|
success?: boolean;
|
|
300
|
+
/** Normalized tool execution status (for "tool_result" event) */
|
|
301
|
+
status?: "running" | "completed" | "error" | "cancelled";
|
|
302
|
+
/** Structured action required hint (for "tool_result" event) */
|
|
303
|
+
action_required?: string;
|
|
304
|
+
/** Optional settings deep link target (for "tool_result" event) */
|
|
305
|
+
settings_tab?: string;
|
|
306
|
+
/** Optional settings deep link sub-target (for "tool_result" event) */
|
|
307
|
+
settings_sub_tab?: string;
|
|
308
|
+
/** Structured SDK tool failure marker (for "tool_result" event) */
|
|
309
|
+
sdk_tool_error?: boolean;
|
|
310
|
+
/** App name that emitted the SDK tool failure (for "tool_result" event) */
|
|
311
|
+
sdk_tool_app?: string;
|
|
312
|
+
/** Failure domain for structured tool errors (for "tool_result" event) */
|
|
313
|
+
tool_failure_domain?: string;
|
|
314
|
+
/** App identifier for structured tool errors (for "tool_result" event) */
|
|
315
|
+
tool_failure_app?: string;
|
|
316
|
+
/** Failure kind for structured tool errors (for "tool_result" event) */
|
|
317
|
+
tool_failure_kind?: string;
|
|
318
|
+
/** Whether the tool reported a rollback during failure handling (for "tool_result" event) */
|
|
319
|
+
tool_failure_rolled_back?: boolean;
|
|
320
|
+
/** Human-readable failure message for structured tool errors (for "tool_result" event) */
|
|
321
|
+
tool_failure_error?: string;
|
|
322
|
+
/** Stable target key for structured tool errors (for "tool_result" event) */
|
|
323
|
+
tool_failure_target_key?: string;
|
|
300
324
|
/** Conversation ID (for "done" event) */
|
|
301
325
|
conversationId?: string;
|
|
302
326
|
/** Conversation title (for "done" event) */
|
|
@@ -519,6 +543,27 @@ interface ConversationHistoryResult {
|
|
|
519
543
|
user_loaded_tools?: string[];
|
|
520
544
|
user_loaded_subagents?: string[];
|
|
521
545
|
}
|
|
546
|
+
interface UploadFileOptions {
|
|
547
|
+
conversationId?: string;
|
|
548
|
+
autoIndex?: boolean;
|
|
549
|
+
asyncProcess?: boolean;
|
|
550
|
+
}
|
|
551
|
+
interface UploadedFileInfo {
|
|
552
|
+
id?: number | null;
|
|
553
|
+
path: string;
|
|
554
|
+
name: string;
|
|
555
|
+
size: number;
|
|
556
|
+
mimeType?: string | null;
|
|
557
|
+
extension?: string | null;
|
|
558
|
+
source?: string | null;
|
|
559
|
+
processStatus?: string | null;
|
|
560
|
+
resourceUri?: string | null;
|
|
561
|
+
resourceStatus?: string | null;
|
|
562
|
+
}
|
|
563
|
+
interface UploadFileResult {
|
|
564
|
+
conversationId: string;
|
|
565
|
+
file: UploadedFileInfo;
|
|
566
|
+
}
|
|
522
567
|
/** Agent update configuration (all fields optional except agent_id) */
|
|
523
568
|
interface AgentUpdateConfig {
|
|
524
569
|
/** Agent ID to update */
|
|
@@ -998,7 +1043,9 @@ declare abstract class SanqianSDKBase {
|
|
|
998
1043
|
private resolvePendingStartIndex;
|
|
999
1044
|
private getActiveConnectionInfo;
|
|
1000
1045
|
private getHttpBaseUrl;
|
|
1001
|
-
getHttpAuthHeaders(
|
|
1046
|
+
getHttpAuthHeaders(options?: {
|
|
1047
|
+
includeAppIdentity?: boolean;
|
|
1048
|
+
}): Record<string, string>;
|
|
1002
1049
|
/**
|
|
1003
1050
|
* Centralized HTTP request method.
|
|
1004
1051
|
* Automatically injects X-App-Token auth header and standardizes error handling.
|
|
@@ -1156,6 +1203,11 @@ declare abstract class SanqianSDKBase {
|
|
|
1156
1203
|
* Delete a conversation
|
|
1157
1204
|
*/
|
|
1158
1205
|
deleteConversation(conversationId: string): Promise<void>;
|
|
1206
|
+
/**
|
|
1207
|
+
* Prepare a local file for chat attachment via the backend ingest-local route.
|
|
1208
|
+
* This is intended for same-machine deployments where the backend can read localPath directly.
|
|
1209
|
+
*/
|
|
1210
|
+
uploadFile(localPath: string, options?: UploadFileOptions): Promise<UploadFileResult>;
|
|
1159
1211
|
/**
|
|
1160
1212
|
* Send a chat message to an agent (non-streaming)
|
|
1161
1213
|
*/
|
package/dist/index.browser.js
CHANGED
|
@@ -368,10 +368,20 @@ var SanqianSDKBase = class _SanqianSDKBase {
|
|
|
368
368
|
const host = info.ws_host || "127.0.0.1";
|
|
369
369
|
return `${protocol}://${host}:${info.port}`;
|
|
370
370
|
}
|
|
371
|
-
getHttpAuthHeaders() {
|
|
371
|
+
getHttpAuthHeaders(options) {
|
|
372
372
|
const info = this.getActiveConnectionInfo();
|
|
373
373
|
const token = info?.token;
|
|
374
|
-
|
|
374
|
+
const headers = token ? { "X-App-Token": token } : {};
|
|
375
|
+
if (options?.includeAppIdentity) {
|
|
376
|
+
headers["X-App-Name"] = this.config.appName;
|
|
377
|
+
if (this.config.appVersion) {
|
|
378
|
+
headers["X-App-Version"] = this.config.appVersion;
|
|
379
|
+
}
|
|
380
|
+
if (this.config.displayName) {
|
|
381
|
+
headers["X-App-Display-Name"] = this.config.displayName;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return headers;
|
|
375
385
|
}
|
|
376
386
|
/**
|
|
377
387
|
* Centralized HTTP request method.
|
|
@@ -384,11 +394,18 @@ var SanqianSDKBase = class _SanqianSDKBase {
|
|
|
384
394
|
if (qs) {
|
|
385
395
|
url += `?${qs}`;
|
|
386
396
|
}
|
|
387
|
-
const headers = {
|
|
397
|
+
const headers = {
|
|
398
|
+
...this.getHttpAuthHeaders({ includeAppIdentity: options?.includeAppIdentity })
|
|
399
|
+
};
|
|
388
400
|
const init = { method, headers };
|
|
389
401
|
if (options?.body !== void 0) {
|
|
390
402
|
headers["Content-Type"] = "application/json";
|
|
391
403
|
init.body = JSON.stringify(options.body);
|
|
404
|
+
} else if (options?.rawBody !== void 0) {
|
|
405
|
+
if (options.contentType) {
|
|
406
|
+
headers["Content-Type"] = options.contentType;
|
|
407
|
+
}
|
|
408
|
+
init.body = options.rawBody;
|
|
392
409
|
}
|
|
393
410
|
const response = await fetch(url, init);
|
|
394
411
|
if (!response.ok) {
|
|
@@ -784,7 +801,19 @@ var SanqianSDKBase = class _SanqianSDKBase {
|
|
|
784
801
|
tool_call_id: tool_result.call_id,
|
|
785
802
|
result: tool_result.result,
|
|
786
803
|
success: tool_result.success,
|
|
787
|
-
error: tool_result.error
|
|
804
|
+
error: tool_result.error,
|
|
805
|
+
status: tool_result.status,
|
|
806
|
+
action_required: tool_result.action_required,
|
|
807
|
+
settings_tab: tool_result.settings_tab,
|
|
808
|
+
settings_sub_tab: tool_result.settings_sub_tab,
|
|
809
|
+
sdk_tool_error: tool_result.sdk_tool_error,
|
|
810
|
+
sdk_tool_app: tool_result.sdk_tool_app,
|
|
811
|
+
tool_failure_domain: tool_result.tool_failure_domain,
|
|
812
|
+
tool_failure_app: tool_result.tool_failure_app,
|
|
813
|
+
tool_failure_kind: tool_result.tool_failure_kind,
|
|
814
|
+
tool_failure_rolled_back: tool_result.tool_failure_rolled_back,
|
|
815
|
+
tool_failure_error: tool_result.tool_failure_error,
|
|
816
|
+
tool_failure_target_key: tool_result.tool_failure_target_key
|
|
788
817
|
});
|
|
789
818
|
} else {
|
|
790
819
|
this.log("Received tool_result event without tool_result data");
|
|
@@ -896,10 +925,22 @@ var SanqianSDKBase = class _SanqianSDKBase {
|
|
|
896
925
|
if (handler) {
|
|
897
926
|
handler.onEvent({
|
|
898
927
|
type: "tool_result",
|
|
899
|
-
tool_call_id: message.tool_call_id,
|
|
928
|
+
tool_call_id: message.tool_call_id || message.tool_id,
|
|
900
929
|
result: message.result,
|
|
901
930
|
success: message.success,
|
|
902
|
-
error: message.error
|
|
931
|
+
error: message.error,
|
|
932
|
+
status: message.status,
|
|
933
|
+
action_required: message.action_required,
|
|
934
|
+
settings_tab: message.settings_tab,
|
|
935
|
+
settings_sub_tab: message.settings_sub_tab,
|
|
936
|
+
sdk_tool_error: message.sdk_tool_error,
|
|
937
|
+
sdk_tool_app: message.sdk_tool_app,
|
|
938
|
+
tool_failure_domain: message.tool_failure_domain,
|
|
939
|
+
tool_failure_app: message.tool_failure_app,
|
|
940
|
+
tool_failure_kind: message.tool_failure_kind,
|
|
941
|
+
tool_failure_rolled_back: message.tool_failure_rolled_back,
|
|
942
|
+
tool_failure_error: message.tool_failure_error,
|
|
943
|
+
tool_failure_target_key: message.tool_failure_target_key
|
|
903
944
|
});
|
|
904
945
|
}
|
|
905
946
|
}
|
|
@@ -970,11 +1011,12 @@ var SanqianSDKBase = class _SanqianSDKBase {
|
|
|
970
1011
|
} catch (e) {
|
|
971
1012
|
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
972
1013
|
const errorStack = e instanceof Error ? e.stack : void 0;
|
|
1014
|
+
const structuredToolResult = e && typeof e === "object" && "toolResult" in e ? e.toolResult : void 0;
|
|
973
1015
|
this.log(`Tool '${toolName}' failed:`, errorMessage);
|
|
974
1016
|
if (errorStack) {
|
|
975
1017
|
this.log(`Tool error stack:`, errorStack);
|
|
976
1018
|
}
|
|
977
|
-
await this.sendToolResult(msgId, call_id, false,
|
|
1019
|
+
await this.sendToolResult(msgId, call_id, false, structuredToolResult, errorMessage);
|
|
978
1020
|
}
|
|
979
1021
|
}
|
|
980
1022
|
async sendToolResult(id, callId, success, result, error) {
|
|
@@ -1518,6 +1560,46 @@ var SanqianSDKBase = class _SanqianSDKBase {
|
|
|
1518
1560
|
throw createSDKError("CONVERSATION_NOT_FOUND" /* CONVERSATION_NOT_FOUND */, response.error);
|
|
1519
1561
|
}
|
|
1520
1562
|
}
|
|
1563
|
+
/**
|
|
1564
|
+
* Prepare a local file for chat attachment via the backend ingest-local route.
|
|
1565
|
+
* This is intended for same-machine deployments where the backend can read localPath directly.
|
|
1566
|
+
*/
|
|
1567
|
+
async uploadFile(localPath, options) {
|
|
1568
|
+
await this.ensureHttpReady();
|
|
1569
|
+
const form = new URLSearchParams();
|
|
1570
|
+
form.append("local_path", localPath);
|
|
1571
|
+
if (options?.conversationId) {
|
|
1572
|
+
form.append("conversation_id", options.conversationId);
|
|
1573
|
+
}
|
|
1574
|
+
form.append("auto_index", String(options?.autoIndex ?? true));
|
|
1575
|
+
form.append("async_process", String(options?.asyncProcess ?? true));
|
|
1576
|
+
const response = await this.httpRequest("POST", "/api/files/ingest-local", {
|
|
1577
|
+
rawBody: form.toString(),
|
|
1578
|
+
contentType: "application/x-www-form-urlencoded",
|
|
1579
|
+
includeAppIdentity: true
|
|
1580
|
+
});
|
|
1581
|
+
if (!response.success || !response.conversation_id || !response.file?.path) {
|
|
1582
|
+
throw createSDKError(
|
|
1583
|
+
"REQUEST_FAILED" /* REQUEST_FAILED */,
|
|
1584
|
+
response.error || "POST /api/files/ingest-local returned an invalid response"
|
|
1585
|
+
);
|
|
1586
|
+
}
|
|
1587
|
+
return {
|
|
1588
|
+
conversationId: response.conversation_id,
|
|
1589
|
+
file: {
|
|
1590
|
+
id: response.file.id,
|
|
1591
|
+
path: response.file.path,
|
|
1592
|
+
name: response.file.name || "",
|
|
1593
|
+
size: response.file.size ?? 0,
|
|
1594
|
+
mimeType: response.file.mime_type,
|
|
1595
|
+
extension: response.file.extension,
|
|
1596
|
+
source: response.file.source,
|
|
1597
|
+
processStatus: response.file.process_status,
|
|
1598
|
+
resourceUri: response.file.resource_uri,
|
|
1599
|
+
resourceStatus: response.file.resource_status
|
|
1600
|
+
}
|
|
1601
|
+
};
|
|
1602
|
+
}
|
|
1521
1603
|
// ============================================
|
|
1522
1604
|
// Chat API
|
|
1523
1605
|
// ============================================
|