@oharness/engine 0.6.0 → 0.7.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/agent/agent.d.ts +83 -0
- package/dist/agent/agent.js +112 -1
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/memory-backup.d.ts +2 -0
- package/dist/agent/memory-backup.js +9 -1
- package/dist/agent/memory-backup.js.map +1 -1
- package/dist/agent/memory-limits.js +8 -1
- package/dist/agent/memory-limits.js.map +1 -1
- package/dist/agent/memory-usage.d.ts +1 -1
- package/dist/agent/memory-usage.js +2 -3
- package/dist/agent/memory-usage.js.map +1 -1
- package/dist/agent/memory.d.ts +3 -0
- package/dist/agent/memory.js +6 -18
- package/dist/agent/memory.js.map +1 -1
- package/dist/agent/session.d.ts +9 -0
- package/dist/agent/session.js +14 -2
- package/dist/agent/session.js.map +1 -1
- package/dist/agent/settings.js +3 -2
- package/dist/agent/settings.js.map +1 -1
- package/dist/agent/store.d.ts +45 -4
- package/dist/agent/store.js +198 -25
- package/dist/agent/store.js.map +1 -1
- package/dist/artifacts/files.d.ts +52 -0
- package/dist/artifacts/files.js +169 -0
- package/dist/artifacts/files.js.map +1 -0
- package/dist/auth/store.js +3 -2
- package/dist/auth/store.js.map +1 -1
- package/dist/config-files.js +3 -2
- package/dist/config-files.js.map +1 -1
- package/dist/config.d.ts +6 -1
- package/dist/config.js +10 -2
- package/dist/config.js.map +1 -1
- package/dist/harness.d.ts +62 -1
- package/dist/harness.js +174 -12
- package/dist/harness.js.map +1 -1
- package/dist/paths.d.ts +5 -0
- package/dist/paths.js +21 -3
- package/dist/paths.js.map +1 -1
- package/dist/providers/builtin.d.ts +2 -0
- package/dist/providers/builtin.js +38 -24
- package/dist/providers/builtin.js.map +1 -1
- package/dist/providers/catalog.d.ts +5 -0
- package/dist/providers/catalog.js +32 -1
- package/dist/providers/catalog.js.map +1 -1
- package/dist/providers/catalog.json +241 -123
- package/dist/providers/discovery.js +17 -0
- package/dist/providers/discovery.js.map +1 -1
- package/dist/providers/models-dev.d.ts +89 -0
- package/dist/providers/models-dev.js +160 -0
- package/dist/providers/models-dev.js.map +1 -0
- package/dist/providers/models-dev.json +821 -0
- package/dist/providers/registry.d.ts +12 -0
- package/dist/providers/registry.js +33 -1
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/types.d.ts +21 -0
- package/dist/providers/types.js +16 -0
- package/dist/providers/types.js.map +1 -1
- package/dist/runtime-plugins/builtin/memory-migrate.d.ts +5 -21
- package/dist/runtime-plugins/builtin/memory-migrate.js +5 -125
- package/dist/runtime-plugins/builtin/memory-migrate.js.map +1 -1
- package/dist/runtime-plugins/builtin/memory.d.ts +3 -0
- package/dist/runtime-plugins/builtin/memory.js +12 -10
- package/dist/runtime-plugins/builtin/memory.js.map +1 -1
- package/dist/schedule/clock.d.ts +76 -0
- package/dist/schedule/clock.js +147 -0
- package/dist/schedule/clock.js.map +1 -0
- package/dist/schedule/cron.d.ts +9 -0
- package/dist/schedule/cron.js +18 -0
- package/dist/schedule/cron.js.map +1 -1
- package/dist/schedule/lock.d.ts +38 -0
- package/dist/schedule/lock.js +100 -0
- package/dist/schedule/lock.js.map +1 -0
- package/dist/schedule/runner.d.ts +67 -0
- package/dist/schedule/runner.js +100 -0
- package/dist/schedule/runner.js.map +1 -0
- package/dist/schedule/scheduler.d.ts +56 -15
- package/dist/schedule/scheduler.js +80 -107
- package/dist/schedule/scheduler.js.map +1 -1
- package/dist/storage/kv.js +3 -2
- package/dist/storage/kv.js.map +1 -1
- package/dist/storage/project.d.ts +26 -0
- package/dist/storage/project.js +74 -15
- package/dist/storage/project.js.map +1 -1
- package/dist/tools/builtin/routine.d.ts +31 -0
- package/dist/tools/builtin/routine.js +70 -0
- package/dist/tools/builtin/routine.js.map +1 -0
- package/dist/util/fs.d.ts +6 -0
- package/dist/util/fs.js +22 -0
- package/dist/util/fs.js.map +1 -0
- package/package.json +3 -3
package/dist/auth/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/auth/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/auth/store.ts"],"names":[],"mappings":"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"}
|
package/dist/config-files.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
|
-
import { mkdir, writeFile,
|
|
2
|
+
import { mkdir, writeFile, rm } from "node:fs/promises";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { userPath } from "./paths.js";
|
|
6
6
|
import { ConfigError } from "./core/errors.js";
|
|
7
|
+
import { renameWithRetry } from "./util/fs.js";
|
|
7
8
|
/** Read only trusted user files, never a repository's executable plugin list. */
|
|
8
9
|
export function readUserFile(name) {
|
|
9
10
|
const file = userPath(name);
|
|
@@ -47,7 +48,7 @@ export async function writeUserFile(name, data) {
|
|
|
47
48
|
const temp = `${file}.${randomUUID()}.tmp`;
|
|
48
49
|
try {
|
|
49
50
|
await writeFile(temp, JSON.stringify(data, null, 2) + "\n", { mode: 0o600, flag: "wx" });
|
|
50
|
-
await
|
|
51
|
+
await renameWithRetry(temp, file);
|
|
51
52
|
}
|
|
52
53
|
finally {
|
|
53
54
|
await rm(temp, { force: true });
|
package/dist/config-files.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-files.js","sourceRoot":"","sources":["../src/config-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"config-files.js","sourceRoot":"","sources":["../src/config-files.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -59,7 +59,7 @@ export interface HarnessConfig {
|
|
|
59
59
|
schedules?: ScheduleDefinition[];
|
|
60
60
|
/**
|
|
61
61
|
* Where project notes live, relative to the project root. Legacy spelling of
|
|
62
|
-
* `memory.dir`; by default notes live
|
|
62
|
+
* `memory.dir`; by default notes live in the project's visible `MEMORY/` directory.
|
|
63
63
|
*/
|
|
64
64
|
memoryDir?: string;
|
|
65
65
|
/** Limits, recall and automatic extraction for durable notes. */
|
|
@@ -177,6 +177,11 @@ export declare function loadConfig(cwd?: string): Promise<HarnessConfig>;
|
|
|
177
177
|
* first.
|
|
178
178
|
*/
|
|
179
179
|
export declare function loadProjectConfig(cwd?: string): Promise<HarnessConfig | undefined>;
|
|
180
|
+
/**
|
|
181
|
+
* The user's own config file, unmerged — the counterpart of loadProjectConfig,
|
|
182
|
+
* for a control that may only change what this file holds.
|
|
183
|
+
*/
|
|
184
|
+
export declare function loadUserConfig(): Promise<HarnessConfig>;
|
|
180
185
|
/**
|
|
181
186
|
* Change the user's own config file.
|
|
182
187
|
*
|
package/dist/config.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { userPath } from "./paths.js";
|
|
2
|
-
import { mkdir, readFile,
|
|
2
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { renameWithRetry } from "./util/fs.js";
|
|
4
5
|
import { ConfigError } from "./core/errors.js";
|
|
5
6
|
import { parseJson } from "./util/json.js";
|
|
6
7
|
import { readMcpFile, readPluginFile } from "./config-files.js";
|
|
@@ -91,6 +92,13 @@ function projectSafe(project) {
|
|
|
91
92
|
const { url: _url, token: _token, team: _team, ...allowed } = rest.sync;
|
|
92
93
|
return { ...rest, sync: allowed };
|
|
93
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* The user's own config file, unmerged — the counterpart of loadProjectConfig,
|
|
97
|
+
* for a control that may only change what this file holds.
|
|
98
|
+
*/
|
|
99
|
+
export async function loadUserConfig() {
|
|
100
|
+
return (await readConfigFile(userPath("config.json"))) ?? {};
|
|
101
|
+
}
|
|
94
102
|
/**
|
|
95
103
|
* Change the user's own config file.
|
|
96
104
|
*
|
|
@@ -113,7 +121,7 @@ export async function updateUserConfig(change) {
|
|
|
113
121
|
// Temp plus rename, so an interrupted write cannot leave a config file that
|
|
114
122
|
// fails to parse — which would read as "every setting reverted".
|
|
115
123
|
await writeFile(temp, `${JSON.stringify(next, null, 2)}\n`, "utf8");
|
|
116
|
-
await
|
|
124
|
+
await renameWithRetry(temp, file);
|
|
117
125
|
return next;
|
|
118
126
|
}
|
|
119
127
|
export function mergeConfig(base, override) {
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/harness.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ import type { HarnessConfig } from "./config.ts";
|
|
|
19
19
|
import type { PluginDefinition } from "./plugins.ts";
|
|
20
20
|
import { McpManager } from "./mcp/manager.ts";
|
|
21
21
|
import { Scheduler } from "./schedule/scheduler.ts";
|
|
22
|
+
import type { ScheduleDefinition } from "./schedule/scheduler.ts";
|
|
22
23
|
import type { McpServerStatus } from "./mcp/manager.ts";
|
|
23
24
|
import { ProviderRegistry } from "./providers/registry.ts";
|
|
24
25
|
import type { VerifyResult } from "./providers/registry.ts";
|
|
@@ -74,6 +75,8 @@ export interface HarnessOptions {
|
|
|
74
75
|
* Construct it with `Harness.create()` rather than `new`, because MCP
|
|
75
76
|
* connection and config loading are async.
|
|
76
77
|
*/
|
|
78
|
+
/** How old the saved model list may get before it is fetched again. */
|
|
79
|
+
export declare const MODEL_LIST_MAX_AGE_MS: number;
|
|
77
80
|
export declare class Harness {
|
|
78
81
|
readonly cwd: string;
|
|
79
82
|
readonly config: HarnessConfig;
|
|
@@ -204,6 +207,45 @@ export declare class Harness {
|
|
|
204
207
|
reason?: string;
|
|
205
208
|
url?: string;
|
|
206
209
|
};
|
|
210
|
+
/**
|
|
211
|
+
* Add a routine, and remember it.
|
|
212
|
+
*
|
|
213
|
+
* Written to the user's config, never the project's: a routine made from a
|
|
214
|
+
* button is this machine's, and one written into the repository would fire
|
|
215
|
+
* on every clone. It runs in the directory it was made in, because the user
|
|
216
|
+
* config is read by every project and "the harness cwd" would otherwise be
|
|
217
|
+
* whichever project happened to load it.
|
|
218
|
+
*/
|
|
219
|
+
addSchedule(input: {
|
|
220
|
+
name: string;
|
|
221
|
+
cron: string;
|
|
222
|
+
prompt: string;
|
|
223
|
+
cwd?: string;
|
|
224
|
+
}): Promise<ScheduleDefinition>;
|
|
225
|
+
/**
|
|
226
|
+
* Bring the scheduler in line with the config files as they are now.
|
|
227
|
+
*
|
|
228
|
+
* The user config is shared by every open project, and a routine added from
|
|
229
|
+
* one of them — by the agent, in its own session — is written to the file
|
|
230
|
+
* but known only to that project's scheduler. Reading the files again is
|
|
231
|
+
* what lets the others see it without a restart. The project's own list
|
|
232
|
+
* wins a name both define, as it does at load.
|
|
233
|
+
*/
|
|
234
|
+
syncUserSchedules(): Promise<void>;
|
|
235
|
+
/**
|
|
236
|
+
* Pause a routine or resume it, and remember which.
|
|
237
|
+
*
|
|
238
|
+
* Only the user's own: a project's routine is the repository's, and pausing
|
|
239
|
+
* it here would be undone by the next launch reading the file again.
|
|
240
|
+
*/
|
|
241
|
+
setScheduleEnabled(name: string, enabled: boolean): Promise<void>;
|
|
242
|
+
/**
|
|
243
|
+
* Remove a routine this machine's config holds.
|
|
244
|
+
*
|
|
245
|
+
* One from the project's config is refused rather than hidden: it would be
|
|
246
|
+
* back on the next launch, and the file it lives in is the repository's.
|
|
247
|
+
*/
|
|
248
|
+
removeSchedule(name: string): Promise<void>;
|
|
207
249
|
/**
|
|
208
250
|
* Turn sync on or off now, and remember the choice.
|
|
209
251
|
*
|
|
@@ -235,6 +277,17 @@ export declare class Harness {
|
|
|
235
277
|
* the user catalog so the next run starts with a current list.
|
|
236
278
|
*/
|
|
237
279
|
refreshModels(providerId?: string): Promise<ModelSpec[]>;
|
|
280
|
+
/**
|
|
281
|
+
* Re-list every provider's models when the list on disk is older than
|
|
282
|
+
* `maxAgeMs` (three days by default), and do nothing otherwise.
|
|
283
|
+
*
|
|
284
|
+
* A listing is otherwise only fetched when somebody signs in or presses
|
|
285
|
+
* refresh, so a model the vendor withdrew stays in the picker until they
|
|
286
|
+
* happen to — and answers 404 when picked. Nothing to refresh from (no
|
|
287
|
+
* listing ever made) counts as stale. Resolves to undefined when the list
|
|
288
|
+
* was fresh enough to leave alone.
|
|
289
|
+
*/
|
|
290
|
+
refreshStaleModels(maxAgeMs?: number): Promise<ModelSpec[] | undefined>;
|
|
238
291
|
/**
|
|
239
292
|
* Check a provider's credential by asking it what it serves, and keep the
|
|
240
293
|
* answer.
|
|
@@ -246,7 +299,14 @@ export declare class Harness {
|
|
|
246
299
|
* thing to remember to ask for.
|
|
247
300
|
*/
|
|
248
301
|
verifyProvider(providerId: string): Promise<VerifyResult>;
|
|
249
|
-
/**
|
|
302
|
+
/**
|
|
303
|
+
* Store discovered models in the user catalog on disk.
|
|
304
|
+
*
|
|
305
|
+
* Per provider, a listing replaces the one before it rather than adding to
|
|
306
|
+
* it: merging only ever grew the file, so a model the vendor withdrew stayed
|
|
307
|
+
* in the picker for good. `discovered` records which providers have a live
|
|
308
|
+
* listing, so the pi-ai snapshot stops filling in models for them.
|
|
309
|
+
*/
|
|
250
310
|
private saveDiscovered;
|
|
251
311
|
/**
|
|
252
312
|
* Re-scan the skill directories.
|
|
@@ -265,6 +325,7 @@ export declare class Harness {
|
|
|
265
325
|
model?: string;
|
|
266
326
|
title?: string;
|
|
267
327
|
effort?: EffortChoice;
|
|
328
|
+
routine?: string;
|
|
268
329
|
}): Session;
|
|
269
330
|
/**
|
|
270
331
|
* Give a session the machinery that outlives it: where remembered approvals
|
package/dist/harness.js
CHANGED
|
@@ -11,7 +11,7 @@ import { SettingsStore } from "./agent/settings.js";
|
|
|
11
11
|
import { createPolicy } from "./agent/workspace.js";
|
|
12
12
|
import { PluginExtensions } from "./runtime-plugins/extensions.js";
|
|
13
13
|
import { createMemoryPlugin, MemoryService } from "./runtime-plugins/builtin/memory.js";
|
|
14
|
-
import {
|
|
14
|
+
import { projectMemoryDirectory, resolveMemoryDirectories } from "./runtime-plugins/builtin/memory-migrate.js";
|
|
15
15
|
import { resolveMemoryPolicy } from "./agent/memory-limits.js";
|
|
16
16
|
import { siteUrl } from "./auth/providers/account.js";
|
|
17
17
|
import { loadConfig, loadProjectConfig, loadProjectInstructions, mergeConfig } from "./config.js";
|
|
@@ -24,14 +24,16 @@ import { Scheduler } from "./schedule/scheduler.js";
|
|
|
24
24
|
import { SyncClient } from "./sync/client.js";
|
|
25
25
|
import { SessionMirror } from "./sync/mirror.js";
|
|
26
26
|
import { isExcluded, resolveSync, resolveSyncUrl } from "./sync/settings.js";
|
|
27
|
-
import { projectId } from "./storage/project.js";
|
|
28
|
-
import { updateUserConfig } from "./config.js";
|
|
27
|
+
import { ensureProjectManifest, projectId } from "./storage/project.js";
|
|
28
|
+
import { loadUserConfig, updateUserConfig } from "./config.js";
|
|
29
|
+
import { parseCron } from "./schedule/cron.js";
|
|
30
|
+
import { createRoutineTool } from "./tools/builtin/routine.js";
|
|
29
31
|
import { ProviderRegistry } from "./providers/registry.js";
|
|
30
32
|
import { userMessage } from "./core/types.js";
|
|
31
33
|
import { loadCatalog, userCatalogPath } from "./providers/catalog.js";
|
|
32
34
|
import { builtinTools } from "./tools/builtin/index.js";
|
|
33
35
|
import { ToolRegistry } from "./tools/registry.js";
|
|
34
|
-
import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
36
|
+
import { appendFile, mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
35
37
|
import path from "node:path";
|
|
36
38
|
import { createLogger } from "./util/logger.js";
|
|
37
39
|
import { PluginHost } from "./runtime-plugins/host.js";
|
|
@@ -44,6 +46,8 @@ import { CloudConnectorService, createCloudConnectorPlugin } from "./runtime-plu
|
|
|
44
46
|
* Construct it with `Harness.create()` rather than `new`, because MCP
|
|
45
47
|
* connection and config loading are async.
|
|
46
48
|
*/
|
|
49
|
+
/** How old the saved model list may get before it is fetched again. */
|
|
50
|
+
export const MODEL_LIST_MAX_AGE_MS = 3 * 24 * 60 * 60 * 1000;
|
|
47
51
|
export class Harness {
|
|
48
52
|
cwd;
|
|
49
53
|
config;
|
|
@@ -152,6 +156,11 @@ export class Harness {
|
|
|
152
156
|
this.mcp = new McpManager(this.logger, this.auth.store, (id) => this.auth.secret(id));
|
|
153
157
|
this.store = new SessionStore(config.sessionDir);
|
|
154
158
|
this.scheduler = new Scheduler(this, config.schedules ?? []);
|
|
159
|
+
this.tools.register(createRoutineTool({
|
|
160
|
+
list: () => this.scheduler.status(),
|
|
161
|
+
add: (input) => this.addSchedule(input),
|
|
162
|
+
remove: (name) => this.removeSchedule(name),
|
|
163
|
+
}));
|
|
155
164
|
this.ephemeral = opts.ephemeral === true;
|
|
156
165
|
this.runtimeAudit = new RuntimeAuditBus(this.logger);
|
|
157
166
|
this.cloudConnectors = opts.cloudConnectorService ?? new CloudConnectorService({ token: async (origin) => {
|
|
@@ -170,7 +179,11 @@ export class Harness {
|
|
|
170
179
|
});
|
|
171
180
|
}
|
|
172
181
|
static async create(opts = {}) {
|
|
173
|
-
const cwd = opts.cwd ?? process.cwd();
|
|
182
|
+
const cwd = path.resolve(opts.cwd ?? process.cwd());
|
|
183
|
+
const stableProjectId = opts.ephemeral
|
|
184
|
+
? await projectId(cwd)
|
|
185
|
+
: (await ensureProjectManifest(cwd)).id;
|
|
186
|
+
opts = { ...opts, cwd };
|
|
174
187
|
const baseConfig = opts.config ?? (await loadConfig(cwd));
|
|
175
188
|
const plugins = await discoverPlugins(cwd, baseConfig.plugins);
|
|
176
189
|
// Explicit user/project config is applied after plugins, so it can always
|
|
@@ -220,14 +233,14 @@ export class Harness {
|
|
|
220
233
|
}
|
|
221
234
|
const platform = (opts.cloudConnectors ?? !opts.ephemeral)
|
|
222
235
|
? [{ plugin: createCloudConnectorPlugin(harness.cloudConnectors), required: false, builtin: true }] : [];
|
|
223
|
-
//
|
|
224
|
-
//
|
|
236
|
+
// The Markdown source belongs to the project; machine-local indexes and
|
|
237
|
+
// sync baselines remain in the user directory.
|
|
225
238
|
const memoryConfigured = config.memory?.dir ?? config.memoryDir;
|
|
226
239
|
const memoryEnabled = config.runtimePlugins?.find((plugin) => plugin.id === "memory")?.enabled !== false;
|
|
227
240
|
const memoryDirs = memoryEnabled
|
|
228
241
|
? await resolveMemoryDirectories({ cwd, ...(memoryConfigured ? { configured: memoryConfigured } : {}), logger: harness.logger })
|
|
229
|
-
: { project: memoryConfigured ? path.resolve(cwd, memoryConfigured) :
|
|
230
|
-
const memory = createMemoryPlugin({ cwd, directory: memoryDirs.project,
|
|
242
|
+
: { project: memoryConfigured ? path.resolve(cwd, memoryConfigured) : projectMemoryDirectory(cwd) };
|
|
243
|
+
const memory = createMemoryPlugin({ cwd, projectId: stableProjectId, directory: memoryDirs.project,
|
|
231
244
|
...(memoryDirs.user ? { userDirectory: memoryDirs.user } : {}),
|
|
232
245
|
policy: resolveMemoryPolicy(config.memory),
|
|
233
246
|
identity: async () => {
|
|
@@ -454,6 +467,107 @@ export class Harness {
|
|
|
454
467
|
}
|
|
455
468
|
return { on: false, reason: this.syncState.reason };
|
|
456
469
|
}
|
|
470
|
+
/**
|
|
471
|
+
* Add a routine, and remember it.
|
|
472
|
+
*
|
|
473
|
+
* Written to the user's config, never the project's: a routine made from a
|
|
474
|
+
* button is this machine's, and one written into the repository would fire
|
|
475
|
+
* on every clone. It runs in the directory it was made in, because the user
|
|
476
|
+
* config is read by every project and "the harness cwd" would otherwise be
|
|
477
|
+
* whichever project happened to load it.
|
|
478
|
+
*/
|
|
479
|
+
async addSchedule(input) {
|
|
480
|
+
const name = input.name.trim();
|
|
481
|
+
const cron = input.cron.trim();
|
|
482
|
+
const prompt = input.prompt.trim();
|
|
483
|
+
if (!name)
|
|
484
|
+
throw new ConfigError("a routine needs a name");
|
|
485
|
+
if (!prompt)
|
|
486
|
+
throw new ConfigError("a routine needs a prompt");
|
|
487
|
+
// Before anything is written: a bad expression saved to the file would
|
|
488
|
+
// stop every later launch from loading its config.
|
|
489
|
+
parseCron(cron);
|
|
490
|
+
if (this.scheduler.list().some((existing) => existing.name === name)) {
|
|
491
|
+
throw new ConfigError(`a routine named "${name}" already exists`);
|
|
492
|
+
}
|
|
493
|
+
const cwd = path.resolve(this.cwd, input.cwd ?? this.cwd);
|
|
494
|
+
// A routine for a directory that is not there fails every morning, where
|
|
495
|
+
// nobody sees it; better to say so now, to the person asking.
|
|
496
|
+
const where = await stat(cwd).catch(() => undefined);
|
|
497
|
+
if (!where?.isDirectory())
|
|
498
|
+
throw new ConfigError(`"${cwd}" is not a directory`);
|
|
499
|
+
const def = { name, cron, prompt, cwd, createdAt: Date.now() };
|
|
500
|
+
await updateUserConfig((current) => ({ ...current, schedules: [...(current.schedules ?? []), def] }));
|
|
501
|
+
this.scheduler.add(def);
|
|
502
|
+
return def;
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Bring the scheduler in line with the config files as they are now.
|
|
506
|
+
*
|
|
507
|
+
* The user config is shared by every open project, and a routine added from
|
|
508
|
+
* one of them — by the agent, in its own session — is written to the file
|
|
509
|
+
* but known only to that project's scheduler. Reading the files again is
|
|
510
|
+
* what lets the others see it without a restart. The project's own list
|
|
511
|
+
* wins a name both define, as it does at load.
|
|
512
|
+
*/
|
|
513
|
+
async syncUserSchedules() {
|
|
514
|
+
const project = (await loadProjectConfig(this.cwd))?.schedules ?? [];
|
|
515
|
+
const user = (await loadUserConfig()).schedules ?? [];
|
|
516
|
+
const wanted = new Map();
|
|
517
|
+
for (const def of [...user, ...project])
|
|
518
|
+
wanted.set(def.name, def);
|
|
519
|
+
for (const existing of this.scheduler.list()) {
|
|
520
|
+
if (!wanted.has(existing.name))
|
|
521
|
+
this.scheduler.remove(existing.name);
|
|
522
|
+
}
|
|
523
|
+
const known = new Set(this.scheduler.list().map((one) => one.name));
|
|
524
|
+
for (const def of wanted.values()) {
|
|
525
|
+
if (known.has(def.name))
|
|
526
|
+
continue;
|
|
527
|
+
try {
|
|
528
|
+
this.scheduler.add(def);
|
|
529
|
+
}
|
|
530
|
+
catch (err) {
|
|
531
|
+
this.logger.warn("skipping routine", { routine: def.name, error: String(err) });
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Pause a routine or resume it, and remember which.
|
|
537
|
+
*
|
|
538
|
+
* Only the user's own: a project's routine is the repository's, and pausing
|
|
539
|
+
* it here would be undone by the next launch reading the file again.
|
|
540
|
+
*/
|
|
541
|
+
async setScheduleEnabled(name, enabled) {
|
|
542
|
+
const mine = (await loadUserConfig()).schedules ?? [];
|
|
543
|
+
if (!mine.some((existing) => existing.name === name)) {
|
|
544
|
+
throw new ConfigError(`"${name}" is set in the project's oharness.config.json; change it there`);
|
|
545
|
+
}
|
|
546
|
+
await updateUserConfig((current) => ({
|
|
547
|
+
...current,
|
|
548
|
+
schedules: (current.schedules ?? []).map((existing) => existing.name === name ? { ...existing, enabled } : existing),
|
|
549
|
+
}));
|
|
550
|
+
const held = this.scheduler.list().find((existing) => existing.name === name);
|
|
551
|
+
if (held)
|
|
552
|
+
this.scheduler.add({ ...held, enabled });
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Remove a routine this machine's config holds.
|
|
556
|
+
*
|
|
557
|
+
* One from the project's config is refused rather than hidden: it would be
|
|
558
|
+
* back on the next launch, and the file it lives in is the repository's.
|
|
559
|
+
*/
|
|
560
|
+
async removeSchedule(name) {
|
|
561
|
+
const mine = (await loadUserConfig()).schedules ?? [];
|
|
562
|
+
if (!mine.some((existing) => existing.name === name)) {
|
|
563
|
+
throw new ConfigError(`"${name}" is set in the project's oharness.config.json; remove it there`);
|
|
564
|
+
}
|
|
565
|
+
await updateUserConfig((current) => ({
|
|
566
|
+
...current,
|
|
567
|
+
schedules: (current.schedules ?? []).filter((existing) => existing.name !== name),
|
|
568
|
+
}));
|
|
569
|
+
this.scheduler.remove(name);
|
|
570
|
+
}
|
|
457
571
|
/**
|
|
458
572
|
* Turn sync on or off now, and remember the choice.
|
|
459
573
|
*
|
|
@@ -574,6 +688,29 @@ export class Harness {
|
|
|
574
688
|
}
|
|
575
689
|
return discovered;
|
|
576
690
|
}
|
|
691
|
+
/**
|
|
692
|
+
* Re-list every provider's models when the list on disk is older than
|
|
693
|
+
* `maxAgeMs` (three days by default), and do nothing otherwise.
|
|
694
|
+
*
|
|
695
|
+
* A listing is otherwise only fetched when somebody signs in or presses
|
|
696
|
+
* refresh, so a model the vendor withdrew stays in the picker until they
|
|
697
|
+
* happen to — and answers 404 when picked. Nothing to refresh from (no
|
|
698
|
+
* listing ever made) counts as stale. Resolves to undefined when the list
|
|
699
|
+
* was fresh enough to leave alone.
|
|
700
|
+
*/
|
|
701
|
+
async refreshStaleModels(maxAgeMs = MODEL_LIST_MAX_AGE_MS) {
|
|
702
|
+
let at = NaN;
|
|
703
|
+
try {
|
|
704
|
+
const raw = JSON.parse(await readFile(userCatalogPath(), "utf8"));
|
|
705
|
+
at = Date.parse(String(raw["discoveredAt"] ?? ""));
|
|
706
|
+
}
|
|
707
|
+
catch {
|
|
708
|
+
// No file or an unreadable one: never listed, so due.
|
|
709
|
+
}
|
|
710
|
+
if (Number.isFinite(at) && Date.now() - at < maxAgeMs)
|
|
711
|
+
return undefined;
|
|
712
|
+
return this.refreshModels();
|
|
713
|
+
}
|
|
577
714
|
/**
|
|
578
715
|
* Check a provider's credential by asking it what it serves, and keep the
|
|
579
716
|
* answer.
|
|
@@ -593,7 +730,14 @@ export class Harness {
|
|
|
593
730
|
}
|
|
594
731
|
return result;
|
|
595
732
|
}
|
|
596
|
-
/**
|
|
733
|
+
/**
|
|
734
|
+
* Store discovered models in the user catalog on disk.
|
|
735
|
+
*
|
|
736
|
+
* Per provider, a listing replaces the one before it rather than adding to
|
|
737
|
+
* it: merging only ever grew the file, so a model the vendor withdrew stayed
|
|
738
|
+
* in the picker for good. `discovered` records which providers have a live
|
|
739
|
+
* listing, so the pi-ai snapshot stops filling in models for them.
|
|
740
|
+
*/
|
|
597
741
|
async saveDiscovered(models) {
|
|
598
742
|
const file = userCatalogPath();
|
|
599
743
|
let existing = {};
|
|
@@ -606,10 +750,28 @@ export class Harness {
|
|
|
606
750
|
const byId = new Map((Array.isArray(existing["models"]) ? existing["models"] : [])
|
|
607
751
|
.filter((m) => !!m && typeof m === "object")
|
|
608
752
|
.map((m) => [String(m["id"]), m]));
|
|
753
|
+
const listed = new Set(models.map((model) => model.provider));
|
|
754
|
+
const fresh = new Set(models.map((model) => model.id));
|
|
755
|
+
for (const [id, model] of byId) {
|
|
756
|
+
const { provider, model: wire } = model;
|
|
757
|
+
// Same rule as the registry: only what a listing wrote is replaced by one.
|
|
758
|
+
if (typeof provider !== "string" || !listed.has(provider) || fresh.has(id))
|
|
759
|
+
continue;
|
|
760
|
+
if (id === `${provider}/${String(wire)}`)
|
|
761
|
+
byId.delete(id);
|
|
762
|
+
}
|
|
609
763
|
for (const model of models)
|
|
610
764
|
byId.set(model.id, model);
|
|
765
|
+
const at = new Date().toISOString();
|
|
766
|
+
const previous = existing["discovered"];
|
|
767
|
+
const discovered = {
|
|
768
|
+
...(previous && typeof previous === "object" && !Array.isArray(previous)
|
|
769
|
+
? previous : {}),
|
|
770
|
+
};
|
|
771
|
+
for (const provider of listed)
|
|
772
|
+
discovered[provider] = at;
|
|
611
773
|
await mkdir(path.dirname(file), { recursive: true });
|
|
612
|
-
await writeFile(file, JSON.stringify({ ...existing, discoveredAt:
|
|
774
|
+
await writeFile(file, JSON.stringify({ ...existing, discoveredAt: at, discovered, models: [...byId.values()] }, null, 2), "utf8");
|
|
613
775
|
}
|
|
614
776
|
/**
|
|
615
777
|
* Re-scan the skill directories.
|
|
@@ -645,6 +807,7 @@ export class Harness {
|
|
|
645
807
|
store: this.options.ephemeral ? false : this.store,
|
|
646
808
|
title: overrides.title,
|
|
647
809
|
effort: overrides.effort,
|
|
810
|
+
routine: overrides.routine,
|
|
648
811
|
}));
|
|
649
812
|
}
|
|
650
813
|
/**
|
|
@@ -809,7 +972,6 @@ export class Harness {
|
|
|
809
972
|
async shutdown() {
|
|
810
973
|
this.lifecycle.abort();
|
|
811
974
|
this.cloudConnectors.close();
|
|
812
|
-
this.scheduler.stop();
|
|
813
975
|
// Stopped before MCP, because it is the only thing here holding a socket
|
|
814
976
|
// open on purpose — a long poll would otherwise keep the process alive for
|
|
815
977
|
// up to thirty seconds after everything else had shut down.
|