@linkedclaw/openclaw-plugin 0.1.5 → 0.1.7
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 +4 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +56 -31
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +8 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -39,13 +39,15 @@ plugins:
|
|
|
39
39
|
|
|
40
40
|
# Optional
|
|
41
41
|
cloudUrl: https://api.linkedclaw.com
|
|
42
|
+
serviceUrl: https://api.linkedclaw.com # services-host for gig-task accept/submit
|
|
42
43
|
relayUrl: wss://api.linkedclaw.com/ws
|
|
43
44
|
autoStartProvider: true # default true
|
|
45
|
+
autoAcceptInvokes: true # default true
|
|
44
46
|
autoAcceptSessions: true # default true
|
|
45
47
|
autoAcceptGigTasks: false # default false
|
|
46
48
|
maxConcurrentRuns: 4
|
|
47
49
|
perRequesterLimit: 2
|
|
48
|
-
invokeTimeoutMs:
|
|
50
|
+
invokeTimeoutMs: 60000
|
|
49
51
|
sessionTurnTimeoutMs: 60000
|
|
50
52
|
gigTaskTimeoutMs: 300000
|
|
51
53
|
slaTier: standard
|
|
@@ -70,7 +72,7 @@ When the gateway starts the service, the plugin:
|
|
|
70
72
|
|
|
71
73
|
1. Opens a WebSocket to the LinkedClaw relay and IDENTIFYs with
|
|
72
74
|
`{ apiKey, agentId }`.
|
|
73
|
-
2. For each inbound frame, dispatches it into a new subagent run via
|
|
75
|
+
2. For each accepted inbound frame, dispatches it into a new subagent run via
|
|
74
76
|
`api.runtime.subagent.run({ sessionKey, message, extraSystemPrompt,
|
|
75
77
|
deliver: false })`.
|
|
76
78
|
3. Waits on `waitForRun`, reads the last assistant message, and writes
|
package/dist/index.d.ts
CHANGED
|
@@ -119,6 +119,7 @@ interface PluginEntry {
|
|
|
119
119
|
|
|
120
120
|
interface ProviderConfig {
|
|
121
121
|
cloudUrl: string;
|
|
122
|
+
serviceUrl?: string;
|
|
122
123
|
relayUrl: string;
|
|
123
124
|
apiKey?: string;
|
|
124
125
|
agentId?: string;
|
|
@@ -132,6 +133,7 @@ interface ProviderConfig {
|
|
|
132
133
|
}
|
|
133
134
|
interface PluginRuntimeConfig extends ProviderConfig {
|
|
134
135
|
autoStartProvider: boolean;
|
|
136
|
+
autoAcceptInvokes: boolean;
|
|
135
137
|
autoAcceptSessions: boolean;
|
|
136
138
|
autoAcceptGigTasks: boolean;
|
|
137
139
|
}
|
package/dist/index.js
CHANGED
|
@@ -7896,6 +7896,20 @@ var GigTaskSchema = external_exports.object({
|
|
|
7896
7896
|
acceptance_criteria: external_exports.record(external_exports.unknown()).nullable().optional(),
|
|
7897
7897
|
expires_at: external_exports.string().nullable().optional()
|
|
7898
7898
|
}).passthrough();
|
|
7899
|
+
var GigTaskAvailableItemSchema = GigTaskSchema.extend({
|
|
7900
|
+
requester_reputation: external_exports.record(external_exports.unknown()).optional(),
|
|
7901
|
+
requester_slug: external_exports.string().nullable().optional(),
|
|
7902
|
+
is_locked: external_exports.boolean().optional(),
|
|
7903
|
+
lock_reason: external_exports.string().nullable().optional()
|
|
7904
|
+
}).passthrough();
|
|
7905
|
+
var GigTasksAvailableSchema = external_exports.object({
|
|
7906
|
+
viewer_tier: external_exports.object({
|
|
7907
|
+
name: external_exports.string().optional(),
|
|
7908
|
+
max_concurrent: external_exports.number().int().optional(),
|
|
7909
|
+
max_task_value: external_exports.number().int().nullable().optional()
|
|
7910
|
+
}).passthrough(),
|
|
7911
|
+
tasks: external_exports.array(GigTaskAvailableItemSchema)
|
|
7912
|
+
}).passthrough();
|
|
7899
7913
|
var GigTaskPolicySchema = external_exports.object({
|
|
7900
7914
|
max_credits_per_task: external_exports.number().int().optional(),
|
|
7901
7915
|
max_active_tasks: external_exports.number().int().optional()
|
|
@@ -8214,7 +8228,7 @@ var ProviderClient = class {
|
|
|
8214
8228
|
// ───────── Gig PA (provider) ─────────
|
|
8215
8229
|
/** @implements GET /api/v1/gig-tasks/available */
|
|
8216
8230
|
async listGigTasksAvailable(options) {
|
|
8217
|
-
return this.request(`/api/v1/gig-tasks/available${this.queryString({ capability: options?.capability })}`, { method: "GET" },
|
|
8231
|
+
return this.request(`/api/v1/gig-tasks/available${this.queryString({ capability: options?.capability })}`, { method: "GET" }, GigTasksAvailableSchema);
|
|
8218
8232
|
}
|
|
8219
8233
|
/** @implements GET /api/v1/gig-tasks/policy */
|
|
8220
8234
|
async getGigTaskPolicy() {
|
|
@@ -8388,7 +8402,7 @@ var MessageType = {
|
|
|
8388
8402
|
INVOKE_RESULT: "invoke_result"
|
|
8389
8403
|
};
|
|
8390
8404
|
function parseInbound(frame) {
|
|
8391
|
-
const type = frame
|
|
8405
|
+
const type = frame.type;
|
|
8392
8406
|
switch (type) {
|
|
8393
8407
|
case MessageType.SESSION_CREATE:
|
|
8394
8408
|
return {
|
|
@@ -8396,45 +8410,45 @@ function parseInbound(frame) {
|
|
|
8396
8410
|
session_id: str(frame, "session_id"),
|
|
8397
8411
|
requester_id: strOrEmpty(frame, "requester_id"),
|
|
8398
8412
|
capability: strOrEmpty(frame, "capability"),
|
|
8399
|
-
...frame
|
|
8413
|
+
...frame.scope !== void 0 ? { scope: frame.scope } : {}
|
|
8400
8414
|
};
|
|
8401
8415
|
case MessageType.SESSION_MESSAGE:
|
|
8402
8416
|
return {
|
|
8403
8417
|
type: "session.message",
|
|
8404
8418
|
session_id: str(frame, "session_id"),
|
|
8405
|
-
payload: frame
|
|
8406
|
-
...typeof frame
|
|
8407
|
-
...typeof frame
|
|
8419
|
+
payload: frame.payload,
|
|
8420
|
+
...typeof frame.seq === "number" ? { seq: frame.seq } : {},
|
|
8421
|
+
...typeof frame.sender === "string" ? { sender: frame.sender } : {}
|
|
8408
8422
|
};
|
|
8409
8423
|
case MessageType.SESSION_END:
|
|
8410
8424
|
return {
|
|
8411
8425
|
type: "session.end",
|
|
8412
8426
|
session_id: str(frame, "session_id"),
|
|
8413
|
-
...typeof frame
|
|
8427
|
+
...typeof frame.reason === "string" ? { reason: frame.reason } : {}
|
|
8414
8428
|
};
|
|
8415
8429
|
case MessageType.INVOKE:
|
|
8416
8430
|
return {
|
|
8417
8431
|
type: "invoke",
|
|
8418
8432
|
invoke_id: str(frame, "invoke_id"),
|
|
8419
8433
|
capability: strOrEmpty(frame, "capability"),
|
|
8420
|
-
input: frame
|
|
8421
|
-
...typeof frame
|
|
8422
|
-
...frame
|
|
8423
|
-
...typeof frame
|
|
8424
|
-
...typeof frame
|
|
8434
|
+
input: frame.input ?? {},
|
|
8435
|
+
...typeof frame.manifest_id === "string" ? { manifest_id: frame.manifest_id } : {},
|
|
8436
|
+
...frame.manifest !== void 0 && frame.manifest !== null ? { manifest: frame.manifest } : {},
|
|
8437
|
+
...typeof frame.requester_id === "string" ? { requester_id: frame.requester_id } : {},
|
|
8438
|
+
...typeof frame.timeout_seconds === "number" ? { timeout_seconds: frame.timeout_seconds } : {}
|
|
8425
8439
|
};
|
|
8426
8440
|
case MessageType.GIG_TASK: {
|
|
8427
8441
|
return {
|
|
8428
8442
|
type: "gig_task.offer",
|
|
8429
8443
|
task_id: str(frame, "task_id"),
|
|
8430
8444
|
capability: strOrEmpty(frame, "capability"),
|
|
8431
|
-
...typeof frame
|
|
8432
|
-
...typeof frame
|
|
8433
|
-
...typeof frame
|
|
8434
|
-
...typeof frame
|
|
8435
|
-
...typeof frame
|
|
8436
|
-
...frame
|
|
8437
|
-
...frame
|
|
8445
|
+
...typeof frame.instruction === "string" ? { instruction: frame.instruction } : {},
|
|
8446
|
+
...typeof frame.reward_credits === "number" ? { reward_credits: frame.reward_credits } : {},
|
|
8447
|
+
...typeof frame.response_sla_seconds === "number" ? { response_sla_seconds: frame.response_sla_seconds } : {},
|
|
8448
|
+
...typeof frame.slot_key === "string" ? { slot_key: frame.slot_key } : {},
|
|
8449
|
+
...typeof frame.partition_type === "string" ? { partition_type: frame.partition_type } : {},
|
|
8450
|
+
...frame.manifest !== void 0 && frame.manifest !== null ? { manifest: frame.manifest } : {},
|
|
8451
|
+
...frame.payload !== void 0 && frame.payload !== null ? { payload: frame.payload } : {}
|
|
8438
8452
|
};
|
|
8439
8453
|
}
|
|
8440
8454
|
default:
|
|
@@ -8702,10 +8716,11 @@ var DEFAULT_STRIP_PATTERNS = [
|
|
|
8702
8716
|
"system_prompt*"
|
|
8703
8717
|
];
|
|
8704
8718
|
function sanitizeText(text, patterns) {
|
|
8719
|
+
let result = text;
|
|
8705
8720
|
for (const pattern of patterns) {
|
|
8706
|
-
|
|
8721
|
+
result = result.replace(pattern, "");
|
|
8707
8722
|
}
|
|
8708
|
-
return
|
|
8723
|
+
return result;
|
|
8709
8724
|
}
|
|
8710
8725
|
function sanitizeOutput(payload, patterns = DEFAULT_OUTPUT_PATTERNS) {
|
|
8711
8726
|
if (typeof payload === "string") return sanitizeText(payload, patterns);
|
|
@@ -8868,7 +8883,7 @@ var ProviderRuntime = class {
|
|
|
8868
8883
|
return n;
|
|
8869
8884
|
}
|
|
8870
8885
|
async handleSessionCreate(evt) {
|
|
8871
|
-
const max = this.config.maxConcurrentRuns ??
|
|
8886
|
+
const max = this.config.maxConcurrentRuns ?? Number.POSITIVE_INFINITY;
|
|
8872
8887
|
if (this.totalInFlight() >= max) {
|
|
8873
8888
|
await this.send({
|
|
8874
8889
|
type: MessageType.SESSION_REJECT,
|
|
@@ -8954,7 +8969,7 @@ var ProviderRuntime = class {
|
|
|
8954
8969
|
}
|
|
8955
8970
|
}
|
|
8956
8971
|
async handleInvoke(evt) {
|
|
8957
|
-
const max = this.config.maxConcurrentRuns ??
|
|
8972
|
+
const max = this.config.maxConcurrentRuns ?? Number.POSITIVE_INFINITY;
|
|
8958
8973
|
if (this.totalInFlight() >= max) {
|
|
8959
8974
|
await this.send({
|
|
8960
8975
|
type: MessageType.INVOKE_RESULT,
|
|
@@ -8987,14 +9002,14 @@ var ProviderRuntime = class {
|
|
|
8987
9002
|
invoke_id: evt.invoke_id
|
|
8988
9003
|
};
|
|
8989
9004
|
if (result.error) {
|
|
8990
|
-
frame
|
|
9005
|
+
frame.error = result.error;
|
|
8991
9006
|
} else {
|
|
8992
|
-
frame
|
|
9007
|
+
frame.result = this.sanitizeOut(result.output ?? {});
|
|
8993
9008
|
}
|
|
8994
9009
|
await this.send(frame);
|
|
8995
9010
|
}
|
|
8996
9011
|
async handleGigTask(offer) {
|
|
8997
|
-
const max = this.config.maxConcurrentRuns ??
|
|
9012
|
+
const max = this.config.maxConcurrentRuns ?? Number.POSITIVE_INFINITY;
|
|
8998
9013
|
if (this.totalInFlight() >= max) return;
|
|
8999
9014
|
this.inFlightGigTasks.add(offer.task_id);
|
|
9000
9015
|
try {
|
|
@@ -9122,11 +9137,12 @@ function escapeRegex(s) {
|
|
|
9122
9137
|
function parseConfig(raw) {
|
|
9123
9138
|
const base = {
|
|
9124
9139
|
cloudUrl: typeof raw["cloudUrl"] === "string" ? raw["cloudUrl"] : process.env["LINKEDCLAW_CLOUD_URL"] ?? DEFAULT_CLOUD_URL,
|
|
9140
|
+
...typeof raw["serviceUrl"] === "string" ? { serviceUrl: raw["serviceUrl"] } : process.env["LINKEDCLAW_SERVICE_URL"] !== void 0 ? { serviceUrl: process.env["LINKEDCLAW_SERVICE_URL"] } : process.env["LINKEDCLAW_SERVICES_HOST_URL"] !== void 0 ? { serviceUrl: process.env["LINKEDCLAW_SERVICES_HOST_URL"] } : {},
|
|
9125
9141
|
relayUrl: typeof raw["relayUrl"] === "string" ? raw["relayUrl"] : process.env["LINKEDCLAW_RELAY_URL"] ?? DEFAULT_RELAY_URL,
|
|
9126
9142
|
capabilities: Array.isArray(raw["capabilities"]) ? raw["capabilities"] : [],
|
|
9127
9143
|
...typeof raw["apiKey"] === "string" ? { apiKey: raw["apiKey"] } : process.env["LINKEDCLAW_API_KEY"] !== void 0 ? { apiKey: process.env["LINKEDCLAW_API_KEY"] } : {},
|
|
9128
9144
|
...typeof raw["agentId"] === "string" ? { agentId: raw["agentId"] } : {},
|
|
9129
|
-
invokeTimeoutMs: typeof raw["invokeTimeoutMs"] === "number" ? raw["invokeTimeoutMs"] :
|
|
9145
|
+
invokeTimeoutMs: typeof raw["invokeTimeoutMs"] === "number" ? raw["invokeTimeoutMs"] : 6e4,
|
|
9130
9146
|
sessionTurnTimeoutMs: typeof raw["sessionTurnTimeoutMs"] === "number" ? raw["sessionTurnTimeoutMs"] : 6e4,
|
|
9131
9147
|
gigTaskTimeoutMs: typeof raw["gigTaskTimeoutMs"] === "number" ? raw["gigTaskTimeoutMs"] : 3e5,
|
|
9132
9148
|
maxConcurrentRuns: typeof raw["maxConcurrentRuns"] === "number" ? raw["maxConcurrentRuns"] : 4,
|
|
@@ -9136,6 +9152,7 @@ function parseConfig(raw) {
|
|
|
9136
9152
|
return {
|
|
9137
9153
|
...base,
|
|
9138
9154
|
autoStartProvider: raw["autoStartProvider"] !== false,
|
|
9155
|
+
autoAcceptInvokes: raw["autoAcceptInvokes"] !== false,
|
|
9139
9156
|
autoAcceptSessions: raw["autoAcceptSessions"] !== false,
|
|
9140
9157
|
autoAcceptGigTasks: raw["autoAcceptGigTasks"] === true
|
|
9141
9158
|
};
|
|
@@ -9194,6 +9211,12 @@ var SubagentHandler = class {
|
|
|
9194
9211
|
}
|
|
9195
9212
|
// ───── Invoke ─────
|
|
9196
9213
|
async onInvoke(evt) {
|
|
9214
|
+
if (!this.config.autoAcceptInvokes) {
|
|
9215
|
+
return { error: { code: "provider_manual_mode", message: "invoke handling disabled" } };
|
|
9216
|
+
}
|
|
9217
|
+
if (this.config.capabilities && this.config.capabilities.length > 0 && !this.config.capabilities.includes(evt.capability)) {
|
|
9218
|
+
return { error: { code: "capability_not_supported", message: "capability not supported" } };
|
|
9219
|
+
}
|
|
9197
9220
|
const sessionKey = this.invokeKey(evt.invoke_id);
|
|
9198
9221
|
try {
|
|
9199
9222
|
const run = await this.api.runtime.subagent.run({
|
|
@@ -9202,7 +9225,7 @@ var SubagentHandler = class {
|
|
|
9202
9225
|
extraSystemPrompt: buildInvokePrompt(evt),
|
|
9203
9226
|
deliver: false
|
|
9204
9227
|
});
|
|
9205
|
-
const timeoutMs = (evt.timeout_seconds !== void 0 ? evt.timeout_seconds * 1e3 : this.config.invokeTimeoutMs) ??
|
|
9228
|
+
const timeoutMs = (evt.timeout_seconds !== void 0 ? evt.timeout_seconds * 1e3 : this.config.invokeTimeoutMs) ?? 6e4;
|
|
9206
9229
|
const waited = await this.api.runtime.subagent.waitForRun({ runId: run.runId, timeoutMs });
|
|
9207
9230
|
if (!isDone(waited.status)) {
|
|
9208
9231
|
return {
|
|
@@ -9420,7 +9443,7 @@ var ProviderHolder = class {
|
|
|
9420
9443
|
const agentId = cfg.agentId;
|
|
9421
9444
|
if (!apiKey) throw new Error("apiKey missing");
|
|
9422
9445
|
if (!agentId) throw new Error("agentId missing \u2014 register the provider first");
|
|
9423
|
-
const
|
|
9446
|
+
const gigTaskClient = new ProviderClient(cfg.serviceUrl ?? cfg.cloudUrl, apiKey);
|
|
9424
9447
|
const relay = new RelayClient({
|
|
9425
9448
|
url: cfg.relayUrl,
|
|
9426
9449
|
apiKey,
|
|
@@ -9431,8 +9454,8 @@ var ProviderHolder = class {
|
|
|
9431
9454
|
return new ProviderRuntime({
|
|
9432
9455
|
cloud: {
|
|
9433
9456
|
gigTasks: {
|
|
9434
|
-
accept: (taskId, body, idempotencyKey) =>
|
|
9435
|
-
submit: (taskId, body) =>
|
|
9457
|
+
accept: (taskId, body, idempotencyKey) => gigTaskClient.acceptGigTask(taskId, body, idempotencyKey),
|
|
9458
|
+
submit: (taskId, body) => gigTaskClient.submitGigTask(taskId, body)
|
|
9436
9459
|
}
|
|
9437
9460
|
},
|
|
9438
9461
|
relay,
|
|
@@ -9466,9 +9489,11 @@ var SUPPORTED_CONFIG_FIELDS = /* @__PURE__ */ new Set([
|
|
|
9466
9489
|
"apiKey",
|
|
9467
9490
|
"agentId",
|
|
9468
9491
|
"cloudUrl",
|
|
9492
|
+
"serviceUrl",
|
|
9469
9493
|
"relayUrl",
|
|
9470
9494
|
"capabilities",
|
|
9471
9495
|
"autoStartProvider",
|
|
9496
|
+
"autoAcceptInvokes",
|
|
9472
9497
|
"autoAcceptSessions",
|
|
9473
9498
|
"autoAcceptGigTasks",
|
|
9474
9499
|
"invokeTimeoutMs",
|