@mobcode/openclaw-plugin 0.1.15 → 0.1.16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mobcode/openclaw-plugin",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "MobCode integration plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -67,6 +67,16 @@ export function createMobcodePluginDefinition() {
67
67
  api,
68
68
  store,
69
69
  });
70
+ api.on("tool_result_persist", (event, ctx) => {
71
+ store.appendMessageSync({
72
+ sessionKey: ctx?.sessionKey,
73
+ message: event?.message,
74
+ messageId:
75
+ typeof event?.message?.id === "string" && event.message.id.trim()
76
+ ? event.message.id.trim()
77
+ : undefined,
78
+ });
79
+ });
70
80
  },
71
81
  };
72
82
  }
@@ -996,10 +996,129 @@ export class MobcodeStateStore {
996
996
  this.logger?.warn?.(
997
997
  `[mobcode-debug] appendMessage sessionKey=${sessionKey} messageId=${String(update?.messageId ?? normalizedMessage?.id ?? "").trim() || "-"} role=${String(normalizedMessage?.role ?? "").trim() || "-"} toolCallId=${String(normalizedMessage?.toolCallId ?? "").trim() || "-"} sourceKey=${createMessageSourceKey(sessionKey, String(update?.messageId ?? normalizedMessage?.id ?? "").trim() || null, normalizedMessage)}`,
998
998
  );
999
- await this.indexSessionMessages(sessionKey, [normalizedMessage]);
1000
- const row = this._db()
1001
- .prepare(`SELECT COUNT(*) AS count FROM messages WHERE session_key=?`)
1002
- .get(sessionKey);
999
+ return this._appendMessageInternal({
1000
+ sessionKey,
1001
+ normalizedMessage,
1002
+ messageId: String(update?.messageId ?? normalizedMessage?.id ?? "").trim() || null,
1003
+ });
1004
+ }
1005
+
1006
+ appendMessageSync(update) {
1007
+ const sessionKey = String(update?.sessionKey ?? "").trim();
1008
+ const normalizedMessage = normalizeMessageObject(update?.message, update?.messageId);
1009
+ if (!sessionKey) {
1010
+ this.logger?.warn?.(
1011
+ `[mobcode-store] appendMessageSync skipped rawSessionKey=${String(update?.sessionKey ?? "").trim() || "-"} messageId=${String(update?.messageId ?? normalizedMessage?.id ?? "").trim() || "-"} reason=missing_session_key`,
1012
+ );
1013
+ return { sessionKey: null, count: 0, skipped: true };
1014
+ }
1015
+ if (!this.database) {
1016
+ this.logger?.warn?.(
1017
+ `[mobcode-store] appendMessageSync skipped sessionKey=${sessionKey} messageId=${String(update?.messageId ?? normalizedMessage?.id ?? "").trim() || "-"} reason=store_not_initialized`,
1018
+ );
1019
+ return { sessionKey, count: 0, skipped: true };
1020
+ }
1021
+ this.logger?.warn?.(
1022
+ `[mobcode-debug] appendMessageSync sessionKey=${sessionKey} messageId=${String(update?.messageId ?? normalizedMessage?.id ?? "").trim() || "-"} role=${String(normalizedMessage?.role ?? "").trim() || "-"} toolCallId=${String(normalizedMessage?.toolCallId ?? "").trim() || "-"} sourceKey=${createMessageSourceKey(sessionKey, String(update?.messageId ?? normalizedMessage?.id ?? "").trim() || null, normalizedMessage)}`,
1023
+ );
1024
+ return this._appendMessageInternal({
1025
+ sessionKey,
1026
+ normalizedMessage,
1027
+ messageId: String(update?.messageId ?? normalizedMessage?.id ?? "").trim() || null,
1028
+ });
1029
+ }
1030
+
1031
+ _appendMessageInternal({ sessionKey, normalizedMessage, messageId }) {
1032
+ const db = this._db();
1033
+ const insert = db.prepare(
1034
+ `INSERT OR IGNORE INTO messages(
1035
+ session_key,
1036
+ source_key,
1037
+ message_id,
1038
+ role,
1039
+ text,
1040
+ raw_json,
1041
+ created_at_ms,
1042
+ indexed_at
1043
+ ) VALUES(?, ?, ?, ?, ?, ?, ?, ?)`,
1044
+ );
1045
+ const touchSession = db.prepare(
1046
+ `INSERT INTO indexed_sessions(session_key, updated_at)
1047
+ VALUES(?, ?)
1048
+ ON CONFLICT(session_key) DO UPDATE SET updated_at=excluded.updated_at`,
1049
+ );
1050
+ const upsertArtifact = db.prepare(
1051
+ `INSERT INTO artifacts(
1052
+ artifact_id,
1053
+ session_key,
1054
+ run_id,
1055
+ kind,
1056
+ title,
1057
+ summary,
1058
+ document_json,
1059
+ created_at_ms,
1060
+ updated_at_ms
1061
+ ) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)
1062
+ ON CONFLICT(artifact_id) DO UPDATE SET
1063
+ session_key=excluded.session_key,
1064
+ run_id=excluded.run_id,
1065
+ kind=excluded.kind,
1066
+ title=excluded.title,
1067
+ summary=excluded.summary,
1068
+ document_json=excluded.document_json,
1069
+ updated_at_ms=excluded.updated_at_ms`,
1070
+ );
1071
+ const now = new Date().toISOString();
1072
+ const sourceKey = createMessageSourceKey(sessionKey, messageId, normalizedMessage);
1073
+ const timestampRaw =
1074
+ normalizedMessage?.timestamp ?? normalizedMessage?.createdAt ?? Date.now();
1075
+ const createdAtMs =
1076
+ typeof timestampRaw === "number"
1077
+ ? timestampRaw
1078
+ : Number.parseInt(String(timestampRaw), 10) || Date.now();
1079
+
1080
+ db.exec("BEGIN");
1081
+ try {
1082
+ insert.run(
1083
+ sessionKey,
1084
+ sourceKey,
1085
+ messageId,
1086
+ String(normalizedMessage?.role ?? "").trim() || null,
1087
+ extractMessageText(normalizedMessage),
1088
+ toJson(normalizedMessage),
1089
+ createdAtMs,
1090
+ now,
1091
+ );
1092
+ const artifactDocument = extractArtifactDocumentFromMessage(normalizedMessage);
1093
+ const artifactId = String(
1094
+ artifactDocument?.artifactId ?? artifactDocument?.artifact_id ?? "",
1095
+ ).trim();
1096
+ const artifactKind = String(artifactDocument?.kind ?? "").trim();
1097
+ const artifactTitle = String(artifactDocument?.title ?? "").trim();
1098
+ if (artifactId && artifactKind && artifactTitle) {
1099
+ upsertArtifact.run(
1100
+ artifactId,
1101
+ sessionKey,
1102
+ String(normalizedMessage?.runId ?? normalizedMessage?.run_id ?? "").trim() || null,
1103
+ artifactKind,
1104
+ artifactTitle,
1105
+ String(artifactDocument?.summary ?? "").trim() || null,
1106
+ toJson(artifactDocument),
1107
+ createdAtMs,
1108
+ createdAtMs,
1109
+ );
1110
+ }
1111
+ touchSession.run(sessionKey, now);
1112
+ db.exec("COMMIT");
1113
+ } catch (error) {
1114
+ try {
1115
+ db.exec("ROLLBACK");
1116
+ } catch {
1117
+ // Ignore rollback failures so the original write error is preserved.
1118
+ }
1119
+ throw error;
1120
+ }
1121
+ const row = db.prepare(`SELECT COUNT(*) AS count FROM messages WHERE session_key=?`).get(sessionKey);
1003
1122
  return { sessionKey, count: Number(row?.count ?? 0), skipped: false };
1004
1123
  }
1005
1124