@mono-agent/agent-app 0.3.0 → 0.4.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/README.md +24 -10
- package/dist/adapter-send-tools-main.d.ts +3 -0
- package/dist/adapter-send-tools-main.d.ts.map +1 -0
- package/dist/adapter-send-tools-main.js +20 -0
- package/dist/adapter-send-tools-main.js.map +1 -0
- package/dist/adapter-send-tools.d.ts +125 -0
- package/dist/adapter-send-tools.d.ts.map +1 -0
- package/dist/adapter-send-tools.js +629 -0
- package/dist/adapter-send-tools.js.map +1 -0
- package/dist/app-config.d.ts +86 -26
- package/dist/app-config.d.ts.map +1 -1
- package/dist/app-config.js +284 -90
- package/dist/app-config.js.map +1 -1
- package/dist/app.d.ts +51 -20
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +889 -119
- package/dist/app.js.map +1 -1
- package/dist/artifact-retention.d.ts +32 -0
- package/dist/artifact-retention.d.ts.map +1 -0
- package/dist/artifact-retention.js +111 -0
- package/dist/artifact-retention.js.map +1 -0
- package/dist/audit-runs.d.ts +12 -0
- package/dist/audit-runs.d.ts.map +1 -0
- package/dist/audit-runs.js +68 -0
- package/dist/audit-runs.js.map +1 -0
- package/dist/backfill.d.ts +75 -0
- package/dist/backfill.d.ts.map +1 -0
- package/dist/backfill.js +350 -0
- package/dist/backfill.js.map +1 -0
- package/dist/background.d.ts +8 -5
- package/dist/background.d.ts.map +1 -1
- package/dist/background.js +279 -53
- package/dist/background.js.map +1 -1
- package/dist/broadcast-recorder.d.ts +27 -0
- package/dist/broadcast-recorder.d.ts.map +1 -0
- package/dist/broadcast-recorder.js +82 -0
- package/dist/broadcast-recorder.js.map +1 -0
- package/dist/channel-config-view.d.ts +28 -0
- package/dist/channel-config-view.d.ts.map +1 -0
- package/dist/channel-config-view.js +79 -0
- package/dist/channel-config-view.js.map +1 -0
- package/dist/channel-gate.d.ts +22 -0
- package/dist/channel-gate.d.ts.map +1 -0
- package/dist/channel-gate.js +35 -0
- package/dist/channel-gate.js.map +1 -0
- package/dist/channel-plugins.d.ts +39 -0
- package/dist/channel-plugins.d.ts.map +1 -0
- package/dist/channel-plugins.js +346 -0
- package/dist/channel-plugins.js.map +1 -0
- package/dist/channels.d.ts +62 -66
- package/dist/channels.d.ts.map +1 -1
- package/dist/channels.js +850 -120
- package/dist/channels.js.map +1 -1
- package/dist/cli.d.ts +103 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +984 -112
- package/dist/cli.js.map +1 -1
- package/dist/config-reference.d.ts +24 -0
- package/dist/config-reference.d.ts.map +1 -0
- package/dist/config-reference.js +580 -0
- package/dist/config-reference.js.map +1 -0
- package/dist/configured-agent.d.ts +104 -0
- package/dist/configured-agent.d.ts.map +1 -0
- package/dist/configured-agent.js +578 -0
- package/dist/configured-agent.js.map +1 -0
- package/dist/consumer-contract.d.ts +36 -0
- package/dist/consumer-contract.d.ts.map +1 -0
- package/dist/consumer-contract.js +290 -0
- package/dist/consumer-contract.js.map +1 -0
- package/dist/doctor.d.ts +17 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +392 -95
- package/dist/doctor.js.map +1 -1
- package/dist/index.d.ts +14 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +23 -7
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +91 -26
- package/dist/init.js.map +1 -1
- package/dist/install-skill.d.ts +1 -1
- package/dist/install-skill.js +2 -2
- package/dist/install-skill.js.map +1 -1
- package/dist/interaction-bridge.d.ts +72 -0
- package/dist/interaction-bridge.d.ts.map +1 -0
- package/dist/interaction-bridge.js +354 -0
- package/dist/interaction-bridge.js.map +1 -0
- package/dist/launchd.d.ts +0 -2
- package/dist/launchd.d.ts.map +1 -1
- package/dist/launchd.js +0 -2
- package/dist/launchd.js.map +1 -1
- package/dist/memory-command.d.ts +10 -0
- package/dist/memory-command.d.ts.map +1 -0
- package/dist/memory-command.js +649 -0
- package/dist/memory-command.js.map +1 -0
- package/dist/memory-recall-main.d.ts +3 -0
- package/dist/memory-recall-main.d.ts.map +1 -0
- package/dist/memory-recall-main.js +30 -0
- package/dist/memory-recall-main.js.map +1 -0
- package/dist/memory-recall.d.ts +147 -0
- package/dist/memory-recall.d.ts.map +1 -0
- package/dist/memory-recall.js +345 -0
- package/dist/memory-recall.js.map +1 -0
- package/dist/memory-rituals.d.ts +8 -11
- package/dist/memory-rituals.d.ts.map +1 -1
- package/dist/memory-rituals.js +26 -25
- package/dist/memory-rituals.js.map +1 -1
- package/dist/metrics.d.ts +13 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +105 -0
- package/dist/metrics.js.map +1 -0
- package/dist/notify-destinations.d.ts +23 -0
- package/dist/notify-destinations.d.ts.map +1 -0
- package/dist/notify-destinations.js +79 -0
- package/dist/notify-destinations.js.map +1 -0
- package/dist/posted-message-index.d.ts +61 -0
- package/dist/posted-message-index.d.ts.map +1 -0
- package/dist/posted-message-index.js +178 -0
- package/dist/posted-message-index.js.map +1 -0
- package/dist/proactive-notify.d.ts +32 -0
- package/dist/proactive-notify.d.ts.map +1 -0
- package/dist/proactive-notify.js +62 -0
- package/dist/proactive-notify.js.map +1 -0
- package/dist/recipes/base.d.ts +15 -0
- package/dist/recipes/base.d.ts.map +1 -0
- package/dist/recipes/base.js +51 -0
- package/dist/recipes/base.js.map +1 -0
- package/dist/recipes/catalog.d.ts +4 -0
- package/dist/recipes/catalog.d.ts.map +1 -0
- package/dist/recipes/catalog.js +509 -0
- package/dist/recipes/catalog.js.map +1 -0
- package/dist/recipes/index.d.ts +11 -0
- package/dist/recipes/index.d.ts.map +1 -0
- package/dist/recipes/index.js +14 -0
- package/dist/recipes/index.js.map +1 -0
- package/dist/recipes/types.d.ts +70 -0
- package/dist/recipes/types.d.ts.map +1 -0
- package/dist/recipes/types.js +15 -0
- package/dist/recipes/types.js.map +1 -0
- package/dist/request-model-override.d.ts +67 -0
- package/dist/request-model-override.d.ts.map +1 -0
- package/dist/request-model-override.js +96 -0
- package/dist/request-model-override.js.map +1 -0
- package/dist/runs-health.d.ts +22 -0
- package/dist/runs-health.d.ts.map +1 -0
- package/dist/runs-health.js +144 -0
- package/dist/runs-health.js.map +1 -0
- package/dist/seen-conversations.d.ts +22 -0
- package/dist/seen-conversations.d.ts.map +1 -0
- package/dist/seen-conversations.js +120 -0
- package/dist/seen-conversations.js.map +1 -0
- package/dist/sessions.d.ts +21 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +45 -0
- package/dist/sessions.js.map +1 -0
- package/dist/setup.d.ts +29 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +97 -0
- package/dist/setup.js.map +1 -0
- package/dist/trigger-overrides.d.ts +17 -0
- package/dist/trigger-overrides.d.ts.map +1 -0
- package/dist/trigger-overrides.js +30 -0
- package/dist/trigger-overrides.js.map +1 -0
- package/dist/tui-command.d.ts +56 -0
- package/dist/tui-command.d.ts.map +1 -0
- package/dist/tui-command.js +160 -0
- package/dist/tui-command.js.map +1 -0
- package/dist/ui.d.ts +54 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +157 -0
- package/dist/ui.js.map +1 -0
- package/dist/web-command.d.ts +39 -0
- package/dist/web-command.d.ts.map +1 -0
- package/dist/web-command.js +151 -0
- package/dist/web-command.js.map +1 -0
- package/package.json +22 -17
- package/schema/mono-agent.config.schema.json +1686 -0
- package/skills/mono-agent-composer/SKILL.md +38 -12
- package/skills/mono-agent-composer/agents/openai.yaml +4 -0
- package/skills/mono-agent-composer/references/config-blueprint.md +84 -31
- package/skills/mono-agent-composer/references/discovery-questions.md +49 -36
- package/skills/mono-agent-composer/references/feature-coverage.md +26 -19
- package/skills/mono-agent-composer/references/package-map.md +20 -22
- package/skills/mono-agent-composer/references/playbooks.md +209 -0
- package/skills/mono-agent-composer/references/validation.md +14 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/recipes/types.ts"],"names":[],"mappings":"AA0EA,wEAAwE;AACxE,MAAM,UAAU,mBAAmB,CACjC,MAAmB,EACnB,YAA+B,EAAE;IAEjC,MAAM,MAAM,GAAuC,EAAE,CAAC;IACtD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC;IAC1D,CAAC;IACD,iFAAiF;IACjF,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { LocalProviderDefinition, LocalProviderRuntimeOptions, RuntimeModelReference } from "@mono-agent/runtime-adapter";
|
|
2
|
+
/**
|
|
3
|
+
* Per-request runtime-options extension that applies a per-turn model/effort
|
|
4
|
+
* override carried on webhook (`metadata.webhook`), cron (`metadata.cron`), or
|
|
5
|
+
* interactive TUI (`metadata.tui`) request metadata — an operator can pick a
|
|
6
|
+
* per-session model/effort from the TUI just as a trigger can pin one. The
|
|
7
|
+
* adapters carry the override as raw strings; this is the
|
|
8
|
+
* first place with both the model parser and the effort enum, so validation
|
|
9
|
+
* lives here. An invalid value is WARNED and IGNORED (the turn falls back to the
|
|
10
|
+
* harness default) rather than failing — a bad dynamic webhook `model` must not
|
|
11
|
+
* 500 the request.
|
|
12
|
+
*
|
|
13
|
+
* Execution mode is NOT set here: the harness derives it from the effective model
|
|
14
|
+
* plus the host's configured executionMode (keeping a compatible host mode, e.g.
|
|
15
|
+
* claude in `cli`, and only falling back to the model default for an incompatible
|
|
16
|
+
* one, e.g. a `codex:*` override under an `sdk` host).
|
|
17
|
+
*
|
|
18
|
+
* A model override OWNS the local-provider endpoint block. Whenever a VALID model
|
|
19
|
+
* override is applied, this extension SETS the four endpoint fields
|
|
20
|
+
* (`customProvider`/`customModel`/`modelCapabilities`/`isPrivateProvider`):
|
|
21
|
+
* - LOCAL override (`sdk === "pi"` with a configured provider id): recompute the
|
|
22
|
+
* block for the OVERRIDE model via `runtimeOptionsForLocalProvider`.
|
|
23
|
+
* - CLOUD/registry override, an UNCONFIGURED local provider id, or a
|
|
24
|
+
* misconfigured provider: set the four fields to `null` to explicitly CLEAR
|
|
25
|
+
* the host default's block.
|
|
26
|
+
* This is required because the host default block is computed ONCE from
|
|
27
|
+
* `config.runtime.model` at harness creation, and the pi runtime routes on
|
|
28
|
+
* `customProvider` PRESENCE alone — so a cloud override under an all-LOCAL default
|
|
29
|
+
* would otherwise inherit the default's local endpoint and send the cloud model to
|
|
30
|
+
* localhost (same mis-route for an unconfigured local provider id). The harness
|
|
31
|
+
* `mergeRuntimeOptions` applies the override AFTER the host default
|
|
32
|
+
* (last-writer-wins) and reads `null` on these keys as "delete", so a set block
|
|
33
|
+
* REPLACES the default and a null CLEARS it. An effort-only / no-model turn leaves
|
|
34
|
+
* the block untouched (the default's block is correct for the default model).
|
|
35
|
+
*/
|
|
36
|
+
export interface RequestModelOverrideLogger {
|
|
37
|
+
warn?(message: string, metadata?: Record<string, unknown>): void;
|
|
38
|
+
}
|
|
39
|
+
export interface RequestModelOverrideOptions {
|
|
40
|
+
readonly logger?: RequestModelOverrideLogger;
|
|
41
|
+
/**
|
|
42
|
+
* Configured local providers (`config.providers?.local`). When an override
|
|
43
|
+
* names a model one of these serves, the extension recomputes the provider
|
|
44
|
+
* endpoint block so the override reaches the right local endpoint instead of
|
|
45
|
+
* inheriting the host default's block.
|
|
46
|
+
*/
|
|
47
|
+
readonly localProviders?: readonly LocalProviderDefinition[];
|
|
48
|
+
}
|
|
49
|
+
interface RequestModelOverrideInput {
|
|
50
|
+
readonly request: {
|
|
51
|
+
readonly metadata?: Record<string, unknown>;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
interface RequestModelOverrideResult {
|
|
55
|
+
readonly runtimeOptions: {
|
|
56
|
+
model?: RuntimeModelReference;
|
|
57
|
+
effort?: string;
|
|
58
|
+
customProvider?: LocalProviderRuntimeOptions["customProvider"] | null;
|
|
59
|
+
customModel?: LocalProviderRuntimeOptions["customModel"] | null;
|
|
60
|
+
modelCapabilities?: LocalProviderRuntimeOptions["modelCapabilities"] | null;
|
|
61
|
+
isPrivateProvider?: LocalProviderRuntimeOptions["isPrivateProvider"] | null;
|
|
62
|
+
};
|
|
63
|
+
readonly cleanup: () => Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
export declare function createRequestModelOverrideRuntimeExtension(options?: RequestModelOverrideOptions): (input: RequestModelOverrideInput) => Promise<RequestModelOverrideResult>;
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=request-model-override.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-model-override.d.ts","sourceRoot":"","sources":["../src/request-model-override.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,uBAAuB,EACvB,2BAA2B,EAC3B,qBAAqB,EACtB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,WAAW,0BAA0B;IACzC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAClE;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,0BAA0B,CAAC;IAC7C;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAC9D;AAED,UAAU,yBAAyB;IACjC,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;CACnE;AAED,UAAU,0BAA0B;IAClC,QAAQ,CAAC,cAAc,EAAE;QACvB,KAAK,CAAC,EAAE,qBAAqB,CAAC;QAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;QAIhB,cAAc,CAAC,EAAE,2BAA2B,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;QACtE,WAAW,CAAC,EAAE,2BAA2B,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;QAChE,iBAAiB,CAAC,EAAE,2BAA2B,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC;QAC5E,iBAAiB,CAAC,EAAE,2BAA2B,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC;KAC7E,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAID,wBAAgB,0CAA0C,CACxD,OAAO,CAAC,EAAE,2BAA2B,GACpC,CAAC,KAAK,EAAE,yBAAyB,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAoC3E"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { EFFORT_LEVELS } from "@mono-agent/config";
|
|
2
|
+
import { parseMonoRuntimeModelReference, runtimeOptionsForLocalProvider } from "@mono-agent/runtime-adapter";
|
|
3
|
+
const EFFORT_SET = new Set(EFFORT_LEVELS);
|
|
4
|
+
export function createRequestModelOverrideRuntimeExtension(options) {
|
|
5
|
+
const logger = options?.logger;
|
|
6
|
+
const localProviders = options?.localProviders;
|
|
7
|
+
return async (input) => {
|
|
8
|
+
const { model: rawModel, effort: rawEffort } = readOverride(input.request.metadata);
|
|
9
|
+
const runtimeOptions = {};
|
|
10
|
+
if (rawModel !== undefined) {
|
|
11
|
+
let parsed;
|
|
12
|
+
try {
|
|
13
|
+
parsed = parseMonoRuntimeModelReference(rawModel);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
logger?.warn?.("Ignoring invalid per-request model override.", {
|
|
17
|
+
model: rawModel,
|
|
18
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
if (parsed !== undefined) {
|
|
22
|
+
runtimeOptions.model = parsed;
|
|
23
|
+
applyLocalProviderBlock(runtimeOptions, parsed, rawModel, localProviders, logger);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (rawEffort !== undefined) {
|
|
27
|
+
if (EFFORT_SET.has(rawEffort)) {
|
|
28
|
+
runtimeOptions.effort = rawEffort;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
logger?.warn?.("Ignoring invalid per-request effort override.", {
|
|
32
|
+
effort: rawEffort,
|
|
33
|
+
valid: [...EFFORT_SET],
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return { runtimeOptions, cleanup: async () => { } };
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* OWN the endpoint block for a valid model override. For a model served by a
|
|
42
|
+
* configured LOCAL provider, `runtimeOptionsForLocalProvider` yields the block and
|
|
43
|
+
* we SET all four fields. For a cloud/registry model or an unconfigured provider
|
|
44
|
+
* id it returns `{}`, so `x ?? null` sets each field to `null` — the harness merge
|
|
45
|
+
* reads that as an explicit CLEAR of the host default's local block (undefined
|
|
46
|
+
* would silently inherit it and mis-route the run to localhost). A genuinely
|
|
47
|
+
* MISCONFIGURED provider (e.g. an untrusted public HTTP baseUrl) throws; that is
|
|
48
|
+
* warned-and-ignored and treated as non-local (block cleared) so a bad override
|
|
49
|
+
* never fails the turn — the model ref still applies.
|
|
50
|
+
*/
|
|
51
|
+
function applyLocalProviderBlock(runtimeOptions, model, rawModel, localProviders, logger) {
|
|
52
|
+
let local;
|
|
53
|
+
try {
|
|
54
|
+
local = runtimeOptionsForLocalProvider(model, localProviders);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
logger?.warn?.("Ignoring local-provider endpoint for per-request model override.", {
|
|
58
|
+
model: rawModel,
|
|
59
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
60
|
+
});
|
|
61
|
+
local = {};
|
|
62
|
+
}
|
|
63
|
+
runtimeOptions.customProvider = local.customProvider ?? null;
|
|
64
|
+
runtimeOptions.customModel = local.customModel ?? null;
|
|
65
|
+
runtimeOptions.modelCapabilities = local.modelCapabilities ?? null;
|
|
66
|
+
runtimeOptions.isPrivateProvider = local.isPrivateProvider ?? null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Read model/effort from webhook, cron, or TUI request metadata. Webhook takes
|
|
70
|
+
* precedence, then cron, then an interactive TUI per-session override — a turn
|
|
71
|
+
* is only ever one of the three. A turn carrying none of these blocks (e.g. an
|
|
72
|
+
* ordinary chat turn) returns `{}` and the extension is a no-op.
|
|
73
|
+
*/
|
|
74
|
+
function readOverride(metadata) {
|
|
75
|
+
if (!isRecord(metadata)) {
|
|
76
|
+
return {};
|
|
77
|
+
}
|
|
78
|
+
const source = isRecord(metadata.webhook)
|
|
79
|
+
? metadata.webhook
|
|
80
|
+
: isRecord(metadata.cron)
|
|
81
|
+
? metadata.cron
|
|
82
|
+
: isRecord(metadata.tui)
|
|
83
|
+
? metadata.tui
|
|
84
|
+
: undefined;
|
|
85
|
+
if (source === undefined) {
|
|
86
|
+
return {};
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
...(typeof source.model === "string" ? { model: source.model } : {}),
|
|
90
|
+
...(typeof source.effort === "string" ? { effort: source.effort } : {}),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function isRecord(value) {
|
|
94
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=request-model-override.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-model-override.js","sourceRoot":"","sources":["../src/request-model-override.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type RecordedRunListItem } from "@mono-agent/observability";
|
|
2
|
+
export declare const RUNS_HEALTH_MAX_RUNS = 50;
|
|
3
|
+
export declare const RUNS_HEALTH_RECENT_RUNS = 5;
|
|
4
|
+
export type RunsHealthStatus = "ok" | "waiting" | "disabled";
|
|
5
|
+
export interface RunsHealthDisplay {
|
|
6
|
+
readonly status: RunsHealthStatus;
|
|
7
|
+
readonly details: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
export interface BuildRunsHealthDisplayInput {
|
|
10
|
+
readonly artifactDir: string;
|
|
11
|
+
readonly totalRuns?: number;
|
|
12
|
+
readonly runs: readonly RecordedRunListItem[];
|
|
13
|
+
readonly warnings: readonly string[];
|
|
14
|
+
readonly selectedSkills?: readonly string[];
|
|
15
|
+
readonly includeSelectedSkills?: boolean;
|
|
16
|
+
readonly runOwnerAlive?: boolean;
|
|
17
|
+
readonly nowMs?: number;
|
|
18
|
+
readonly maxRuns?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function buildRunsHealthDisplay(input: BuildRunsHealthDisplayInput): RunsHealthDisplay;
|
|
21
|
+
export declare function formatSelectedSkillsLine(selectedSkills: readonly string[] | undefined): string;
|
|
22
|
+
//# sourceMappingURL=runs-health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs-health.d.ts","sourceRoot":"","sources":["../src/runs-health.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,mBAAmB,EAEzB,MAAM,2BAA2B,CAAC;AAEnC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,SAAS,GAAG,UAAU,CAAC;AAE7D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC9C,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAKD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,GAAG,iBAAiB,CAuE5F;AAED,wBAAgB,wBAAwB,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,CAM9F"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { describeRunFailureKind, RUNS_HEALTH_STALE_RUNNING_MS, } from "@mono-agent/observability";
|
|
2
|
+
export const RUNS_HEALTH_MAX_RUNS = 50;
|
|
3
|
+
export const RUNS_HEALTH_RECENT_RUNS = 5;
|
|
4
|
+
const RUN_SUMMARY_STATUSES = ["running", "succeeded", "failed", "cancelled", "interrupted"];
|
|
5
|
+
const FAILED_LIKE_RUN_STATUSES = new Set(["failed", "cancelled", "interrupted"]);
|
|
6
|
+
export function buildRunsHealthDisplay(input) {
|
|
7
|
+
const maxRuns = input.maxRuns ?? RUNS_HEALTH_MAX_RUNS;
|
|
8
|
+
const now = input.nowMs ?? Date.now();
|
|
9
|
+
const totalRuns = input.totalRuns ?? input.runs.length;
|
|
10
|
+
const details = [
|
|
11
|
+
...(input.includeSelectedSkills ? [formatSelectedSkillsLine(input.selectedSkills)] : []),
|
|
12
|
+
`Artifact dir: ${input.artifactDir}`,
|
|
13
|
+
`Recorded runs: ${totalRuns} total; showing ${input.runs.length} recent (max ${maxRuns}).`,
|
|
14
|
+
];
|
|
15
|
+
let hasWarnings = false;
|
|
16
|
+
for (const warning of input.warnings) {
|
|
17
|
+
hasWarnings = true;
|
|
18
|
+
details.push(`[WARN] Run artifact reader: ${warning}`);
|
|
19
|
+
}
|
|
20
|
+
if (input.runs.length === 0) {
|
|
21
|
+
details.push("No runs recorded yet.");
|
|
22
|
+
return { status: hasWarnings ? "waiting" : "disabled", details };
|
|
23
|
+
}
|
|
24
|
+
details.push(`Last runs: ${formatRunExamples(input.runs, now)}.`);
|
|
25
|
+
const statusCounts = statusHistogram(input.runs);
|
|
26
|
+
details.push(`Recent status counts: ${RUN_SUMMARY_STATUSES.map((status) => `${status}=${statusCounts[status]}`).join(", ")}.`);
|
|
27
|
+
const staleRunning = input.runs.filter((run) => isStaleRunningRun(run, now));
|
|
28
|
+
if (staleRunning.length > 0) {
|
|
29
|
+
hasWarnings = true;
|
|
30
|
+
details.push(`[WARN] Stale running runs older than ${RUNS_HEALTH_STALE_RUNNING_MS / 60_000}m: ${formatRunExamples(staleRunning, now)}.`);
|
|
31
|
+
}
|
|
32
|
+
const runningWhileOwnerGone = input.runOwnerAlive === false
|
|
33
|
+
? input.runs.filter((run) => run.status === "running")
|
|
34
|
+
: [];
|
|
35
|
+
if (runningWhileOwnerGone.length > 0) {
|
|
36
|
+
hasWarnings = true;
|
|
37
|
+
details.push(`[WARN] Running summaries while process is gone: ${formatRunExamples(runningWhileOwnerGone, now)}.`);
|
|
38
|
+
}
|
|
39
|
+
const unsuccessful = input.runs.filter((run) => FAILED_LIKE_RUN_STATUSES.has(run.status));
|
|
40
|
+
if (unsuccessful.length > 0) {
|
|
41
|
+
hasWarnings = true;
|
|
42
|
+
details.push(`[WARN] Recent non-successful runs: ${formatRunExamples(unsuccessful, now)}.`);
|
|
43
|
+
}
|
|
44
|
+
if (statusCounts.cancelled > 0) {
|
|
45
|
+
hasWarnings = true;
|
|
46
|
+
details.push(`[WARN] Cancelled recent runs: ${statusCounts.cancelled}.`);
|
|
47
|
+
}
|
|
48
|
+
if (statusCounts.interrupted > 0) {
|
|
49
|
+
hasWarnings = true;
|
|
50
|
+
details.push(`[WARN] Interrupted recent runs: ${statusCounts.interrupted}.`);
|
|
51
|
+
}
|
|
52
|
+
const failureKindCounts = failureKindHistogram(input.runs);
|
|
53
|
+
if (failureKindCounts.length > 0) {
|
|
54
|
+
hasWarnings = true;
|
|
55
|
+
details.push(`[WARN] Failure kinds: ${failureKindCounts.map(([kind, count]) => `${kind}=${count}`).join(", ")}.`);
|
|
56
|
+
for (const [kind, count] of failureKindCounts) {
|
|
57
|
+
const description = describeRunFailureKind({ failureKind: kind });
|
|
58
|
+
const prefix = description.known ? description.kind : `${description.kind} (unclassified)`;
|
|
59
|
+
details.push(`[WARN] ${description.label} [${prefix}, ${count} recent]: ${description.explanation} Next: ${description.nextStep}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
details.push("Failure kinds: none in recent window.");
|
|
64
|
+
}
|
|
65
|
+
return { status: hasWarnings ? "waiting" : "ok", details };
|
|
66
|
+
}
|
|
67
|
+
export function formatSelectedSkillsLine(selectedSkills) {
|
|
68
|
+
if (selectedSkills === undefined) {
|
|
69
|
+
return "Active skills: unavailable.";
|
|
70
|
+
}
|
|
71
|
+
const names = selectedSkills.map((skill) => skill.trim()).filter(Boolean);
|
|
72
|
+
return names.length === 0 ? "Active skills: none." : `Active skills: ${names.join(", ")}.`;
|
|
73
|
+
}
|
|
74
|
+
function statusHistogram(runs) {
|
|
75
|
+
const counts = {
|
|
76
|
+
running: 0,
|
|
77
|
+
succeeded: 0,
|
|
78
|
+
failed: 0,
|
|
79
|
+
cancelled: 0,
|
|
80
|
+
interrupted: 0,
|
|
81
|
+
};
|
|
82
|
+
for (const run of runs) {
|
|
83
|
+
counts[run.status] += 1;
|
|
84
|
+
}
|
|
85
|
+
return counts;
|
|
86
|
+
}
|
|
87
|
+
function isStaleRunningRun(run, now) {
|
|
88
|
+
if (run.status !== "running" || run.startedAt === undefined) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
const startedAtMs = Date.parse(run.startedAt);
|
|
92
|
+
return Number.isFinite(startedAtMs) && now - startedAtMs > RUNS_HEALTH_STALE_RUNNING_MS;
|
|
93
|
+
}
|
|
94
|
+
function failureKindHistogram(runs) {
|
|
95
|
+
const counts = new Map();
|
|
96
|
+
for (const run of runs) {
|
|
97
|
+
const failureKind = displayFailureKind(run);
|
|
98
|
+
if (failureKind !== undefined) {
|
|
99
|
+
counts.set(failureKind, (counts.get(failureKind) ?? 0) + 1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return [...counts.entries()].sort(([leftKind, leftCount], [rightKind, rightCount]) => rightCount - leftCount || leftKind.localeCompare(rightKind));
|
|
103
|
+
}
|
|
104
|
+
function displayFailureKind(run) {
|
|
105
|
+
const failureKind = run.failureKind?.trim();
|
|
106
|
+
if (failureKind !== undefined && failureKind.length > 0) {
|
|
107
|
+
return failureKind;
|
|
108
|
+
}
|
|
109
|
+
if (!FAILED_LIKE_RUN_STATUSES.has(run.status)) {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
return describeRunFailureKind({ status: run.status }).kind;
|
|
113
|
+
}
|
|
114
|
+
function formatRunExamples(runs, nowMs) {
|
|
115
|
+
const shown = runs.slice(0, RUNS_HEALTH_RECENT_RUNS).map((run) => `${run.runId} ${run.status} ${formatRelativeAge(runTimestamp(run), nowMs)}`);
|
|
116
|
+
const remaining = runs.length - shown.length;
|
|
117
|
+
return remaining > 0 ? `${shown.join(", ")} and ${remaining} more` : shown.join(", ");
|
|
118
|
+
}
|
|
119
|
+
function runTimestamp(run) {
|
|
120
|
+
return run.endedAt ?? run.updatedAt ?? run.startedAt;
|
|
121
|
+
}
|
|
122
|
+
function formatRelativeAge(timestamp, nowMs) {
|
|
123
|
+
if (timestamp === undefined) {
|
|
124
|
+
return "age unknown";
|
|
125
|
+
}
|
|
126
|
+
const parsed = Date.parse(timestamp);
|
|
127
|
+
if (!Number.isFinite(parsed)) {
|
|
128
|
+
return "age unknown";
|
|
129
|
+
}
|
|
130
|
+
const elapsedSeconds = Math.max(0, Math.floor((nowMs - parsed) / 1000));
|
|
131
|
+
if (elapsedSeconds < 60) {
|
|
132
|
+
return `${elapsedSeconds}s ago`;
|
|
133
|
+
}
|
|
134
|
+
const elapsedMinutes = Math.floor(elapsedSeconds / 60);
|
|
135
|
+
if (elapsedMinutes < 60) {
|
|
136
|
+
return `${elapsedMinutes}m ago`;
|
|
137
|
+
}
|
|
138
|
+
const elapsedHours = Math.floor(elapsedMinutes / 60);
|
|
139
|
+
if (elapsedHours < 48) {
|
|
140
|
+
return `${elapsedHours}h ago`;
|
|
141
|
+
}
|
|
142
|
+
return `${Math.floor(elapsedHours / 24)}d ago`;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=runs-health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs-health.js","sourceRoot":"","sources":["../src/runs-health.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ChannelId } from "./channels.js";
|
|
2
|
+
/** A real conversation the agent has handled, recovered from run artifacts. */
|
|
3
|
+
export interface SeenConversation {
|
|
4
|
+
/** The base (de-bucketed) conversationId to use as a `notify` destination. */
|
|
5
|
+
readonly conversationId: string;
|
|
6
|
+
readonly channelId: ChannelId;
|
|
7
|
+
/** ISO timestamp of the most recent run on this conversation, if recorded. */
|
|
8
|
+
readonly lastSeen?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ListSeenOptions {
|
|
11
|
+
/** Cap on the number of (newest-first) summary files read. Default 2000. */
|
|
12
|
+
readonly limit?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Distinct push-channel conversationIds the agent has actually handled, read from
|
|
16
|
+
* the run-artifact summaries in `artifactDir`. Synthetic ids (`cron:`/`webhook:`/…)
|
|
17
|
+
* are dropped via {@link channelIdForConversation}; daily-rollover buckets are
|
|
18
|
+
* stripped to the base id (the form a `notify` destination uses) and deduped to the
|
|
19
|
+
* most recent sighting. Sorted newest-first. A missing dir yields an empty list.
|
|
20
|
+
*/
|
|
21
|
+
export declare function listSeenNotifyDestinations(artifactDir: string, options?: ListSeenOptions): Promise<readonly SeenConversation[]>;
|
|
22
|
+
//# sourceMappingURL=seen-conversations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seen-conversations.d.ts","sourceRoot":"","sources":["../src/seen-conversations.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG/C,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B,8EAA8E;IAC9E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAQD;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC,CAwDtC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { readFile, readdir, stat } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { channelIdForConversation } from "./proactive-notify.js";
|
|
4
|
+
const DEFAULT_LIMIT = 2000;
|
|
5
|
+
const SUMMARY_SUFFIX = ".summary.json";
|
|
6
|
+
const ROLLOVER_BUCKET = /#\d{4}-\d{2}-\d{2}$/u;
|
|
7
|
+
/** Max summary files statted concurrently, to bound open fds and avoid EMFILE. */
|
|
8
|
+
const STAT_BATCH_SIZE = 64;
|
|
9
|
+
/**
|
|
10
|
+
* Distinct push-channel conversationIds the agent has actually handled, read from
|
|
11
|
+
* the run-artifact summaries in `artifactDir`. Synthetic ids (`cron:`/`webhook:`/…)
|
|
12
|
+
* are dropped via {@link channelIdForConversation}; daily-rollover buckets are
|
|
13
|
+
* stripped to the base id (the form a `notify` destination uses) and deduped to the
|
|
14
|
+
* most recent sighting. Sorted newest-first. A missing dir yields an empty list.
|
|
15
|
+
*/
|
|
16
|
+
export async function listSeenNotifyDestinations(artifactDir, options = {}) {
|
|
17
|
+
const limit = options.limit ?? DEFAULT_LIMIT;
|
|
18
|
+
let entries;
|
|
19
|
+
try {
|
|
20
|
+
entries = await readdir(artifactDir);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Dir absent (agent never ran) or unreadable → nothing seen yet.
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
const summaries = entries.filter((name) => name.endsWith(SUMMARY_SUFFIX));
|
|
27
|
+
// Summary filenames are conversationId-based with no embedded time ordering, so a
|
|
28
|
+
// full stat pass is required to learn each file's mtime before we can take the
|
|
29
|
+
// newest `limit`. We stat in bounded batches (not one big Promise.all over every
|
|
30
|
+
// summary) to keep open file descriptors capped and avoid EMFILE/IO spikes on a
|
|
31
|
+
// busy agent with thousands of artifacts.
|
|
32
|
+
const withMtime = [];
|
|
33
|
+
for (let i = 0; i < summaries.length; i += STAT_BATCH_SIZE) {
|
|
34
|
+
const batch = summaries.slice(i, i + STAT_BATCH_SIZE);
|
|
35
|
+
const stated = await Promise.all(batch.map(async (name) => {
|
|
36
|
+
try {
|
|
37
|
+
return { name, mtimeMs: (await stat(join(artifactDir, name))).mtimeMs };
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return { name, mtimeMs: 0 };
|
|
41
|
+
}
|
|
42
|
+
}));
|
|
43
|
+
withMtime.push(...stated);
|
|
44
|
+
}
|
|
45
|
+
// Newest files first, then cap, so a busy agent's scan stays bounded.
|
|
46
|
+
withMtime.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
47
|
+
const latest = new Map();
|
|
48
|
+
for (const { name } of withMtime.slice(0, limit)) {
|
|
49
|
+
const parsed = await readSummary(join(artifactDir, name));
|
|
50
|
+
if (parsed === undefined) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const channelId = channelIdForConversation(parsed.conversationId);
|
|
54
|
+
if (channelId === undefined) {
|
|
55
|
+
continue; // synthetic / non-push destination
|
|
56
|
+
}
|
|
57
|
+
const conversationId = parsed.conversationId.replace(ROLLOVER_BUCKET, "");
|
|
58
|
+
const seen = {
|
|
59
|
+
conversationId,
|
|
60
|
+
channelId,
|
|
61
|
+
...(parsed.lastSeen === undefined ? {} : { lastSeen: parsed.lastSeen }),
|
|
62
|
+
};
|
|
63
|
+
const prior = latest.get(conversationId);
|
|
64
|
+
if (prior === undefined || isNewer(seen.lastSeen, prior.lastSeen)) {
|
|
65
|
+
latest.set(conversationId, seen);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return [...latest.values()].sort((a, b) => compareLastSeen(b.lastSeen, a.lastSeen));
|
|
69
|
+
}
|
|
70
|
+
async function readSummary(path) {
|
|
71
|
+
let raw;
|
|
72
|
+
try {
|
|
73
|
+
raw = await readFile(path, "utf8");
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
let json;
|
|
79
|
+
try {
|
|
80
|
+
json = JSON.parse(raw);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
if (typeof json !== "object" || json === null) {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
const record = json;
|
|
89
|
+
const conversationId = record.conversationId;
|
|
90
|
+
if (typeof conversationId !== "string" || conversationId.length === 0) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
const lastSeen = firstString(record.endedAt, record.updatedAt, record.startedAt);
|
|
94
|
+
return { conversationId, ...(lastSeen === undefined ? {} : { lastSeen }) };
|
|
95
|
+
}
|
|
96
|
+
function firstString(...values) {
|
|
97
|
+
for (const value of values) {
|
|
98
|
+
if (typeof value === "string" && value.length > 0) {
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
function isNewer(candidate, current) {
|
|
105
|
+
return compareLastSeen(candidate, current) > 0;
|
|
106
|
+
}
|
|
107
|
+
/** Compare ISO timestamps; a missing timestamp sorts oldest. */
|
|
108
|
+
function compareLastSeen(a, b) {
|
|
109
|
+
if (a === b) {
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
if (a === undefined) {
|
|
113
|
+
return -1;
|
|
114
|
+
}
|
|
115
|
+
if (b === undefined) {
|
|
116
|
+
return 1;
|
|
117
|
+
}
|
|
118
|
+
return a < b ? -1 : 1;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=seen-conversations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seen-conversations.js","sourceRoot":"","sources":["../src/seen-conversations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { MonoAgentAppConfigInput } from "./app-config.js";
|
|
2
|
+
export interface PurgeSessionsResult {
|
|
3
|
+
/** The resolved sessions root, or undefined when sessions are in-memory only. */
|
|
4
|
+
readonly root?: string;
|
|
5
|
+
/** True when an on-disk sessions store existed and was removed. */
|
|
6
|
+
readonly removed: boolean;
|
|
7
|
+
/** Count of removed `*.jsonl` session files (best-effort; 0 when none/unknown). */
|
|
8
|
+
readonly files: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Remove the durable pi-session store so the next start begins with fresh sessions
|
|
12
|
+
* instead of resuming persisted transcripts. A no-op (`removed: false`) when no
|
|
13
|
+
* on-disk store is configured (in-memory sessions) or the directory does not exist.
|
|
14
|
+
*
|
|
15
|
+
* The runtime recreates the directory on the next session, and the agent's durable
|
|
16
|
+
* memory lives elsewhere (`memory.path`), so this drops only resumable conversation
|
|
17
|
+
* transcripts — not the knowledge base. Stop the worker before calling this so it is
|
|
18
|
+
* not writing sessions while they are deleted.
|
|
19
|
+
*/
|
|
20
|
+
export declare function purgeSessions(input: MonoAgentAppConfigInput): Promise<PurgeSessionsResult>;
|
|
21
|
+
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../src/sessions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE/D,MAAM,WAAW,mBAAmB;IAClC,iFAAiF;IACjF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAgBhG"}
|
package/dist/sessions.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readdir, rm } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { resolveAppSessionsRoot } from "./app-config.js";
|
|
4
|
+
/**
|
|
5
|
+
* Remove the durable pi-session store so the next start begins with fresh sessions
|
|
6
|
+
* instead of resuming persisted transcripts. A no-op (`removed: false`) when no
|
|
7
|
+
* on-disk store is configured (in-memory sessions) or the directory does not exist.
|
|
8
|
+
*
|
|
9
|
+
* The runtime recreates the directory on the next session, and the agent's durable
|
|
10
|
+
* memory lives elsewhere (`memory.path`), so this drops only resumable conversation
|
|
11
|
+
* transcripts — not the knowledge base. Stop the worker before calling this so it is
|
|
12
|
+
* not writing sessions while they are deleted.
|
|
13
|
+
*/
|
|
14
|
+
export async function purgeSessions(input) {
|
|
15
|
+
const root = await resolveAppSessionsRoot(input);
|
|
16
|
+
if (root === undefined) {
|
|
17
|
+
return { removed: false, files: 0 };
|
|
18
|
+
}
|
|
19
|
+
let files = 0;
|
|
20
|
+
try {
|
|
21
|
+
files = await countSessionFiles(root);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// The store may not exist yet; treat it as nothing to remove.
|
|
25
|
+
return { root, removed: false, files: 0 };
|
|
26
|
+
}
|
|
27
|
+
await rm(root, { recursive: true, force: true });
|
|
28
|
+
return { root, removed: true, files };
|
|
29
|
+
}
|
|
30
|
+
/** Recursively count `*.jsonl` session files under a sessions root. */
|
|
31
|
+
async function countSessionFiles(dir) {
|
|
32
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
33
|
+
let total = 0;
|
|
34
|
+
for (const entry of entries) {
|
|
35
|
+
const full = join(dir, entry.name);
|
|
36
|
+
if (entry.isDirectory()) {
|
|
37
|
+
total += await countSessionFiles(full);
|
|
38
|
+
}
|
|
39
|
+
else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
40
|
+
total += 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return total;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../src/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAYzD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAA8B;IAChE,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACjD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IACtC,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,8DAA8D;QAC9D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACxC,CAAC;AAED,uEAAuE;AACvE,KAAK,UAAU,iBAAiB,CAAC,GAAW;IAC1C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,KAAK,IAAI,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3D,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/setup.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { WithChannel } from "./init.js";
|
|
2
|
+
import type { AgentRecipe, RecipeInputValues } from "./recipes/index.js";
|
|
3
|
+
export interface SetupPromptSource {
|
|
4
|
+
question(prompt: string): Promise<string>;
|
|
5
|
+
}
|
|
6
|
+
export interface SecretChecklistItem {
|
|
7
|
+
readonly id: string;
|
|
8
|
+
readonly label: string;
|
|
9
|
+
readonly description: string;
|
|
10
|
+
readonly envVar?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface CollectSetupOptions {
|
|
13
|
+
readonly prompt: SetupPromptSource;
|
|
14
|
+
readonly recipe?: AgentRecipe;
|
|
15
|
+
readonly model?: string;
|
|
16
|
+
readonly fallbackModels?: readonly string[];
|
|
17
|
+
readonly withChannels?: readonly WithChannel[];
|
|
18
|
+
readonly recipes?: readonly AgentRecipe[];
|
|
19
|
+
}
|
|
20
|
+
export interface CollectedSetupOptions {
|
|
21
|
+
readonly recipe: AgentRecipe;
|
|
22
|
+
readonly recipeInputs: RecipeInputValues;
|
|
23
|
+
readonly fallbackModels: readonly string[];
|
|
24
|
+
readonly withChannels: readonly WithChannel[];
|
|
25
|
+
readonly secrets: readonly SecretChecklistItem[];
|
|
26
|
+
}
|
|
27
|
+
export declare function collectSetupOptions(options: CollectSetupOptions): Promise<CollectedSetupOptions>;
|
|
28
|
+
export declare function renderSetupRecipeMenu(recipes?: readonly AgentRecipe[]): string;
|
|
29
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAe,MAAM,oBAAoB,CAAC;AAEtF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAC/C,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC;IACzC,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,YAAY,EAAE,SAAS,WAAW,EAAE,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAClD;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAwBtG;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,SAAS,WAAW,EAAmB,GAAG,MAAM,CAO9F"}
|