@akalsey/sapience-thinking 0.1.4 → 0.2.1
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/dist/src/events.js +12 -0
- package/dist/src/service.js +16 -0
- package/dist/src/types.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { appendFile, mkdir } from "fs/promises";
|
|
2
|
+
import { dirname } from "path";
|
|
3
|
+
export async function appendEvent(eventsPath, event) {
|
|
4
|
+
try {
|
|
5
|
+
const full = { ...event, ts: event.ts ?? new Date().toISOString() };
|
|
6
|
+
await mkdir(dirname(eventsPath), { recursive: true });
|
|
7
|
+
await appendFile(eventsPath, JSON.stringify(full) + "\n", "utf-8");
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
// Observability must never break the host plugin.
|
|
11
|
+
}
|
|
12
|
+
}
|
package/dist/src/service.js
CHANGED
|
@@ -6,6 +6,7 @@ import { buildContext, getLastThreePasses } from "./context-builder.js";
|
|
|
6
6
|
import { buildPrompt } from "./prompt-builder.js";
|
|
7
7
|
import { parseProposals, ParseError } from "./output-parser.js";
|
|
8
8
|
import { appendPass, appendError, appendSkipped, appendStructuredProposals } from "./log-writer.js";
|
|
9
|
+
import { appendEvent } from "./events.js";
|
|
9
10
|
import { loadOutcomes, saveOutcomes, addProposals, expireOldProposals } from "./outcome-tracker.js";
|
|
10
11
|
import { computeSignal } from "./signal-analyzer.js";
|
|
11
12
|
import { maybeDeliver } from "./delivery.js";
|
|
@@ -74,6 +75,7 @@ function mergeConfig(raw, workspaceDir) {
|
|
|
74
75
|
...(raw.output ?? {}),
|
|
75
76
|
logPath: resolveDataPath(raw.output?.logPath, workspaceDir, DEFAULT_CONFIG.output.logPath),
|
|
76
77
|
trackerPath: resolveDataPath(raw.output?.trackerPath, workspaceDir, DEFAULT_CONFIG.output.trackerPath),
|
|
78
|
+
eventsPath: resolveDataPath(raw.output?.eventsPath, workspaceDir, DEFAULT_CONFIG.output.eventsPath),
|
|
77
79
|
},
|
|
78
80
|
delivery: { ...DEFAULT_CONFIG.delivery, ...(raw.delivery ?? {}) },
|
|
79
81
|
learning: { ...DEFAULT_CONFIG.learning, ...(raw.learning ?? {}) },
|
|
@@ -84,6 +86,8 @@ export default definePluginEntry({
|
|
|
84
86
|
name: "Sapience Thinking",
|
|
85
87
|
description: "Periodic isolated thinking passes that produce structured proposals",
|
|
86
88
|
register(api) {
|
|
89
|
+
if (!api.runtime?.agent?.resolveAgentWorkspaceDir)
|
|
90
|
+
return;
|
|
87
91
|
const workspaceDir = api.runtime.agent.resolveAgentWorkspaceDir(api.pluginConfig);
|
|
88
92
|
const config = mergeConfig(api.pluginConfig, workspaceDir);
|
|
89
93
|
const lockDir = join(workspaceDir, "proactive-thinking");
|
|
@@ -95,11 +99,13 @@ export default definePluginEntry({
|
|
|
95
99
|
parameters: Type.Object({}),
|
|
96
100
|
async execute(_id, _params) {
|
|
97
101
|
if (!isWithinActiveHours(config)) {
|
|
102
|
+
await appendEvent(config.output.eventsPath, { plugin: "thinking", type: "pass_skipped", reason: "outside_hours" });
|
|
98
103
|
return { content: [{ type: "text", text: JSON.stringify({ status: "skip", reason: "outside_active_hours" }) }] };
|
|
99
104
|
}
|
|
100
105
|
const acquired = await acquireLock(lockDir, lockFile);
|
|
101
106
|
if (!acquired) {
|
|
102
107
|
await appendSkipped("pass_already_running", config.output.logPath);
|
|
108
|
+
await appendEvent(config.output.eventsPath, { plugin: "thinking", type: "pass_skipped", reason: "already_running" });
|
|
103
109
|
return { content: [{ type: "text", text: JSON.stringify({ status: "skip", reason: "pass_already_running" }) }] };
|
|
104
110
|
}
|
|
105
111
|
try {
|
|
@@ -134,6 +140,16 @@ export default definePluginEntry({
|
|
|
134
140
|
outcomes = expireOldProposals(outcomes);
|
|
135
141
|
await saveOutcomes(outcomes, config.output.trackerPath);
|
|
136
142
|
}
|
|
143
|
+
await appendEvent(config.output.eventsPath, {
|
|
144
|
+
plugin: "thinking",
|
|
145
|
+
type: "pass_completed",
|
|
146
|
+
pass_id: proposals.pass_id,
|
|
147
|
+
observations: proposals.observations.length,
|
|
148
|
+
actions: proposals.proposed_actions.length,
|
|
149
|
+
audits: proposals.proposed_audits.length,
|
|
150
|
+
questions: proposals.open_questions.length,
|
|
151
|
+
nothing_to_report: proposals.nothing_to_report,
|
|
152
|
+
});
|
|
137
153
|
const sapienceActive = await access(join(workspaceDir, "sapience", ".present")).then(() => true, () => false);
|
|
138
154
|
if (!sapienceActive)
|
|
139
155
|
await maybeDeliver(proposals, api, config);
|
package/dist/src/types.js
CHANGED
|
@@ -43,6 +43,7 @@ export const DEFAULT_CONFIG = {
|
|
|
43
43
|
output: {
|
|
44
44
|
logPath: "proactive-thinking/log.md",
|
|
45
45
|
trackerPath: "proactive-thinking/outcomes.json",
|
|
46
|
+
eventsPath: "sapience/events.jsonl",
|
|
46
47
|
},
|
|
47
48
|
delivery: { heartbeatTrigger: true, priorityThreshold: 4, maxProposalsPerHeartbeat: 3 },
|
|
48
49
|
learning: { trackOutcomes: true, adjustPromptBasedOnSignal: true, bootstrapDays: 14 },
|