@xiashe/sdk 0.1.0 → 0.1.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/index.mjs +82 -17
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import path from 'node:path';
|
|
|
6
6
|
import { ConvexHttpClient } from 'convex/browser';
|
|
7
7
|
import { anyApi as api } from 'convex/server';
|
|
8
8
|
|
|
9
|
-
export const VERSION = '0.1.
|
|
9
|
+
export const VERSION = '0.1.3';
|
|
10
10
|
|
|
11
11
|
export const DEFAULTS = {
|
|
12
12
|
cn: {
|
|
@@ -38,6 +38,7 @@ const CONFIG_DIR = process.env.XIASHE_CONFIG_DIR || path.join(os.homedir(), DEFA
|
|
|
38
38
|
const CONFIG_PATH = process.env.XIASHE_CONFIG_PATH || path.join(CONFIG_DIR, 'config.json');
|
|
39
39
|
const DEFAULT_PROFILE = 'default';
|
|
40
40
|
const HTTP_TIMEOUT_MS = 20_000;
|
|
41
|
+
const DEFAULT_MAX_UPLOAD_BYTES = 10 * 1024 * 1024;
|
|
41
42
|
|
|
42
43
|
export class XiasheError extends Error {
|
|
43
44
|
constructor(message, options = {}) {
|
|
@@ -529,6 +530,16 @@ export class XiasheClient {
|
|
|
529
530
|
return this.query(api.agentGateway.listForUser, this.authArgs({ limit }));
|
|
530
531
|
}
|
|
531
532
|
|
|
533
|
+
async revokeAgent(agentConnectionId, options = {}) {
|
|
534
|
+
return this.mutation(
|
|
535
|
+
api.agentGateway.revokeConnection,
|
|
536
|
+
this.authArgs({
|
|
537
|
+
agentConnectionId,
|
|
538
|
+
idempotencyKey: options.idempotencyKey || createIdempotencyKey('cli-agent-revoke', [agentConnectionId])
|
|
539
|
+
})
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
|
|
532
543
|
async createAgentChatTask(options = {}) {
|
|
533
544
|
return this.mutation(
|
|
534
545
|
api.agentGateway.createChatTask,
|
|
@@ -598,6 +609,12 @@ export class XiasheClient {
|
|
|
598
609
|
if (!info.isFile()) {
|
|
599
610
|
throw new XiasheError(`Not a file: ${absolutePath}`, { code: 'UPLOAD_NOT_FILE' });
|
|
600
611
|
}
|
|
612
|
+
if (info.size > DEFAULT_MAX_UPLOAD_BYTES) {
|
|
613
|
+
throw new XiasheError(`File too large. Max ${DEFAULT_MAX_UPLOAD_BYTES} bytes.`, {
|
|
614
|
+
code: 'UPLOAD_FILE_TOO_LARGE',
|
|
615
|
+
details: { maxBytes: DEFAULT_MAX_UPLOAD_BYTES, size: info.size }
|
|
616
|
+
});
|
|
617
|
+
}
|
|
601
618
|
const fileName = options.fileName || path.basename(absolutePath);
|
|
602
619
|
const mime = options.mime || inferMime(absolutePath);
|
|
603
620
|
const source = options.source || 'manual_upload';
|
|
@@ -663,6 +680,8 @@ export class XiasheClient {
|
|
|
663
680
|
agentName: options.agentName || undefined,
|
|
664
681
|
agentKind: options.agentKind || undefined,
|
|
665
682
|
agentRef: options.agentRef || undefined,
|
|
683
|
+
webhookUrl: options.webhookUrl || undefined,
|
|
684
|
+
webhookAuthToken: options.webhookAuthToken || undefined,
|
|
666
685
|
transport: options.transport || undefined
|
|
667
686
|
},
|
|
668
687
|
{ timeoutMs: this.timeoutMs }
|
|
@@ -691,6 +710,11 @@ export class XiasheClient {
|
|
|
691
710
|
async agentHeartbeat(options = {}) {
|
|
692
711
|
return this.agentRest('/agent-gateway/heartbeat', {
|
|
693
712
|
status: options.status || 'online',
|
|
713
|
+
agentName: options.agentName || undefined,
|
|
714
|
+
agentRef: options.agentRef || undefined,
|
|
715
|
+
webhookUrl: options.webhookUrl || undefined,
|
|
716
|
+
webhookAuthToken: options.webhookAuthToken || undefined,
|
|
717
|
+
webhookMode: options.webhookMode || undefined,
|
|
694
718
|
capabilities: options.capabilities || undefined
|
|
695
719
|
});
|
|
696
720
|
}
|
|
@@ -701,6 +725,28 @@ export class XiasheClient {
|
|
|
701
725
|
});
|
|
702
726
|
}
|
|
703
727
|
|
|
728
|
+
async agentListTransfers(options = {}) {
|
|
729
|
+
return this.agentRest('/agent-gateway/transfers/list', {
|
|
730
|
+
limit: options.limit || 20
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
async agentAcceptTransfer(transferId, options = {}) {
|
|
735
|
+
return this.agentRest('/agent-gateway/transfers/accept', {
|
|
736
|
+
transferId,
|
|
737
|
+
idempotencyKey: options.idempotencyKey || undefined
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
async agentCompleteTransfer(transferId, options = {}) {
|
|
742
|
+
return this.agentRest('/agent-gateway/transfers/complete', {
|
|
743
|
+
transferId,
|
|
744
|
+
status: options.status || 'completed',
|
|
745
|
+
error: options.error || undefined,
|
|
746
|
+
idempotencyKey: options.idempotencyKey || undefined
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
|
|
704
750
|
async agentAckTask(taskId, state = 'running') {
|
|
705
751
|
return this.agentRest('/agent-gateway/tasks/ack', { taskId, state });
|
|
706
752
|
}
|
|
@@ -716,6 +762,7 @@ export class XiasheClient {
|
|
|
716
762
|
async agentCreateTask(options = {}) {
|
|
717
763
|
return this.agentRest('/agent-gateway/tasks/create', {
|
|
718
764
|
targetAgentConnectionId: options.targetAgentConnectionId,
|
|
765
|
+
targetAgentName: options.targetAgentName,
|
|
719
766
|
chatId: options.chatId,
|
|
720
767
|
content: options.content,
|
|
721
768
|
attachments: options.attachments || undefined,
|
|
@@ -774,6 +821,9 @@ export async function saveAgentSession(profileName, claimResult) {
|
|
|
774
821
|
|
|
775
822
|
export function printableAgentPrompt(issue) {
|
|
776
823
|
const claimUrl = issue.claimUrl || issue.restBaseUrl?.replace(/\/+$/, '') + '/agent-gateway/claim';
|
|
824
|
+
const receiverCommand = DEFAULT_ENV === 'global'
|
|
825
|
+
? 'npx -y @agentpie/cli agent run --ack'
|
|
826
|
+
: 'npx -y @xiashe/cli agent run --ack';
|
|
777
827
|
if (DEFAULT_ENV === 'global') {
|
|
778
828
|
return [
|
|
779
829
|
'Connect this Agent to AgentPie. Please complete the setup automatically or call the HTTP endpoint directly. Do not expose the token to the end user.',
|
|
@@ -787,15 +837,21 @@ export function printableAgentPrompt(issue) {
|
|
|
787
837
|
{
|
|
788
838
|
token: issue.token,
|
|
789
839
|
agentName: '<your agent name>',
|
|
790
|
-
agentKind: '<
|
|
840
|
+
agentKind: '<mcp|http|npx|local|other>',
|
|
791
841
|
transport: '<mcp|http|npx|manual>',
|
|
792
|
-
agentRef: '<optional: device, workspace, or instance id>'
|
|
842
|
+
agentRef: '<optional: device, workspace, or instance id>',
|
|
843
|
+
webhookUrl: '<optional public HTTPS endpoint for immediate wake-up>',
|
|
844
|
+
webhookAuthToken: '<optional shared secret for webhook Authorization>'
|
|
793
845
|
},
|
|
794
846
|
null,
|
|
795
847
|
2
|
|
796
848
|
),
|
|
797
849
|
'',
|
|
798
|
-
'After claiming, save the returned runtimeToken
|
|
850
|
+
'After claiming, save the returned runtimeToken. If you expose a public HTTPS webhook, AgentPie will POST task notifications there; return HTTP 202 and process with MCP/REST, or return JSON { "content": "..." } within 8 seconds to complete immediately. If webhook delivery fails, tasks remain queued for polling.',
|
|
851
|
+
'',
|
|
852
|
+
'Persistent Agents may run a lightweight receiver loop with MCP or REST tool calls only; no long-lived socket is required. The loop should send heartbeat, inspect pendingTaskCount/pendingTransferCount, and only call a model when work is present. Default cadence is about 30s while idle, 10s while work is active, and up to 2 minutes after long idle periods. Use recommendedNextHeartbeatMs with jitter/backoff. Temporary sandbox Agents should not run a loop; reconnect when work is needed.',
|
|
853
|
+
'',
|
|
854
|
+
`Recommended receiver command for shell-capable runtimes: ${receiverCommand}`,
|
|
799
855
|
'',
|
|
800
856
|
'If you support MCP, add the MCP URL as a tool server and use the runtimeToken as a Bearer token.',
|
|
801
857
|
'',
|
|
@@ -815,19 +871,25 @@ export function printableAgentPrompt(issue) {
|
|
|
815
871
|
`POST ${claimUrl}`,
|
|
816
872
|
'Content-Type: application/json',
|
|
817
873
|
'',
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
874
|
+
JSON.stringify(
|
|
875
|
+
{
|
|
876
|
+
token: issue.token,
|
|
877
|
+
agentName: '<你的 Agent 名称>',
|
|
878
|
+
agentKind: '<mcp|http|npx|local|other>',
|
|
879
|
+
transport: '<mcp|http|npx|manual>',
|
|
880
|
+
agentRef: '<可选:设备名、工作区或实例标识>',
|
|
881
|
+
webhookUrl: '<可选:用于即时唤醒的公网 HTTPS endpoint>',
|
|
882
|
+
webhookAuthToken: '<可选:webhook Authorization 共享密钥>'
|
|
883
|
+
},
|
|
884
|
+
null,
|
|
885
|
+
2
|
|
886
|
+
),
|
|
887
|
+
'',
|
|
888
|
+
'成功后保存返回的 runtimeToken。如果你能提供公网 HTTPS webhook,虾舍会在创建任务时直接 POST 通知;你可以快速返回 HTTP 202 后用 MCP/REST 处理,也可以在 8 秒内返回 JSON { "content": "..." } 让虾舍立即完成任务。webhook 失败时任务仍会保留在队列里,继续支持 polling。',
|
|
829
889
|
'',
|
|
830
|
-
'
|
|
890
|
+
'常驻 Agent 可以使用 MCP 或 REST 工具调用运行轻量任务接收循环,不需要长连接:发送心跳,查看 pendingTaskCount/pendingTransferCount;只有存在任务时才拉取任务、确认 running、执行并 complete 回虾舍。默认节奏是空闲约 30 秒一次、有任务约 10 秒一次、长时间空闲后最多约 2 分钟一次。',
|
|
891
|
+
'',
|
|
892
|
+
`如果运行环境可以执行 shell,推荐接收命令:${receiverCommand}`,
|
|
831
893
|
'',
|
|
832
894
|
'如果你支持 MCP,请把下面的 MCP URL 加为工具服务,并在调用时使用 runtimeToken 作为 Bearer Token。',
|
|
833
895
|
'',
|
|
@@ -836,7 +898,10 @@ export function printableAgentPrompt(issue) {
|
|
|
836
898
|
`MCP URL: ${issue.mcpUrl}`,
|
|
837
899
|
`REST Base URL: ${issue.restBaseUrl}`,
|
|
838
900
|
'',
|
|
839
|
-
'连接完成后,你会出现在虾舍的 Agent 工作台里,可以接收 @提及、任务和文件。'
|
|
901
|
+
'连接完成后,你会出现在虾舍的 Agent 工作台里,可以接收 @提及、任务和文件。',
|
|
902
|
+
'',
|
|
903
|
+
'常驻 Agent:只发送轻量 heartbeat;没有任务时不要推理、不要调用模型。请使用 heartbeat 返回的 recommendedNextHeartbeatMs,并加入 jitter/backoff。',
|
|
904
|
+
'临时 sandbox:不要跑 receiver loop。需要工作时重新连接;完成一次性任务后即可退出。'
|
|
840
905
|
].join('\n');
|
|
841
906
|
}
|
|
842
907
|
|