pairai 0.2.2 → 0.2.3

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/pairai.ts +108 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pairai",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "pairai CLI — connect AI agents to collaborate via the pairai hub",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/pairai.ts CHANGED
@@ -436,6 +436,11 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
436
436
  required: ["task_id", "status"],
437
437
  },
438
438
  },
439
+ {
440
+ name: "pairai_get_profile",
441
+ description: "Get your own agent profile — name, ID, description, capabilities.",
442
+ inputSchema: { type: "object" as const, properties: {} },
443
+ },
439
444
  {
440
445
  name: "pairai_list_connections",
441
446
  description: "List agents you are connected with.",
@@ -470,6 +475,66 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
470
475
  required: ["code"],
471
476
  },
472
477
  },
478
+ {
479
+ name: "pairai_update_profile",
480
+ description: "Update your agent's profile — name, description, capabilities, and metadata. Returns the updated profile.",
481
+ inputSchema: {
482
+ type: "object" as const,
483
+ properties: {
484
+ name: { type: "string", description: "Display name (1-64 chars)" },
485
+ description: { type: "string", description: "What this agent does (max 500 chars)" },
486
+ capabilities: { type: "array", items: { type: "string" }, description: "List of capabilities, e.g. ['scheduling', 'code-review']" },
487
+ metadata: { type: "object", description: "Arbitrary JSON metadata (max 4KB)" },
488
+ },
489
+ },
490
+ },
491
+ {
492
+ name: "pairai_set_alias",
493
+ description: "Set a local alias for a connected agent. Only you see this alias. Set to null to clear.",
494
+ inputSchema: {
495
+ type: "object" as const,
496
+ properties: {
497
+ connection_id: { type: "string", description: "Connection ID" },
498
+ alias: { type: ["string", "null"], description: "Local alias, or null to clear" },
499
+ },
500
+ required: ["connection_id"],
501
+ },
502
+ },
503
+ {
504
+ name: "pairai_list_tasks",
505
+ description: "List all tasks you are involved in (as initiator or target).",
506
+ inputSchema: {
507
+ type: "object" as const,
508
+ properties: {
509
+ status: { type: "string", enum: ["submitted", "working", "input-required", "completed", "failed", "cancelled"], description: "Filter by status" },
510
+ },
511
+ },
512
+ },
513
+ {
514
+ name: "pairai_get_task",
515
+ description: "Get full details of a task including all messages.",
516
+ inputSchema: {
517
+ type: "object" as const,
518
+ properties: {
519
+ task_id: { type: "string", description: "Task ID" },
520
+ },
521
+ required: ["task_id"],
522
+ },
523
+ },
524
+ {
525
+ name: "pairai_upload_file",
526
+ description: "Upload a file to a task. Provide base64-encoded content.",
527
+ inputSchema: {
528
+ type: "object" as const,
529
+ properties: {
530
+ task_id: { type: "string", description: "Task ID" },
531
+ filename: { type: "string", description: "Original filename, e.g. photo.png" },
532
+ mime_type: { type: "string", description: "MIME type, e.g. image/png" },
533
+ base64_content: { type: "string", description: "Base64-encoded file content" },
534
+ },
535
+ required: ["task_id", "filename", "mime_type", "base64_content"],
536
+ },
537
+ },
473
538
  {
474
539
  name: "pairai_create_encrypted_task",
475
540
  description: "Create an encrypted task. Title and description are encrypted — the hub cannot read them.",
@@ -530,6 +595,11 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
530
595
  return { content: [{ type: "text" as const, text: `Status → ${args.status}` }] };
531
596
  }
532
597
 
598
+ if (name === "pairai_get_profile") {
599
+ const data = await hubGet("/agents/me");
600
+ return { content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }] };
601
+ }
602
+
533
603
  if (name === "pairai_list_connections") {
534
604
  const data = await hubGet("/connections");
535
605
  return { content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }] };
@@ -584,6 +654,43 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
584
654
  return { content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }] };
585
655
  }
586
656
 
657
+ if (name === "pairai_update_profile") {
658
+ const body: Record<string, unknown> = {};
659
+ if (args.name !== undefined) body.name = args.name;
660
+ if (args.description !== undefined) body.description = args.description;
661
+ if (args.capabilities !== undefined) body.capabilities = args.capabilities;
662
+ if (args.metadata !== undefined) body.metadata = args.metadata;
663
+ const data = await hubPatch("/agents/me", body);
664
+ return { content: [{ type: "text" as const, text: "Profile updated.\n" + JSON.stringify(data, null, 2) }] };
665
+ }
666
+
667
+ if (name === "pairai_set_alias") {
668
+ const { connection_id, alias } = args as { connection_id: string; alias?: string | null };
669
+ const data = await hubPatch(`/connections/${connection_id}`, { alias: alias ?? null });
670
+ return { content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }] };
671
+ }
672
+
673
+ if (name === "pairai_list_tasks") {
674
+ const data = (await hubGet("/tasks")) as Array<{ status: string }>;
675
+ const filtered = args.status ? data.filter((t) => t.status === args.status) : data;
676
+ return { content: [{ type: "text" as const, text: JSON.stringify(filtered, null, 2) }] };
677
+ }
678
+
679
+ if (name === "pairai_get_task") {
680
+ const data = await hubGet(`/tasks/${args.task_id}`);
681
+ return { content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }] };
682
+ }
683
+
684
+ if (name === "pairai_upload_file") {
685
+ const { task_id, filename, mime_type, base64_content } = args as {
686
+ task_id: string; filename: string; mime_type: string; base64_content: string;
687
+ };
688
+ const data = await hubPost(`/tasks/${task_id}/files/json`, {
689
+ filename, mimeType: mime_type, base64Content: base64_content,
690
+ });
691
+ return { content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }] };
692
+ }
693
+
587
694
  if (name === "pairai_create_encrypted_task") {
588
695
  if (!PRIVATE_KEY)
589
696
  return { content: [{ type: "text" as const, text: "No private key configured. Re-run setup." }] };
@@ -735,6 +842,7 @@ async function poll() {
735
842
  }>;
736
843
  };
737
844
 
845
+ if (!full?.messages) continue;
738
846
  for (const msg of full.messages.slice(-unread.count)) {
739
847
  const key = `msg:${msg.id}`;
740
848
  if (seenMessages.has(key)) continue;