@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 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: 30000
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" }, external_exports.array(GigTaskSchema));
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["type"];
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["scope"] !== void 0 ? { scope: frame["scope"] } : {}
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["payload"],
8406
- ...typeof frame["seq"] === "number" ? { seq: frame["seq"] } : {},
8407
- ...typeof frame["sender"] === "string" ? { sender: frame["sender"] } : {}
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["reason"] === "string" ? { reason: frame["reason"] } : {}
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["input"] ?? {},
8421
- ...typeof frame["manifest_id"] === "string" ? { manifest_id: frame["manifest_id"] } : {},
8422
- ...frame["manifest"] !== void 0 && frame["manifest"] !== null ? { manifest: frame["manifest"] } : {},
8423
- ...typeof frame["requester_id"] === "string" ? { requester_id: frame["requester_id"] } : {},
8424
- ...typeof frame["timeout_seconds"] === "number" ? { timeout_seconds: frame["timeout_seconds"] } : {}
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["instruction"] === "string" ? { instruction: frame["instruction"] } : {},
8432
- ...typeof frame["reward_credits"] === "number" ? { reward_credits: frame["reward_credits"] } : {},
8433
- ...typeof frame["response_sla_seconds"] === "number" ? { response_sla_seconds: frame["response_sla_seconds"] } : {},
8434
- ...typeof frame["slot_key"] === "string" ? { slot_key: frame["slot_key"] } : {},
8435
- ...typeof frame["partition_type"] === "string" ? { partition_type: frame["partition_type"] } : {},
8436
- ...frame["manifest"] !== void 0 && frame["manifest"] !== null ? { manifest: frame["manifest"] } : {},
8437
- ...frame["payload"] !== void 0 && frame["payload"] !== null ? { payload: frame["payload"] } : {}
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
- text = text.replace(pattern, "");
8721
+ result = result.replace(pattern, "");
8707
8722
  }
8708
- return text;
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 ?? Infinity;
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 ?? Infinity;
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["error"] = result.error;
9005
+ frame.error = result.error;
8991
9006
  } else {
8992
- frame["result"] = this.sanitizeOut(result.output ?? {});
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 ?? Infinity;
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"] : 3e4,
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) ?? 3e4;
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 client = new ProviderClient(cfg.cloudUrl, apiKey);
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) => client.acceptGigTask(taskId, body, idempotencyKey),
9435
- submit: (taskId, body) => client.submitGigTask(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",