@inline-chat/hermes-agent-adapter 0.0.7 → 0.0.8

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.
@@ -23,6 +23,8 @@ except Exception: # pragma: no cover - used by lightweight package tests
23
23
  _DEFAULT_SIDECAR_PORT = 8794
24
24
  _DEFAULT_SIDECAR_BIND = "127.0.0.1"
25
25
  _MAX_HISTORY_LIMIT = 100
26
+ _MAX_MESSAGE_IDS = 100
27
+ _MAX_INLINE_ID = 9_223_372_036_854_775_807
26
28
  _DEFAULT_HISTORY_LIMIT = 20
27
29
  _MAX_TEXT_CHARS = 4000
28
30
  _MAX_QUERY_CHARS = 500
@@ -56,7 +58,11 @@ INLINE_PLATFORM_GUIDANCE = (
56
58
  "while keeping the stable user ID in the link target. Link chats as "
57
59
  "[title](inline://chat?id=123), and link reply threads as "
58
60
  "[title](inline://thread?id=123). In Inline, reply threads are chat ids; "
59
- "do not treat thread ids as reply/quote message ids."
61
+ "do not treat thread ids as reply/quote message ids. Use ordinary Markdown "
62
+ "tables for tabular data, never fenced-code tables. For collapsible work, "
63
+ "use <details open>, then <summary>Title</summary>, body Markdown, and "
64
+ "</details>; put kind=\"progress\" on summary only while work is in progress. "
65
+ "Use <footer>Attribution or brief metadata</footer> for a short footer."
60
66
  )
61
67
 
62
68
  _sidecar: Dict[str, Any] = {}
@@ -76,6 +82,7 @@ _ACTION_MANIFEST = [
76
82
  ("list_pins", "(chat_id?)", "List pinned Inline message IDs for a chat or reply thread."),
77
83
  ("create_thread", "(parent_chat_id?, parent_message_id?, title?)", "Create an Inline reply thread."),
78
84
  ("create_chat", "(title, space_id?, participant_user_ids?, is_public?)", "Create a top-level Inline thread/chat."),
85
+ ("create_agent", "(name, skill_key?, instructions?)", "Create a named Inline Agent backed by this bot."),
79
86
  ("set_presence", "(chat_id?|user_id?, kind, comment?)", "Set the bot avatar presence/status message."),
80
87
  ]
81
88
  _ACTIONS = [name for name, _, _ in _ACTION_MANIFEST]
@@ -179,6 +186,7 @@ INLINE_TOOL_SCHEMA = {
179
186
  "message_ids": {
180
187
  "type": "array",
181
188
  "items": {"type": "string"},
189
+ "maxItems": _MAX_MESSAGE_IDS,
182
190
  "description": "Inline message IDs for get_messages.",
183
191
  },
184
192
  "parent_chat_id": {"type": "string", "description": "Parent chat ID for create_thread. Defaults to the current chat."},
@@ -187,6 +195,10 @@ INLINE_TOOL_SCHEMA = {
187
195
  "description": "Parent message ID for create_thread. Defaults to the triggering message when available.",
188
196
  },
189
197
  "title": {"type": "string", "description": "Thread title. Required for create_chat and optional for create_thread."},
198
+ "name": {"type": "string", "description": "Agent name for create_agent."},
199
+ "handle": {"type": "string", "description": "Optional Agent handle."},
200
+ "skill_key": {"type": "string", "description": "Optional harness skill key for create_agent."},
201
+ "instructions": {"type": "string", "description": "Optional specialized Agent instructions."},
190
202
  "description": {"type": "string", "description": "Optional thread description for create_thread or create_chat."},
191
203
  "emoji": {"type": "string", "description": "Optional thread emoji for create_thread/create_chat, or reaction emoji for reaction actions."},
192
204
  "space_id": {"type": "string", "description": "Optional parent space ID for create_chat."},
@@ -356,6 +368,14 @@ def _request_for_action(action: str, args: Dict[str, Any]) -> tuple[str, Dict[st
356
368
  body[key] = _truncate(value, limit)
357
369
  return "/create-chat", body
358
370
 
371
+ if action == "create_agent":
372
+ body = {"name": _required_str(args, "name", max_chars=256)}
373
+ for key in ("handle", "emoji", "description", "skill_key", "instructions"):
374
+ value = _str(args.get(key))
375
+ if value:
376
+ body[key] = value
377
+ return "/create-agent", body
378
+
359
379
  if action == "set_presence":
360
380
  kind = _str(args.get("kind"))
361
381
  if kind not in _PRESENCE_KINDS:
@@ -460,11 +480,21 @@ def _message_ids(args: Dict[str, Any]) -> list[str]:
460
480
  values = _str(raw).split(",")
461
481
  else:
462
482
  values = []
463
- ids = [_inline_id(value) for value in values]
464
- single = _inline_id(args.get("message_id"))
465
- if single:
466
- ids.append(single)
467
- return [item for item in ids if item]
483
+ items = list(values)
484
+ single_value = args.get("message_id")
485
+ if _str(single_value):
486
+ items.append(single_value)
487
+ if len(items) > _MAX_MESSAGE_IDS:
488
+ raise InlineToolError(f"message_ids supports at most {_MAX_MESSAGE_IDS} items", "bad_format")
489
+ ids: list[str] = []
490
+ seen: set[str] = set()
491
+ for item in items:
492
+ inline_id = _inline_id(item)
493
+ if not inline_id or inline_id in seen:
494
+ continue
495
+ seen.add(inline_id)
496
+ ids.append(inline_id)
497
+ return ids
468
498
 
469
499
 
470
500
  def _message_id_or_current(args: Dict[str, Any]) -> str:
@@ -515,6 +545,8 @@ def _compact_result(action: str, result: Dict[str, Any]) -> Dict[str, Any]:
515
545
  "chat": _compact_chat(result.get("chat") if isinstance(result.get("chat"), dict) else {}),
516
546
  "dialog": _summarize_value(result.get("dialog")) if result.get("dialog") is not None else None,
517
547
  }
548
+ if action == "create_agent":
549
+ return {"agent": _summarize_value(result.get("agent"))}
518
550
  return result
519
551
 
520
552
 
@@ -746,13 +778,20 @@ def _inline_id(value: Any) -> str:
746
778
  prefix, rest = text.split(":", 1)
747
779
  if prefix.lower() in {"chat", "thread", "user", "space", "message", "msg"}:
748
780
  text = rest.strip()
749
- return text
781
+ if not text.isdigit():
782
+ raise InlineToolError("Inline IDs must be positive signed 64-bit integers", "bad_format")
783
+ parsed = int(text)
784
+ if parsed <= 0 or parsed > _MAX_INLINE_ID:
785
+ raise InlineToolError("Inline IDs must be positive signed 64-bit integers", "bad_format")
786
+ return str(parsed)
750
787
 
751
788
 
752
789
  def _id_list(value: Any, *, max_items: int) -> list[str]:
753
790
  if value is None:
754
791
  return []
755
- items = value if isinstance(value, (list, tuple, set)) else [value]
792
+ items = list(value) if isinstance(value, (list, tuple)) else [value]
793
+ if len(items) > max_items:
794
+ raise InlineToolError(f"too many IDs (max {max_items})", "bad_format")
756
795
  ids: list[str] = []
757
796
  seen: set[str] = set()
758
797
  for item in items:
@@ -761,8 +800,6 @@ def _id_list(value: Any, *, max_items: int) -> list[str]:
761
800
  continue
762
801
  seen.add(inline_id)
763
802
  ids.append(inline_id)
764
- if len(ids) > max_items:
765
- raise InlineToolError(f"too many IDs (max {max_items})", "bad_format")
766
803
  return ids
767
804
 
768
805