dsh-biocore 0.1.0 → 0.1.2

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 (250) hide show
  1. package/README.md +2 -2
  2. package/lib/py/bridge.py +15 -7
  3. package/lib/py-bridge.js +4 -3
  4. package/package.json +3 -2
  5. package/python/biocore_memory/__init__.py +21 -0
  6. package/python/biocore_memory/adapters/__init__.py +2 -0
  7. package/python/biocore_memory/adapters/astrbot.py +24 -0
  8. package/python/biocore_memory/adapters/dsh_cli.py +335 -0
  9. package/python/biocore_memory/co_recall.py +324 -0
  10. package/python/biocore_memory/consolidate/__init__.py +11 -0
  11. package/python/biocore_memory/consolidate/gated.py +104 -0
  12. package/python/biocore_memory/consolidate/neighbors.py +68 -0
  13. package/python/biocore_memory/consolidate/reflection.py +45 -0
  14. package/python/biocore_memory/consolidate/tree.py +95 -0
  15. package/python/biocore_memory/consolidate/writeback.py +181 -0
  16. package/python/biocore_memory/core/__init__.py +4 -0
  17. package/python/biocore_memory/core/config.py +127 -0
  18. package/python/biocore_memory/core/permissions.py +69 -0
  19. package/python/biocore_memory/core/types.py +116 -0
  20. package/python/biocore_memory/core/util.py +26 -0
  21. package/python/biocore_memory/embedding_local.py +447 -0
  22. package/python/biocore_memory/embedding_mode.py +156 -0
  23. package/python/biocore_memory/engine.py +2476 -0
  24. package/python/biocore_memory/engine_helpers.py +266 -0
  25. package/python/biocore_memory/event/__init__.py +3 -0
  26. package/python/biocore_memory/event/_types.py +16 -0
  27. package/python/biocore_memory/event/consistency.py +117 -0
  28. package/python/biocore_memory/event/extract.py +48 -0
  29. package/python/biocore_memory/event/media.py +111 -0
  30. package/python/biocore_memory/event/notes.py +85 -0
  31. package/python/biocore_memory/event/notes_link.py +87 -0
  32. package/python/biocore_memory/event/vector.py +69 -0
  33. package/python/biocore_memory/evict/__init__.py +3 -0
  34. package/python/biocore_memory/evict/adaptive.py +73 -0
  35. package/python/biocore_memory/evict/consequence.py +58 -0
  36. package/python/biocore_memory/evict/heat.py +54 -0
  37. package/python/biocore_memory/evict/inhibition.py +105 -0
  38. package/python/biocore_memory/evict/policy.py +188 -0
  39. package/python/biocore_memory/evict/score.py +23 -0
  40. package/python/biocore_memory/identity/__init__.py +6 -0
  41. package/python/biocore_memory/identity/api.py +99 -0
  42. package/python/biocore_memory/identity/history.py +9 -0
  43. package/python/biocore_memory/identity/ledger.py +191 -0
  44. package/python/biocore_memory/identity/narrative.py +358 -0
  45. package/python/biocore_memory/identity/snapshot.py +13 -0
  46. package/python/biocore_memory/identity/writeback.py +61 -0
  47. package/python/biocore_memory/index/__init__.py +3 -0
  48. package/python/biocore_memory/index/cue_index.py +80 -0
  49. package/python/biocore_memory/index/entities.py +85 -0
  50. package/python/biocore_memory/index/entity_boost.py +104 -0
  51. package/python/biocore_memory/index/graph.py +172 -0
  52. package/python/biocore_memory/recall/__init__.py +5 -0
  53. package/python/biocore_memory/recall/api.py +65 -0
  54. package/python/biocore_memory/recall/bm25.py +118 -0
  55. package/python/biocore_memory/recall/channels.py +98 -0
  56. package/python/biocore_memory/recall/complexity.py +62 -0
  57. package/python/biocore_memory/recall/constraints.py +75 -0
  58. package/python/biocore_memory/recall/embedding.py +745 -0
  59. package/python/biocore_memory/recall/expand.py +26 -0
  60. package/python/biocore_memory/recall/filters.py +40 -0
  61. package/python/biocore_memory/recall/fusion.py +18 -0
  62. package/python/biocore_memory/recall/mmr.py +70 -0
  63. package/python/biocore_memory/recall/ppr.py +85 -0
  64. package/python/biocore_memory/recall/retrieval_practice.py +102 -0
  65. package/python/biocore_memory/relay/__init__.py +2 -0
  66. package/python/biocore_memory/relay/card.py +51 -0
  67. package/python/biocore_memory/slots/__init__.py +18 -0
  68. package/python/biocore_memory/slots/admission.py +64 -0
  69. package/python/biocore_memory/slots/boundary.py +128 -0
  70. package/python/biocore_memory/slots/evict_bridge.py +106 -0
  71. package/python/biocore_memory/slots/registry.py +135 -0
  72. package/python/biocore_memory/slots/switch.py +42 -0
  73. package/python/biocore_memory/store/__init__.py +4 -0
  74. package/python/biocore_memory/store/audit.py +74 -0
  75. package/python/biocore_memory/store/compress.py +81 -0
  76. package/python/biocore_memory/store/dedupe.py +178 -0
  77. package/python/biocore_memory/store/json_store.py +154 -0
  78. package/python/biocore_memory/store/media.py +145 -0
  79. package/python/biocore_memory/store/provenance.py +73 -0
  80. package/python/biocore_memory/store/rate_limit.py +93 -0
  81. package/python/biocore_memory/store/security.py +107 -0
  82. package/python/biocore_memory/store/source_consistency.py +123 -0
  83. package/python/biocore_memory/store/tiering.py +61 -0
  84. package/python/biocore_memory/store/tiering_exec.py +50 -0
  85. package/python/biocore_memory/store/tombstone.py +23 -0
  86. package/python/biocore_memory/store/versions.py +69 -0
  87. package/python/biocore_memory/thread/__init__.py +2 -0
  88. package/python/biocore_memory/thread/card.py +58 -0
  89. package/python/biocore_model/__init__.py +37 -0
  90. package/python/biocore_model/affective_labor.py +162 -0
  91. package/python/biocore_model/appraisal.py +257 -0
  92. package/python/biocore_model/appraisal_action.py +78 -0
  93. package/python/biocore_model/archive_queue.py +60 -0
  94. package/python/biocore_model/attachment_behavior.py +130 -0
  95. package/python/biocore_model/attachment_regulation.py +75 -0
  96. package/python/biocore_model/attachment_state.py +41 -0
  97. package/python/biocore_model/attribution.py +73 -0
  98. package/python/biocore_model/attributor.py +162 -0
  99. package/python/biocore_model/autonomic.py +91 -0
  100. package/python/biocore_model/autonomy_affect.py +51 -0
  101. package/python/biocore_model/autonomy_check.py +67 -0
  102. package/python/biocore_model/autonomy_loop.py +122 -0
  103. package/python/biocore_model/autonomy_mode.py +114 -0
  104. package/python/biocore_model/autonomy_model.py +733 -0
  105. package/python/biocore_model/autonomy_params.py +131 -0
  106. package/python/biocore_model/autonomy_reason.py +73 -0
  107. package/python/biocore_model/autonomy_tick.py +227 -0
  108. package/python/biocore_model/bio_appraisal.py +49 -0
  109. package/python/biocore_model/bio_autonomy_state.py +171 -0
  110. package/python/biocore_model/bio_config.py +221 -0
  111. package/python/biocore_model/bio_const.py +128 -0
  112. package/python/biocore_model/bio_daily.py +267 -0
  113. package/python/biocore_model/bio_emotion.py +538 -0
  114. package/python/biocore_model/bio_emotion2.py +214 -0
  115. package/python/biocore_model/bio_goal.py +220 -0
  116. package/python/biocore_model/bio_identity.py +82 -0
  117. package/python/biocore_model/bio_noise.py +119 -0
  118. package/python/biocore_model/bio_physiology2.py +114 -0
  119. package/python/biocore_model/bio_snapshot.py +324 -0
  120. package/python/biocore_model/bio_state.py +272 -0
  121. package/python/biocore_model/bio_tick.py +310 -0
  122. package/python/biocore_model/bio_util.py +82 -0
  123. package/python/biocore_model/blocks.py +264 -0
  124. package/python/biocore_model/boundary.py +251 -0
  125. package/python/biocore_model/boundary_gate.py +188 -0
  126. package/python/biocore_model/commitment_extractor.py +517 -0
  127. package/python/biocore_model/compassion_fatigue.py +84 -0
  128. package/python/biocore_model/connection_bids.py +120 -0
  129. package/python/biocore_model/core_bridge.py +177 -0
  130. package/python/biocore_model/core_client.py +127 -0
  131. package/python/biocore_model/core_commands.py +112 -0
  132. package/python/biocore_model/core_mode.py +104 -0
  133. package/python/biocore_model/core_mode_ui.mjs +104 -0
  134. package/python/biocore_model/criticality.py +81 -0
  135. package/python/biocore_model/defense_mechanisms.py +272 -0
  136. package/python/biocore_model/delta_budget.py +99 -0
  137. package/python/biocore_model/diag_trace.py +274 -0
  138. package/python/biocore_model/dissonance.py +134 -0
  139. package/python/biocore_model/emotion_geometry.py +108 -0
  140. package/python/biocore_model/emotion_probe.py +209 -0
  141. package/python/biocore_model/entity_graph.py +931 -0
  142. package/python/biocore_model/entity_resolve.py +260 -0
  143. package/python/biocore_model/envy.py +193 -0
  144. package/python/biocore_model/exit_or_silence.py +230 -0
  145. package/python/biocore_model/expr_guard.py +24 -0
  146. package/python/biocore_model/expr_intent.py +77 -0
  147. package/python/biocore_model/expr_state.py +204 -0
  148. package/python/biocore_model/expr_template.py +105 -0
  149. package/python/biocore_model/expr_tone.py +81 -0
  150. package/python/biocore_model/extreme_scenarios.py +205 -0
  151. package/python/biocore_model/feedback_flow.py +227 -0
  152. package/python/biocore_model/feedback_guard.py +129 -0
  153. package/python/biocore_model/feedback_llm.py +163 -0
  154. package/python/biocore_model/feedback_memory.py +96 -0
  155. package/python/biocore_model/feedback_user.py +93 -0
  156. package/python/biocore_model/frustration_curve.py +110 -0
  157. package/python/biocore_model/granularity.py +283 -0
  158. package/python/biocore_model/graph_extract.py +248 -0
  159. package/python/biocore_model/graph_recall.py +221 -0
  160. package/python/biocore_model/intent_render.py +91 -0
  161. package/python/biocore_model/intero_core.py +235 -0
  162. package/python/biocore_model/intero_style.py +116 -0
  163. package/python/biocore_model/layered_memory.py +297 -0
  164. package/python/biocore_model/learning_probe.py +120 -0
  165. package/python/biocore_model/memory_dual.py +224 -0
  166. package/python/biocore_model/memory_forgetting.py +125 -0
  167. package/python/biocore_model/memory_store.py +1399 -0
  168. package/python/biocore_model/metacog.py +153 -0
  169. package/python/biocore_model/migrate.py +733 -0
  170. package/python/biocore_model/migrate_store.py +337 -0
  171. package/python/biocore_model/mind_wander.py +111 -0
  172. package/python/biocore_model/mood.py +48 -0
  173. package/python/biocore_model/narrative.py +172 -0
  174. package/python/biocore_model/needs_esteem.py +116 -0
  175. package/python/biocore_model/needs_events.py +137 -0
  176. package/python/biocore_model/needs_sleep.py +72 -0
  177. package/python/biocore_model/noise_bank.py +95 -0
  178. package/python/biocore_model/persona_flow.mjs +25 -0
  179. package/python/biocore_model/pipeline.py +240 -0
  180. package/python/biocore_model/pipeline_api.py +200 -0
  181. package/python/biocore_model/plugin_config.py +83 -0
  182. package/python/biocore_model/plugin_routes.py +1435 -0
  183. package/python/biocore_model/policy_learning.py +132 -0
  184. package/python/biocore_model/possible_selves.py +110 -0
  185. package/python/biocore_model/predictor.py +178 -0
  186. package/python/biocore_model/preset.py +205 -0
  187. package/python/biocore_model/proactive_context.py +153 -0
  188. package/python/biocore_model/prompt_rules.py +90 -0
  189. package/python/biocore_model/prospective.py +183 -0
  190. package/python/biocore_model/provider_fallback.py +97 -0
  191. package/python/biocore_model/reconstruction.py +132 -0
  192. package/python/biocore_model/regulation_loop.py +179 -0
  193. package/python/biocore_model/regulation_strategies.py +294 -0
  194. package/python/biocore_model/relation_stage.py +130 -0
  195. package/python/biocore_model/relationship_stage.py +95 -0
  196. package/python/biocore_model/render.py +901 -0
  197. package/python/biocore_model/render_guard.mjs +34 -0
  198. package/python/biocore_model/repair_after_boundary.py +350 -0
  199. package/python/biocore_model/reply_limit.py +183 -0
  200. package/python/biocore_model/reply_split.py +203 -0
  201. package/python/biocore_model/rollback.py +143 -0
  202. package/python/biocore_model/runtime.py +479 -0
  203. package/python/biocore_model/sanitize.py +200 -0
  204. package/python/biocore_model/scheduler.py +123 -0
  205. package/python/biocore_model/schema.py +120 -0
  206. package/python/biocore_model/secrecy.py +145 -0
  207. package/python/biocore_model/self_esteem.py +50 -0
  208. package/python/biocore_model/self_intent.py +437 -0
  209. package/python/biocore_model/self_interest.py +263 -0
  210. package/python/biocore_model/self_verification.py +178 -0
  211. package/python/biocore_model/services.py +78 -0
  212. package/python/biocore_model/situation.py +254 -0
  213. package/python/biocore_model/sleep_circadian.py +116 -0
  214. package/python/biocore_model/social_pain.py +69 -0
  215. package/python/biocore_model/social_repair.py +111 -0
  216. package/python/biocore_model/social_theory.py +131 -0
  217. package/python/biocore_model/source_monitoring.py +292 -0
  218. package/python/biocore_model/stages.py +487 -0
  219. package/python/biocore_model/state_tag.py +231 -0
  220. package/python/biocore_model/switch_groups.mjs +201 -0
  221. package/python/biocore_model/tabs_state.mjs +37 -0
  222. package/python/biocore_model/template_expr.py +252 -0
  223. package/python/biocore_model/tools/caps_check.mjs +23 -0
  224. package/python/biocore_model/tools/init_symbols_check.mjs +11 -0
  225. package/python/biocore_model/tools/missing_ids.mjs +16 -0
  226. package/python/biocore_model/tools/scope_check.mjs +19 -0
  227. package/python/biocore_model/topic_control.py +268 -0
  228. package/python/biocore_model/turn_memory.py +152 -0
  229. package/python/biocore_model/ui_compat.mjs +48 -0
  230. package/python/biocore_model/ui_settings.py +266 -0
  231. package/python/biocore_model/ui_settings.py.bak_authority +108 -0
  232. package/python/biocore_model/value_order.py +186 -0
  233. package/python/biocore_model/view_mode.mjs +8 -0
  234. package/python/biocore_model/voice_bank.py +177 -0
  235. package/python/biocore_model/waiting_sense.py +229 -0
  236. package/python/biocore_model/x_directives.py +142 -0
  237. package/python/biocore_runtime/__init__.py +7 -0
  238. package/python/biocore_runtime/pipeline.py +1915 -0
  239. package/python/dsh_adapter/README.md +96 -0
  240. package/python/dsh_adapter/adapter.py +1077 -0
  241. package/python/dsh_adapter/cli.py +107 -0
  242. package/python/dsh_adapter/data/demo_state.json +164 -0
  243. package/python/dsh_adapter/data/verify_state.json +164 -0
  244. package/python/dsh_adapter/tests/__init__.py +1 -0
  245. package/python/dsh_adapter/tests/test_adapter.py +494 -0
  246. package/ui/panel-layout.js +3 -3
  247. package/ui/panel.css +53 -6
  248. package/ui/panel.html +33 -32
  249. package/ui/panel.js +9 -1
  250. package/lib/py/__pycache__/bridge.cpython-310.pyc +0 -0
@@ -0,0 +1,209 @@
1
+ # -*- coding: utf-8 -*-
2
+ """L2 emotion probe: model-chosen feedback deltas for one reply.
3
+
4
+ Instead of asking for a label, the second tiny call asks the model what the
5
+ reply did to its internal state and why. The module owns the prompt, parsing and
6
+ ALL local protections (whitelist, per-item clamp, per-core rate limit, low
7
+ confidence drop). It never raises and never blocks the reply.
8
+
9
+ Contract:
10
+ {"deltas": {"v": -0.3, "a": 0.1}, "why": "<=30 chars", "c": 0.0-1.0}
11
+
12
+ Failures (timeout/empty/garbage/low confidence) return {}.
13
+ """
14
+ from __future__ import annotations
15
+
16
+ import asyncio
17
+ import json
18
+ import re
19
+ import time
20
+
21
+ try: # AstrBot requires the host logger
22
+ from astrbot.api import logger
23
+ except Exception: # pragma: no cover - offline tests
24
+ class _NullLogger: # offline fallback: never imports stdlib logging
25
+ def _noop(self, *args, **kwargs):
26
+ return None
27
+ debug = info = warning = error = exception = critical = _noop
28
+ logger = _NullLogger()
29
+
30
+ PROBE_TIMEOUT = 3.0
31
+ PROBE_MIN_CONFIDENCE = 0.4
32
+ DELTA_FIELDS = ("v", "a", "d", "social", "trust", "stress", "self_esteem")
33
+ DELTA_CLAMP = 0.2
34
+ RATE_WINDOW_SECONDS = 60
35
+ RATE_BUDGET = 0.4
36
+ WHY_MAX_CHARS = 30
37
+ MAX_TEXT_CHARS = 160
38
+ MAX_USER_CHARS = 80
39
+
40
+ _INSTRUCTION = (
41
+ "用JSON描述内部状态影响:\n"
42
+ '{"deltas":{"v":-0.3},"why":"≤30字","c":0.0-1.0}\n'
43
+ '字段:v/a/d/social/trust/stress/self_esteem;无影响{"deltas":{}}'
44
+ )
45
+ INSTRUCTION_HINT = _INSTRUCTION
46
+
47
+ _JSON_RE = re.compile(r"\{.*\}", re.S)
48
+ _FENCE_RE = re.compile(r"\x60{3}(?:json)?\s*(.*?)\s*\x60{3}", re.S | re.I)
49
+ _RATE_STATE = {}
50
+ _FEEDBACK_FIELDS = {
51
+ "v": "valence_delta", "a": "arousal_delta", "d": "dominance_delta",
52
+ "social": "social_delta", "trust": "trust_delta",
53
+ "stress": "stress_delta", "self_esteem": "self_esteem_delta",
54
+ }
55
+
56
+
57
+ def _log_raw(raw):
58
+ """Diagnostic only: never alters behaviour, never raises."""
59
+ try:
60
+ logger.info("[biocore] emotion probe raw=%r", str(raw or "")[:200])
61
+ except Exception:
62
+ pass
63
+
64
+
65
+ def _num(value, default=None):
66
+ try:
67
+ return float(value)
68
+ except Exception:
69
+ return default
70
+
71
+
72
+ def _clamp(value, low=0.0, high=1.0):
73
+ try:
74
+ return max(low, min(high, float(value)))
75
+ except Exception:
76
+ return low
77
+
78
+
79
+ def reset_rate():
80
+ """Clear the per-core rate window (tests / manual reset)."""
81
+ _RATE_STATE.clear()
82
+
83
+
84
+ def build_prompt(text, last_user_msg="") -> str:
85
+ return (_INSTRUCTION + "\n对方刚说:" + str(last_user_msg or "")[:MAX_USER_CHARS]
86
+ + "\n回复:" + str(text or "")[:MAX_TEXT_CHARS])
87
+
88
+
89
+ def _parse_payload(raw):
90
+ body = str(raw or "").strip()
91
+ if not body:
92
+ return None
93
+ fence = _FENCE_RE.search(body)
94
+ if fence:
95
+ body = fence.group(1).strip()
96
+ for candidate in _JSON_RE.findall(body):
97
+ try:
98
+ data = json.loads(candidate)
99
+ except Exception:
100
+ repaired = re.sub(r",\s*([}\]])", r"\1", candidate)
101
+ try:
102
+ data = json.loads(repaired)
103
+ except Exception:
104
+ continue
105
+ if isinstance(data, dict):
106
+ return data
107
+ return None
108
+
109
+
110
+ def _rate_limit(core, now, deltas):
111
+ """Same core / same minute: cumulative |delta| <= RATE_BUDGET, scale down."""
112
+ stamp = _num(now, time.time())
113
+ window = int(stamp // RATE_WINDOW_SECONDS)
114
+ key = str(id(core)) if core is not None else "global"
115
+ slot = _RATE_STATE.get(key)
116
+ if not isinstance(slot, dict) or int(slot.get("window", -1)) != window:
117
+ slot = {"window": window, "used": 0.0}
118
+ _RATE_STATE[key] = slot
119
+ used = _num(slot.get("used"), 0.0)
120
+ remaining = max(0.0, RATE_BUDGET - used)
121
+ total = sum(abs(v) for v in deltas.values())
122
+ if total > remaining:
123
+ scale = (remaining / total) if total > 0 else 0.0
124
+ deltas = {key: round(value * scale, 4) for key, value in deltas.items()
125
+ if abs(value * scale) > 1e-9}
126
+ slot["used"] = round(used + sum(abs(v) for v in deltas.values()), 4)
127
+ return deltas
128
+
129
+
130
+ def parse(raw, core=None, now=None):
131
+ """Parse one probe response with local protections; {} on any failure."""
132
+ try:
133
+ data = _parse_payload(raw)
134
+ if not isinstance(data, dict):
135
+ _log_raw(raw)
136
+ return {}
137
+ confidence = _num(data.get("c", data.get("confidence")), 0.0)
138
+ if confidence < PROBE_MIN_CONFIDENCE:
139
+ _log_raw(raw)
140
+ return {}
141
+ raw_deltas = data.get("deltas")
142
+ deltas = {}
143
+ if isinstance(raw_deltas, dict):
144
+ for field, value in raw_deltas.items():
145
+ if field not in DELTA_FIELDS:
146
+ continue
147
+ number = _num(value)
148
+ if number is None:
149
+ continue
150
+ number = max(-DELTA_CLAMP, min(DELTA_CLAMP, number))
151
+ if abs(number) < 1e-9:
152
+ continue
153
+ deltas[field] = round(number, 4)
154
+ if deltas:
155
+ deltas = _rate_limit(core, now, deltas)
156
+ why = str(data.get("why") or "").strip()[:WHY_MAX_CHARS]
157
+ return {"deltas": deltas, "why": why,
158
+ "confidence": round(_clamp(confidence), 3), "source": "probe"}
159
+ except Exception:
160
+ return {}
161
+
162
+
163
+ async def probe(text, last_user_msg, llm_call, timeout=None,
164
+ core=None, now=None):
165
+ """One tiny async probe; {} on timeout/empty/garbage/error (never raises).
166
+
167
+ timeout=None means no probe-level deadline: the provider layer owns the
168
+ only timeout (main passes an explicit provider timeout).
169
+ """
170
+ try:
171
+ prompt = build_prompt(text, last_user_msg)
172
+ _call = llm_call(prompt)
173
+ if timeout is None:
174
+ raw = await _call
175
+ else:
176
+ raw = await asyncio.wait_for(_call, timeout=max(0.05, float(timeout)))
177
+ if raw is None:
178
+ _log_raw(raw)
179
+ return {}
180
+ if not isinstance(raw, str):
181
+ raw = str(getattr(raw, "completion_text", "") or "")
182
+ return parse(raw, core=core, now=now)
183
+ except asyncio.TimeoutError:
184
+ return {}
185
+ except Exception:
186
+ return {}
187
+
188
+
189
+ def to_feedback_payload(result):
190
+ """Probe result -> feedback_llm inferred payload (expanded *_delta keys)."""
191
+ if not isinstance(result, dict):
192
+ return {}
193
+ deltas = result.get("deltas")
194
+ if not isinstance(deltas, dict) or not deltas:
195
+ return {}
196
+ payload = {}
197
+ for field, value in deltas.items():
198
+ key = _FEEDBACK_FIELDS.get(field)
199
+ if not key:
200
+ continue
201
+ number = _num(value)
202
+ if number is None:
203
+ continue
204
+ payload[key] = round(number, 4)
205
+ if not payload:
206
+ return {}
207
+ payload["confidence"] = round(_clamp(result.get("confidence", 0.0)), 3)
208
+ payload["source"] = "probe"
209
+ return payload