@vainplex/openclaw-membrane 0.3.1 → 0.3.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.
@@ -0,0 +1,192 @@
1
+ syntax = "proto3";
2
+
3
+ package membrane.v1;
4
+
5
+ option go_package = "github.com/GustyCube/membrane/api/grpc/gen/membranev1";
6
+
7
+ service MembraneService {
8
+ rpc IngestEvent(IngestEventRequest) returns (IngestResponse);
9
+ rpc IngestToolOutput(IngestToolOutputRequest) returns (IngestResponse);
10
+ rpc IngestObservation(IngestObservationRequest) returns (IngestResponse);
11
+ rpc IngestOutcome(IngestOutcomeRequest) returns (IngestResponse);
12
+ rpc IngestWorkingState(IngestWorkingStateRequest) returns (IngestResponse);
13
+ rpc Retrieve(RetrieveRequest) returns (RetrieveResponse);
14
+ rpc RetrieveByID(RetrieveByIDRequest) returns (MemoryRecordResponse);
15
+ rpc Supersede(SupersedeRequest) returns (MemoryRecordResponse);
16
+ rpc Fork(ForkRequest) returns (MemoryRecordResponse);
17
+ rpc Retract(RetractRequest) returns (RetractResponse);
18
+ rpc Merge(MergeRequest) returns (MemoryRecordResponse);
19
+ rpc Reinforce(ReinforceRequest) returns (ReinforceResponse);
20
+ rpc Penalize(PenalizeRequest) returns (PenalizeResponse);
21
+ rpc GetMetrics(GetMetricsRequest) returns (MetricsResponse);
22
+ rpc Contest(ContestRequest) returns (ContestResponse);
23
+ }
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // Ingestion messages
27
+ // ---------------------------------------------------------------------------
28
+
29
+ message IngestEventRequest {
30
+ string source = 1;
31
+ string event_kind = 2;
32
+ string ref = 3;
33
+ string summary = 4;
34
+ string timestamp = 5; // RFC 3339
35
+ repeated string tags = 6;
36
+ string scope = 7;
37
+ string sensitivity = 8;
38
+ }
39
+
40
+ message IngestToolOutputRequest {
41
+ string source = 1;
42
+ string tool_name = 2;
43
+ bytes args = 3; // JSON-encoded map
44
+ bytes result = 4; // JSON-encoded value
45
+ repeated string depends_on = 5;
46
+ string timestamp = 6; // RFC 3339
47
+ repeated string tags = 7;
48
+ string scope = 8;
49
+ string sensitivity = 9;
50
+ }
51
+
52
+ message IngestObservationRequest {
53
+ string source = 1;
54
+ string subject = 2;
55
+ string predicate = 3;
56
+ bytes object = 4; // JSON-encoded value
57
+ string timestamp = 5; // RFC 3339
58
+ repeated string tags = 6;
59
+ string scope = 7;
60
+ string sensitivity = 8;
61
+ }
62
+
63
+ message IngestOutcomeRequest {
64
+ string source = 1;
65
+ string target_record_id = 2;
66
+ string outcome_status = 3; // success | failure | partial
67
+ string timestamp = 4; // RFC 3339
68
+ }
69
+
70
+ message IngestWorkingStateRequest {
71
+ string source = 1;
72
+ string thread_id = 2;
73
+ string state = 3;
74
+ repeated string next_actions = 4;
75
+ repeated string open_questions = 5;
76
+ string context_summary = 6;
77
+ bytes active_constraints = 7; // JSON-encoded []Constraint
78
+ string timestamp = 8; // RFC 3339
79
+ repeated string tags = 9;
80
+ string scope = 10;
81
+ string sensitivity = 11;
82
+ }
83
+
84
+ message IngestResponse {
85
+ bytes record = 1; // JSON-encoded MemoryRecord
86
+ }
87
+
88
+ // ---------------------------------------------------------------------------
89
+ // Retrieval messages
90
+ // ---------------------------------------------------------------------------
91
+
92
+ message TrustContext {
93
+ string max_sensitivity = 1;
94
+ bool authenticated = 2;
95
+ string actor_id = 3;
96
+ repeated string scopes = 4;
97
+ }
98
+
99
+ message RetrieveRequest {
100
+ string task_descriptor = 1;
101
+ TrustContext trust = 2;
102
+ repeated string memory_types = 3;
103
+ double min_salience = 4;
104
+ int32 limit = 5;
105
+ }
106
+
107
+ message RetrieveResponse {
108
+ repeated bytes records = 1; // JSON-encoded MemoryRecord array
109
+ bytes selection = 2; // JSON-encoded SelectionResult, optional
110
+ }
111
+
112
+ message RetrieveByIDRequest {
113
+ string id = 1;
114
+ TrustContext trust = 2;
115
+ }
116
+
117
+ message MemoryRecordResponse {
118
+ bytes record = 1; // JSON-encoded MemoryRecord
119
+ }
120
+
121
+ // ---------------------------------------------------------------------------
122
+ // Revision messages
123
+ // ---------------------------------------------------------------------------
124
+
125
+ message SupersedeRequest {
126
+ string old_id = 1;
127
+ bytes new_record = 2; // JSON-encoded MemoryRecord
128
+ string actor = 3;
129
+ string rationale = 4;
130
+ }
131
+
132
+ message ForkRequest {
133
+ string source_id = 1;
134
+ bytes forked_record = 2; // JSON-encoded MemoryRecord
135
+ string actor = 3;
136
+ string rationale = 4;
137
+ }
138
+
139
+ message RetractRequest {
140
+ string id = 1;
141
+ string actor = 2;
142
+ string rationale = 3;
143
+ }
144
+
145
+ message RetractResponse {}
146
+
147
+ message MergeRequest {
148
+ repeated string ids = 1;
149
+ bytes merged_record = 2; // JSON-encoded MemoryRecord
150
+ string actor = 3;
151
+ string rationale = 4;
152
+ }
153
+
154
+ message ContestRequest {
155
+ string id = 1;
156
+ string contesting_ref = 2;
157
+ string actor = 3;
158
+ string rationale = 4;
159
+ }
160
+
161
+ message ContestResponse {}
162
+
163
+ // ---------------------------------------------------------------------------
164
+ // Decay messages
165
+ // ---------------------------------------------------------------------------
166
+
167
+ message ReinforceRequest {
168
+ string id = 1;
169
+ string actor = 2;
170
+ string rationale = 3;
171
+ }
172
+
173
+ message ReinforceResponse {}
174
+
175
+ message PenalizeRequest {
176
+ string id = 1;
177
+ double amount = 2;
178
+ string actor = 3;
179
+ string rationale = 4;
180
+ }
181
+
182
+ message PenalizeResponse {}
183
+
184
+ // ---------------------------------------------------------------------------
185
+ // Metrics messages
186
+ // ---------------------------------------------------------------------------
187
+
188
+ message GetMetricsRequest {}
189
+
190
+ message MetricsResponse {
191
+ bytes snapshot = 1; // JSON-encoded metrics.Snapshot
192
+ }
package/dist/index.js CHANGED
@@ -149,17 +149,27 @@ const SEARCH_TOOL_SCHEMA = {
149
149
  const plugin = {
150
150
  id: 'openclaw-membrane',
151
151
  name: '@vainplex/openclaw-membrane',
152
- version: '0.3.1',
152
+ version: '0.3.2',
153
153
  register(api) {
154
154
  const config = createConfig(api.pluginConfig);
155
155
  const logger = api.logger;
156
156
  const client = new MembraneClient(config.grpc_endpoint);
157
157
  const reliability = new ReliabilityManager(config.buffer_size, async (item) => { await client.call(item.method, item.payload); }, logger);
158
158
  logger.info(`[membrane] Registered bridge to ${config.grpc_endpoint}`);
159
- // Write path: subscribe to events
160
- api.on('event', (event) => {
161
- handleEvent(event, config, reliability, logger);
162
- });
159
+ // Write path: subscribe to specific OpenClaw hooks
160
+ // OpenClaw fires named hooks, not a generic 'event' hook
161
+ const hookHandler = (type) => (event, ctx) => {
162
+ const e = event;
163
+ const c = ctx;
164
+ handleEvent({ type, payload: e, context: c }, config, reliability, logger);
165
+ };
166
+ api.on('message_received', hookHandler('message_received'));
167
+ api.on('message_sent', hookHandler('message_sent'));
168
+ api.on('message_sending', hookHandler('message_sending'));
169
+ // after_tool_call removed — tool calls are operational logs, not memories.
170
+ // They flood Membrane (~95% of volume) and drown out actual conversations.
171
+ // Tool data is already captured in NATS event store.
172
+ api.on('session_start', hookHandler('session_start'));
163
173
  // Search tool: gRPC Retrieve (boosts salience via rehearsal)
164
174
  api.registerTool({
165
175
  name: 'membrane_search',
package/dist/mapping.js CHANGED
@@ -112,6 +112,7 @@ export function mapEvent(event, sensitivity) {
112
112
  case 'message_received':
113
113
  return mapMessageReceived(event.payload, timestamp, sensitivity);
114
114
  case 'message_sent':
115
+ case 'message_sending':
115
116
  return mapMessageSent(event.payload, timestamp, sensitivity);
116
117
  case 'session_start':
117
118
  return mapSessionStart(timestamp, sensitivity);
@@ -2,7 +2,7 @@
2
2
  "id": "openclaw-membrane",
3
3
  "name": "@vainplex/openclaw-membrane",
4
4
  "description": "Membrane gRPC bridge for OpenClaw — episodic memory ingestion, search tool, and auto-context injection",
5
- "version": "0.3.1",
5
+ "version": "0.3.2",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "additionalProperties": true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vainplex/openclaw-membrane",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "type": "module",
5
5
  "description": "Membrane gRPC bridge for OpenClaw — episodic memory ingestion, search tool, and auto-context injection via Membrane sidecar",
6
6
  "main": "dist/index.js",