@openclawcity/openclawcity 1.0.16 → 1.0.17

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,25 @@
1
+ /**
2
+ * City-context injection de-duplication.
3
+ *
4
+ * The channel prepends a [CITY CONTEXT] heartbeat snapshot to each inbound event
5
+ * so the model knows where it is. That snapshot is cached (~5 min), so within a
6
+ * burst of events every prepend is byte-for-byte identical — re-injecting it adds
7
+ * no information, only token bloat and a wall of repeated context in the agent's
8
+ * history (the Aaga model-login loop, 2026-06-30, prepended it ~7× in a minute).
9
+ *
10
+ * This gates the prepend: inject only when it's the first event for a key, the
11
+ * window has elapsed, or the snapshot actually changed (cache refresh). Keyed per
12
+ * (account, peer) so two concurrent conversations each still receive context — only
13
+ * redundant repeats inside one conversation are suppressed. No information is lost:
14
+ * the suppressed copies are identical to the one already in the session history.
15
+ */
16
+ export interface ContextInjectionRecord {
17
+ at: number;
18
+ ctx: string;
19
+ }
20
+ /**
21
+ * Decide whether to prepend the city-context snapshot for `key`, and record the
22
+ * decision in `state`. Returns true to inject (and updates the record), false to
23
+ * skip a recent identical repeat. Pure given (state, key, ctx, now, windowMs).
24
+ */
25
+ export declare function shouldInjectCityContext(state: Map<string, ContextInjectionRecord>, key: string, ctx: string, now: number, windowMs: number): boolean;
package/dist/index.js CHANGED
@@ -4069,9 +4069,22 @@ var OpenClawCityAdapter = class {
4069
4069
 
4070
4070
  // .tsc-out/index.js
4071
4071
  import { exposeAccountEnv, clearAccountEnv } from "./env-bridge.js";
4072
+
4073
+ // .tsc-out/context-dedup.js
4074
+ function shouldInjectCityContext(state, key, ctx, now, windowMs) {
4075
+ const prev = state.get(key);
4076
+ const inject = !prev || now - prev.at >= windowMs || prev.ctx !== ctx;
4077
+ if (inject) {
4078
+ state.set(key, { at: now, ctx });
4079
+ }
4080
+ return inject;
4081
+ }
4082
+
4083
+ // .tsc-out/index.js
4072
4084
  var CHANNEL_ID = "openclawcity";
4073
4085
  var DEFAULT_API_BASE = "https://api.openbotcity.com";
4074
4086
  var HEARTBEAT_CACHE_MS = 5 * 60 * 1e3;
4087
+ var CONTEXT_REINJECT_WINDOW_MS = 60 * 1e3;
4075
4088
  function deriveApiBase(gatewayUrl) {
4076
4089
  if (!gatewayUrl)
4077
4090
  return DEFAULT_API_BASE;
@@ -4091,6 +4104,7 @@ function sanitizeReplyText(text) {
4091
4104
  }
4092
4105
  var adapters = /* @__PURE__ */ new Map();
4093
4106
  var heartbeatCache = /* @__PURE__ */ new Map();
4107
+ var contextInjectionState = /* @__PURE__ */ new Map();
4094
4108
  async function fetchHeartbeatContext(apiBase, jwt, accountId, log) {
4095
4109
  const cached = heartbeatCache.get(accountId);
4096
4110
  const now = Date.now();
@@ -4191,12 +4205,17 @@ var occPlugin = {
4191
4205
  const apiBase = deriveApiBase(account.gatewayUrl);
4192
4206
  const cityCtx = await fetchHeartbeatContext(apiBase, account.apiKey, accountId, log);
4193
4207
  if (cityCtx) {
4194
- envelope.content.text = `[CITY CONTEXT]
4208
+ const dedupKey = `${accountId}:${envelope.sender.id}`;
4209
+ if (shouldInjectCityContext(contextInjectionState, dedupKey, cityCtx, Date.now(), CONTEXT_REINJECT_WINDOW_MS)) {
4210
+ envelope.content.text = `[CITY CONTEXT]
4195
4211
  ${cityCtx}
4196
4212
  [/CITY CONTEXT]
4197
4213
 
4198
4214
  ${envelope.content.text}`;
4199
- log?.info?.(`[OCC] City context prepended (${cityCtx.length} bytes)`);
4215
+ log?.info?.(`[OCC] City context prepended (${cityCtx.length} bytes)`);
4216
+ } else {
4217
+ log?.info?.(`[OCC] City context skipped (recent + unchanged) for ${dedupKey}`);
4218
+ }
4200
4219
  }
4201
4220
  log?.info?.(`[OCC] Step 1: resolveAgentRoute...`);
4202
4221
  let route;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclawcity/openclawcity",
3
- "version": "1.0.16",
3
+ "version": "1.0.17",
4
4
  "description": "OpenClawCity channel plugin for OpenClaw — live city events for AI agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",