@stamn/stamn-plugin 0.1.0-alpha.28 → 0.1.0-alpha.29

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/dist/index.js CHANGED
@@ -5332,16 +5332,19 @@ function respondToService(ws) {
5332
5332
  properties: {
5333
5333
  requestId: param("string", "The requestId from the incoming event."),
5334
5334
  output: param("string", "The result/output of the service."),
5335
- success: param("string", "Whether it succeeded.", { enum: ["true", "false"] })
5335
+ success: param("string", "Whether it succeeded.", { enum: ["true", "false"] }),
5336
+ domain: param("string", 'Optional domain tag for experience tracking (e.g. "typescript-nestjs-monorepos").')
5336
5337
  },
5337
5338
  required: ["requestId", "output", "success"]
5338
5339
  },
5339
5340
  execute: (_id, args) => {
5340
- ws.send("participant:service_result", {
5341
+ const payload = {
5341
5342
  requestId: args.requestId,
5342
5343
  output: args.output,
5343
5344
  success: args.success === "true"
5344
- });
5345
+ };
5346
+ if (args.domain) payload.domain = args.domain;
5347
+ ws.send("participant:service_result", payload);
5345
5348
  return text(`Service response sent for request ${args.requestId}.`);
5346
5349
  }
5347
5350
  };
@@ -5559,6 +5562,264 @@ function ping() {
5559
5562
  execute: () => text("pong \u2014 stamn plugin tools are loaded and reachable.")
5560
5563
  };
5561
5564
  }
5565
+ function getReputation(ws) {
5566
+ return {
5567
+ name: "stamn_get_reputation",
5568
+ description: "Get your reputation score and reviews. Returns trust score (0-1000), completion rate, review average, and score breakdown.",
5569
+ parameters: NO_PARAMS,
5570
+ execute: () => {
5571
+ ws.send("participant:get_reviews", {});
5572
+ return text("Reputation request sent. Check events for the response (server:reviews).");
5573
+ }
5574
+ };
5575
+ }
5576
+ function reviewService(ws) {
5577
+ return {
5578
+ name: "stamn_review_service",
5579
+ description: "Rate a completed service you purchased. Only the buyer can review. Rating is 1-5 stars.",
5580
+ parameters: {
5581
+ type: "object",
5582
+ properties: {
5583
+ requestId: param("string", "The requestId of the completed service job."),
5584
+ rating: param("string", "Rating from 1 to 5.", { enum: ["1", "2", "3", "4", "5"] }),
5585
+ comment: param("string", "Optional review comment.")
5586
+ },
5587
+ required: ["requestId", "rating"]
5588
+ },
5589
+ execute: (_id, args) => {
5590
+ ws.send("participant:service_review", {
5591
+ requestId: args.requestId,
5592
+ rating: Number(args.rating),
5593
+ ...args.comment ? { comment: args.comment } : {}
5594
+ });
5595
+ return text(`Review submitted for request ${args.requestId}. Check events for confirmation.`);
5596
+ }
5597
+ };
5598
+ }
5599
+ function getReviews(ws) {
5600
+ return {
5601
+ name: "stamn_get_reviews",
5602
+ description: "Get reviews received for your services along with your reputation score.",
5603
+ parameters: NO_PARAMS,
5604
+ execute: () => {
5605
+ ws.send("participant:get_reviews", {});
5606
+ return text("Reviews request sent. Check events for the response (server:reviews).");
5607
+ }
5608
+ };
5609
+ }
5610
+ function getExperience(ws) {
5611
+ return {
5612
+ name: "stamn_get_experience",
5613
+ description: "Get your experience profiles \u2014 verifiable work history by service tag and domain. Shows jobs completed, success rate, volume, and response time.",
5614
+ parameters: NO_PARAMS,
5615
+ execute: () => {
5616
+ ws.send("participant:get_experience", {});
5617
+ return text("Experience request sent. Check events for the response (server:experience).");
5618
+ }
5619
+ };
5620
+ }
5621
+ function searchExperts(ws) {
5622
+ return {
5623
+ name: "stamn_search_experts",
5624
+ description: "Search for agents with proven experience in a domain or service tag. Find the best provider for a task based on verifiable track record.",
5625
+ parameters: {
5626
+ type: "object",
5627
+ properties: {
5628
+ domain: param("string", 'Domain to search for (e.g. "typescript", "data-analysis"). Partial match supported.'),
5629
+ serviceTag: param("string", "Exact service tag to filter by."),
5630
+ minJobs: param("number", "Minimum number of completed jobs."),
5631
+ minSuccessRate: param("number", "Minimum success rate (0-1, e.g. 0.95 for 95%)."),
5632
+ limit: param("number", "Max results to return (default 20).")
5633
+ }
5634
+ },
5635
+ execute: (_id, args) => {
5636
+ const payload = {};
5637
+ if (args.domain) payload.domain = args.domain;
5638
+ if (args.serviceTag) payload.serviceTag = args.serviceTag;
5639
+ if (args.minJobs) payload.minJobs = Number(args.minJobs);
5640
+ if (args.minSuccessRate) payload.minSuccessRate = Number(args.minSuccessRate);
5641
+ if (args.limit) payload.limit = Number(args.limit);
5642
+ ws.send("participant:search_experts", payload);
5643
+ return text("Expert search sent. Check events for the response (server:experts).");
5644
+ }
5645
+ };
5646
+ }
5647
+ function declareCapability(ws) {
5648
+ return {
5649
+ name: "stamn_declare_capability",
5650
+ description: "Declare a capability (tool, integration, hardware, access, or credential) that you have. This is stored in your profile and helps buyers find you.",
5651
+ parameters: {
5652
+ type: "object",
5653
+ properties: {
5654
+ capabilityType: param("string", "Type of capability.", { enum: ["tool", "integration", "hardware", "access", "credential"] }),
5655
+ name: param("string", 'Short name for the capability (e.g. "web-search", "github-api").'),
5656
+ description: param("string", "What this capability lets you do."),
5657
+ provider: param("string", 'Optional provider/platform (e.g. "Google", "GitHub").')
5658
+ },
5659
+ required: ["capabilityType", "name", "description"]
5660
+ },
5661
+ execute: (_id, args) => {
5662
+ const payload = {
5663
+ capabilityType: args.capabilityType,
5664
+ name: args.name,
5665
+ description: args.description
5666
+ };
5667
+ if (args.provider) payload.provider = args.provider;
5668
+ ws.send("participant:capability_declare", payload);
5669
+ return text(`Capability "${args.name}" declaration sent. Check events for confirmation (server:capability_declared).`);
5670
+ }
5671
+ };
5672
+ }
5673
+ function removeCapability(ws) {
5674
+ return {
5675
+ name: "stamn_remove_capability",
5676
+ description: "Remove a previously declared capability from your profile.",
5677
+ parameters: {
5678
+ type: "object",
5679
+ properties: {
5680
+ capabilityType: param("string", "Type of capability.", { enum: ["tool", "integration", "hardware", "access", "credential"] }),
5681
+ name: param("string", "Name of the capability to remove.")
5682
+ },
5683
+ required: ["capabilityType", "name"]
5684
+ },
5685
+ execute: (_id, args) => {
5686
+ ws.send("participant:capability_remove", {
5687
+ capabilityType: args.capabilityType,
5688
+ name: args.name
5689
+ });
5690
+ return text(`Capability removal sent. Check events for confirmation (server:capability_removed).`);
5691
+ }
5692
+ };
5693
+ }
5694
+ function listCapabilities(ws) {
5695
+ return {
5696
+ name: "stamn_list_capabilities",
5697
+ description: "List all capabilities you have declared.",
5698
+ parameters: NO_PARAMS,
5699
+ execute: () => {
5700
+ ws.send("participant:capability_list", {});
5701
+ return text("Capability list requested. Check events for the response (server:capability_list).");
5702
+ }
5703
+ };
5704
+ }
5705
+ function searchCapabilities(ws) {
5706
+ return {
5707
+ name: "stamn_search_capabilities",
5708
+ description: "Search for agents with specific capabilities. Find agents that have the tools or integrations you need.",
5709
+ parameters: {
5710
+ type: "object",
5711
+ properties: {
5712
+ capabilityType: param("string", "Filter by type.", { enum: ["tool", "integration", "hardware", "access", "credential"] }),
5713
+ name: param("string", "Search by capability name (partial match)."),
5714
+ provider: param("string", "Filter by provider (partial match)."),
5715
+ limit: param("number", "Max results (default 20).")
5716
+ }
5717
+ },
5718
+ execute: (_id, args) => {
5719
+ const payload = {};
5720
+ if (args.capabilityType) payload.capabilityType = args.capabilityType;
5721
+ if (args.name) payload.name = args.name;
5722
+ if (args.provider) payload.provider = args.provider;
5723
+ if (args.limit) payload.limit = Number(args.limit);
5724
+ ws.send("participant:search_capabilities", payload);
5725
+ return text("Capability search sent. Check events for the response (server:search_results).");
5726
+ }
5727
+ };
5728
+ }
5729
+ function setHybridMode(ws) {
5730
+ return {
5731
+ name: "stamn_set_hybrid_mode",
5732
+ description: "Set your hybrid mode: autonomous (fully AI), human_backed (AI with human escalation), or human_operated (human drives, AI assists).",
5733
+ parameters: {
5734
+ type: "object",
5735
+ properties: {
5736
+ mode: param("string", "The hybrid mode.", { enum: ["autonomous", "human_backed", "human_operated"] }),
5737
+ humanRole: param("string", 'Role of the human (e.g. "Senior Engineer", "Domain Expert").'),
5738
+ escalationTriggers: param("string", 'Comma-separated triggers for escalation (e.g. "complex-bug,security-review").'),
5739
+ humanAvailabilityHours: param("string", 'Availability window (e.g. "9am-5pm PST").')
5740
+ },
5741
+ required: ["mode"]
5742
+ },
5743
+ execute: (_id, args) => {
5744
+ const payload = {
5745
+ mode: args.mode
5746
+ };
5747
+ if (args.humanRole) payload.humanRole = args.humanRole;
5748
+ if (args.escalationTriggers) {
5749
+ payload.escalationTriggers = args.escalationTriggers.split(",").map((s) => s.trim());
5750
+ }
5751
+ if (args.humanAvailabilityHours) payload.humanAvailabilityHours = args.humanAvailabilityHours;
5752
+ ws.send("participant:set_hybrid_mode", payload);
5753
+ return text(`Hybrid mode update sent. Check events for confirmation (server:hybrid_mode_updated).`);
5754
+ }
5755
+ };
5756
+ }
5757
+ function addCredential(ws) {
5758
+ return {
5759
+ name: "stamn_add_credential",
5760
+ description: "Add a verified credential to your profile (e.g. certification, license, degree). Credentials are initially unverified.",
5761
+ parameters: {
5762
+ type: "object",
5763
+ properties: {
5764
+ credentialType: param("string", 'Type (e.g. "certification", "license", "degree", "membership").'),
5765
+ title: param("string", 'Title of the credential (e.g. "AWS Solutions Architect").'),
5766
+ issuer: param("string", 'Issuing organization (e.g. "Amazon Web Services").')
5767
+ },
5768
+ required: ["credentialType", "title", "issuer"]
5769
+ },
5770
+ execute: (_id, args) => {
5771
+ ws.send("participant:add_credential", {
5772
+ credentialType: args.credentialType,
5773
+ title: args.title,
5774
+ issuer: args.issuer
5775
+ });
5776
+ return text(`Credential submission sent. Check events for confirmation (server:credential_added).`);
5777
+ }
5778
+ };
5779
+ }
5780
+ function requestEscalation(ws) {
5781
+ return {
5782
+ name: "stamn_escalation_request",
5783
+ description: "Request human escalation for a task you cannot handle alone. Only relevant for human_backed or human_operated agents.",
5784
+ parameters: {
5785
+ type: "object",
5786
+ properties: {
5787
+ trigger: param("string", 'What triggered the escalation (e.g. "complex-bug", "security-review", "domain-expertise").'),
5788
+ context: param("string", "Context for the human \u2014 what you need help with."),
5789
+ serviceJobId: param("string", "Optional service job ID this escalation relates to.")
5790
+ },
5791
+ required: ["trigger", "context"]
5792
+ },
5793
+ execute: (_id, args) => {
5794
+ const payload = {
5795
+ trigger: args.trigger,
5796
+ context: args.context
5797
+ };
5798
+ if (args.serviceJobId) payload.serviceJobId = args.serviceJobId;
5799
+ ws.send("participant:escalation_request", payload);
5800
+ return text(`Escalation request sent. Check events for confirmation (server:escalation_created).`);
5801
+ }
5802
+ };
5803
+ }
5804
+ function resolveEscalation(ws) {
5805
+ return {
5806
+ name: "stamn_escalation_resolve",
5807
+ description: "Mark an escalation as resolved after human intervention is complete.",
5808
+ parameters: {
5809
+ type: "object",
5810
+ properties: {
5811
+ escalationId: param("string", "The escalation ID to resolve.")
5812
+ },
5813
+ required: ["escalationId"]
5814
+ },
5815
+ execute: (_id, args) => {
5816
+ ws.send("participant:escalation_resolved", {
5817
+ escalationId: args.escalationId
5818
+ });
5819
+ return text(`Escalation resolution sent. Check events for confirmation (server:escalation_resolved).`);
5820
+ }
5821
+ };
5822
+ }
5562
5823
  function allTools(ws, agentId) {
5563
5824
  return [
5564
5825
  worldStatus(ws),
@@ -5573,7 +5834,20 @@ function allTools(ws, agentId) {
5573
5834
  updateServiceListing(ws),
5574
5835
  listServiceListings(ws),
5575
5836
  chatReply(ws, agentId),
5576
- spend(ws)
5837
+ spend(ws),
5838
+ getReputation(ws),
5839
+ reviewService(ws),
5840
+ getReviews(ws),
5841
+ getExperience(ws),
5842
+ searchExperts(ws),
5843
+ declareCapability(ws),
5844
+ removeCapability(ws),
5845
+ listCapabilities(ws),
5846
+ searchCapabilities(ws),
5847
+ setHybridMode(ws),
5848
+ addCredential(ws),
5849
+ requestEscalation(ws),
5850
+ resolveEscalation(ws)
5577
5851
  ];
5578
5852
  }
5579
5853
  function withAuthGuard(tool, ws) {
@@ -5743,7 +6017,8 @@ var ServerEvent = {
5743
6017
  HEARTBEAT_ACK: "server:heartbeat_ack",
5744
6018
  WORLD_UPDATE: "server:world_update",
5745
6019
  BALANCE: "server:balance",
5746
- OWNER_CHAT_MESSAGE: "server:owner_chat_message"
6020
+ OWNER_CHAT_MESSAGE: "server:owner_chat_message",
6021
+ SERVICE_INCOMING: "server:service_incoming"
5747
6022
  };
5748
6023
  var ClientEvent = {
5749
6024
  AUTHENTICATE: "participant:authenticate",
@@ -5769,6 +6044,7 @@ var StamnWsService = class {
5769
6044
  createSocket;
5770
6045
  ownerChatHandler;
5771
6046
  messageHandlers;
6047
+ serviceRequestHandler;
5772
6048
  constructor(opts) {
5773
6049
  this.config = opts.config;
5774
6050
  this.logger = opts.logger;
@@ -5782,7 +6058,8 @@ var StamnWsService = class {
5782
6058
  [ServerEvent.HEARTBEAT_ACK]: () => this.logger.debug("Heartbeat acknowledged"),
5783
6059
  [ServerEvent.WORLD_UPDATE]: (d) => this.onWorldUpdate(d),
5784
6060
  [ServerEvent.BALANCE]: (d) => this.onBalanceUpdate(d),
5785
- [ServerEvent.OWNER_CHAT_MESSAGE]: (d) => this.handleOwnerChat(d)
6061
+ [ServerEvent.OWNER_CHAT_MESSAGE]: (d) => this.handleOwnerChat(d),
6062
+ [ServerEvent.SERVICE_INCOMING]: (d) => this.handleServiceIncoming(d)
5786
6063
  };
5787
6064
  }
5788
6065
  async start() {
@@ -5825,6 +6102,9 @@ var StamnWsService = class {
5825
6102
  setOwnerChatHandler(handler) {
5826
6103
  this.ownerChatHandler = handler;
5827
6104
  }
6105
+ setServiceRequestHandler(handler) {
6106
+ this.serviceRequestHandler = handler;
6107
+ }
5828
6108
  connect() {
5829
6109
  this.logger.info(`Connecting to ${this.wsUrl}...`);
5830
6110
  try {
@@ -6023,6 +6303,11 @@ var StamnWsService = class {
6023
6303
  this.bufferEvent(ServerEvent.OWNER_CHAT_MESSAGE, payload);
6024
6304
  this.ownerChatHandler?.(payload);
6025
6305
  }
6306
+ handleServiceIncoming(payload) {
6307
+ this.logger.info(`Service request: ${payload.serviceTag} from ${payload.fromParticipantName} (${payload.requestId})`);
6308
+ this.bufferEvent(ServerEvent.SERVICE_INCOMING, payload);
6309
+ this.serviceRequestHandler?.(payload);
6310
+ }
6026
6311
  bufferEvent(event, data) {
6027
6312
  if (this.eventBuffer.length >= MAX_EVENT_BUFFER_SIZE) {
6028
6313
  this.eventBuffer.shift();
@@ -6178,6 +6463,9 @@ var index_default = {
6178
6463
  wsService.setOwnerChatHandler((payload) => {
6179
6464
  dispatchOwnerChat(api, wsService, payload, agentId);
6180
6465
  });
6466
+ wsService.setServiceRequestHandler((payload) => {
6467
+ dispatchServiceRequest(api, wsService, payload, agentId);
6468
+ });
6181
6469
  api.registerService({
6182
6470
  id: "stamn-ws",
6183
6471
  start: () => wsService.start(),
@@ -6245,6 +6533,59 @@ function dispatchOwnerChat(api, wsService, payload, agentId) {
6245
6533
  api.logger.error(`[stamn-channel] dispatchOwnerChat threw: ${err}`);
6246
6534
  }
6247
6535
  }
6536
+ function dispatchServiceRequest(api, _wsService, payload, agentId) {
6537
+ api.logger.info(
6538
+ `[stamn-channel] service request: ${payload.serviceTag} from ${payload.fromParticipantName}`
6539
+ );
6540
+ if (!api.runtime?.channel?.reply) {
6541
+ api.logger.warn("[stamn-channel] channel.reply not available \u2014 cannot dispatch service request");
6542
+ return;
6543
+ }
6544
+ const reply = api.runtime.channel.reply;
6545
+ try {
6546
+ const { dispatcher, replyOptions } = reply.createReplyDispatcherWithTyping({
6547
+ deliver: async () => {
6548
+ },
6549
+ channel: "stamn",
6550
+ accountId: agentId
6551
+ });
6552
+ const bodyForAgent = [
6553
+ `SERVICE REQUEST \u2014 You have an incoming paid service request. Process it immediately.`,
6554
+ ``,
6555
+ `Service: ${payload.serviceTag}`,
6556
+ `From: ${payload.fromParticipantName}`,
6557
+ `Price: ${payload.offeredPriceCents} cents USDC`,
6558
+ `Request ID: ${payload.requestId}`,
6559
+ ``,
6560
+ `Input:`,
6561
+ payload.input,
6562
+ ``,
6563
+ `Respond using stamn_service_respond with requestId "${payload.requestId}".`
6564
+ ].join("\n");
6565
+ reply.dispatchReplyFromConfig({
6566
+ ctx: {
6567
+ BodyForAgent: bodyForAgent,
6568
+ ChatType: "direct",
6569
+ MessageSid: payload.requestId,
6570
+ SessionKey: `agent:main:stamn:service:${agentId}`,
6571
+ Provider: "stamn",
6572
+ Surface: "stamn",
6573
+ From: payload.fromParticipantName
6574
+ },
6575
+ cfg: api.config,
6576
+ dispatcher,
6577
+ replyOptions
6578
+ }).then(() => {
6579
+ api.logger.info(
6580
+ `[stamn-channel] service request dispatched for ${payload.serviceTag} (${payload.requestId})`
6581
+ );
6582
+ }).catch((err) => {
6583
+ api.logger.error(`[stamn-channel] service request dispatch failed: ${err}`);
6584
+ });
6585
+ } catch (err) {
6586
+ api.logger.error(`[stamn-channel] dispatchServiceRequest threw: ${err}`);
6587
+ }
6588
+ }
6248
6589
  export {
6249
6590
  StamnWsService,
6250
6591
  createOpenclawAdapter,