@akalsey/openclaw-sapience 0.1.1 → 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.
@@ -11,6 +11,22 @@ export async function loadProcessedPasses(path) {
11
11
  return new Set();
12
12
  }
13
13
  }
14
+ export async function bootstrapProcessedPasses(proposalsPath, processedPath) {
15
+ try {
16
+ const content = await readFile(resolvePath(proposalsPath), "utf-8");
17
+ const ids = new Set(content.trim().split("\n").filter(Boolean)
18
+ .map(l => JSON.parse(l).pass_id));
19
+ if (ids.size === 0)
20
+ return ids;
21
+ const resolved = resolvePath(processedPath);
22
+ await mkdir(dirname(resolved), { recursive: true });
23
+ await writeFile(resolved, JSON.stringify({ pass_ids: [...ids] }, null, 2), "utf-8");
24
+ return ids;
25
+ }
26
+ catch {
27
+ return new Set();
28
+ }
29
+ }
14
30
  export async function markPassProcessed(passId, path, processed) {
15
31
  const updated = new Set([...processed, passId]);
16
32
  const resolved = resolvePath(path);
@@ -1,11 +1,13 @@
1
1
  // src/service.ts
2
+ import { writeFile, mkdir } from "fs/promises";
3
+ import { join } from "path";
2
4
  import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
3
5
  import { DEFAULT_CONFIG } from "./types.js";
4
6
  import { resolveDataPath, isWithinActiveHours } from "./utils.js";
5
7
  import { loadProfile, saveProfile, upsertEntry } from "./calibration.js";
6
8
  import { routeItem } from "./autonomy.js";
7
9
  import { readUnprocessedPasses, proposalSetToItems } from "./proposal-adapter.js";
8
- import { loadProcessedPasses, markPassProcessed } from "./processed-passes.js";
10
+ import { loadProcessedPasses, markPassProcessed, bootstrapProcessedPasses } from "./processed-passes.js";
9
11
  import { deliverItems } from "./delivery.js";
10
12
  import { isDigestDay, buildDigestPrompt } from "./weekly-digest.js";
11
13
  function mergeConfig(raw, workspaceDir) {
@@ -37,6 +39,9 @@ export default definePluginEntry({
37
39
  register(api) {
38
40
  const workspaceDir = api.runtime.agent.resolveAgentWorkspaceDir(api.pluginConfig);
39
41
  const config = mergeConfig(api.pluginConfig, workspaceDir);
42
+ // Write presence marker so sapience-thinking knows to defer direct delivery
43
+ const markerDir = join(workspaceDir, "sapience");
44
+ void mkdir(markerDir, { recursive: true }).then(() => writeFile(join(markerDir, ".present"), "", "utf-8"));
40
45
  api.registerTool({
41
46
  name: "process_proposals",
42
47
  description: "Process new proposals from the sapience-thinking log and route them through the autonomy tier function. Called by the sapience cron.",
@@ -45,10 +50,12 @@ export default definePluginEntry({
45
50
  if (!isWithinActiveHours(config)) {
46
51
  return { content: [{ type: "text", text: "SILENT_REPLY_TOKEN" }] };
47
52
  }
48
- const [processed, profile] = await Promise.all([
49
- loadProcessedPasses(config.output.processedPassesPath),
50
- loadProfile(config.output.calibrationPath),
51
- ]);
53
+ let processed = await loadProcessedPasses(config.output.processedPassesPath);
54
+ const profile = await loadProfile(config.output.calibrationPath);
55
+ // On first run, mark all existing passes as processed to avoid re-delivering stale proposals
56
+ if (processed.size === 0) {
57
+ processed = await bootstrapProcessedPasses(config.proactiveThinking.proposalsPath, config.output.processedPassesPath);
58
+ }
52
59
  const newPasses = await readUnprocessedPasses(config.proactiveThinking.proposalsPath, processed);
53
60
  let updatedProcessed = processed;
54
61
  let updatedProfile = profile;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akalsey/openclaw-sapience",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {