@haaaiawd/second-nature 0.1.34 → 0.1.39
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/agent-inner-guide.md +43 -0
- package/index.js +1270 -1262
- package/openclaw.plugin.json +29 -29
- package/package.json +55 -55
- package/runtime/cli/commands/goal.d.ts +1 -0
- package/runtime/cli/commands/goal.js +1 -0
- package/runtime/cli/index.js +3 -3
- package/runtime/cli/ops/heartbeat-surface.d.ts +75 -54
- package/runtime/cli/ops/heartbeat-surface.js +97 -81
- package/runtime/cli/ops/ops-router.js +1428 -1182
- package/runtime/cli/ops/workspace-heartbeat-runner.d.ts +24 -0
- package/runtime/cli/ops/workspace-heartbeat-runner.js +236 -150
- package/runtime/connectors/base/contract.d.ts +10 -0
- package/runtime/core/second-nature/guidance/apply-guidance.d.ts +12 -10
- package/runtime/core/second-nature/guidance/apply-guidance.js +15 -10
- package/runtime/core/second-nature/guidance/user-reply-continuity.d.ts +50 -50
- package/runtime/core/second-nature/guidance/user-reply-continuity.js +89 -80
- package/runtime/core/second-nature/heartbeat/heartbeat-loop.d.ts +7 -1
- package/runtime/core/second-nature/heartbeat/heartbeat-loop.js +25 -0
- package/runtime/core/second-nature/heartbeat/runtime-snapshot.d.ts +5 -0
- package/runtime/core/second-nature/heartbeat/runtime-snapshot.js +10 -1
- package/runtime/core/second-nature/heartbeat/snapshot-builder.d.ts +5 -0
- package/runtime/core/second-nature/orchestrator/guard-layer.js +24 -1
- package/runtime/core/second-nature/quiet/run-source-backed-quiet.d.ts +20 -0
- package/runtime/core/second-nature/quiet/run-source-backed-quiet.js +32 -2
- package/runtime/core/second-nature/runtime/service-entry.d.ts +39 -36
- package/runtime/core/second-nature/runtime/service-entry.js +44 -45
- package/runtime/dream/dream-engine.d.ts +14 -0
- package/runtime/dream/dream-engine.js +306 -0
- package/runtime/dream/dream-input-loader.d.ts +37 -0
- package/runtime/dream/dream-input-loader.js +155 -0
- package/runtime/dream/dream-scheduler.d.ts +75 -0
- package/runtime/dream/dream-scheduler.js +131 -0
- package/runtime/dream/index.d.ts +16 -0
- package/runtime/dream/index.js +14 -0
- package/runtime/dream/insight-extractor.d.ts +32 -0
- package/runtime/dream/insight-extractor.js +135 -0
- package/runtime/dream/memory-consolidator.d.ts +45 -0
- package/runtime/dream/memory-consolidator.js +140 -0
- package/runtime/dream/narrative-update-proposal.d.ts +34 -0
- package/runtime/dream/narrative-update-proposal.js +83 -0
- package/runtime/dream/output-validator.d.ts +20 -0
- package/runtime/dream/output-validator.js +110 -0
- package/runtime/dream/redaction-gate.d.ts +31 -0
- package/runtime/dream/redaction-gate.js +109 -0
- package/runtime/dream/relationship-update-proposal.d.ts +27 -0
- package/runtime/dream/relationship-update-proposal.js +119 -0
- package/runtime/dream/sampler.d.ts +30 -0
- package/runtime/dream/sampler.js +65 -0
- package/runtime/dream/types.d.ts +187 -0
- package/runtime/dream/types.js +11 -0
- package/runtime/guidance/capability-class.d.ts +38 -0
- package/runtime/guidance/capability-class.js +65 -0
- package/runtime/guidance/fallback.js +20 -17
- package/runtime/guidance/guidance-assembler.d.ts +2 -0
- package/runtime/guidance/guidance-assembler.js +76 -62
- package/runtime/guidance/guidance-draft-service.js +5 -5
- package/runtime/guidance/impulse-assembler.d.ts +71 -0
- package/runtime/guidance/impulse-assembler.js +103 -0
- package/runtime/guidance/index.d.ts +2 -0
- package/runtime/guidance/index.js +2 -0
- package/runtime/guidance/output-guard.d.ts +13 -10
- package/runtime/guidance/output-guard.js +53 -29
- package/runtime/guidance/outreach-strategy-selector.d.ts +13 -0
- package/runtime/guidance/outreach-strategy-selector.js +2 -2
- package/runtime/guidance/template-registry.d.ts +20 -3
- package/runtime/guidance/template-registry.js +123 -45
- package/runtime/guidance/types.d.ts +98 -72
- package/runtime/observability/projections/guidance-audit.js +38 -35
- package/runtime/storage/goal/agent-goal-store.d.ts +2 -0
- package/runtime/storage/goal/agent-goal-store.js +28 -1
- package/runtime/storage/services/tool-experience-store.js +11 -11
package/openclaw.plugin.json
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "second-nature",
|
|
3
|
-
"name": "Second Nature",
|
|
4
|
-
"version": "0.1.
|
|
5
|
-
"description": "OpenClaw native plugin with synchronous surface registration and bundled runtime spine. Set SECOND_NATURE_WORKSPACE_ROOT or tool workspaceRoot to the same path as the agent workspace. Agent inner guide is packaged as agent-inner-guide.md. v7 ops surface: self_health, tool_affordance, heartbeat_digest, snapshot:capture, narrative:diff, timeline, restore, runtime_secret_bootstrap.",
|
|
6
|
-
"activation": {
|
|
7
|
-
"onStartup": true,
|
|
8
|
-
"onCapabilities": [
|
|
9
|
-
"tool"
|
|
10
|
-
]
|
|
11
|
-
},
|
|
12
|
-
"contracts": {
|
|
13
|
-
"commands": [
|
|
14
|
-
"second-nature"
|
|
15
|
-
],
|
|
16
|
-
"tools": [
|
|
17
|
-
"second_nature_ops"
|
|
18
|
-
],
|
|
19
|
-
"services": [
|
|
20
|
-
"second-nature-runtime",
|
|
21
|
-
"second-nature-lifecycle"
|
|
22
|
-
]
|
|
23
|
-
},
|
|
24
|
-
"configSchema": {
|
|
25
|
-
"type": "object",
|
|
26
|
-
"additionalProperties": false,
|
|
27
|
-
"properties": {}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"id": "second-nature",
|
|
3
|
+
"name": "Second Nature",
|
|
4
|
+
"version": "0.1.38",
|
|
5
|
+
"description": "OpenClaw native plugin with synchronous surface registration and bundled runtime spine. Set SECOND_NATURE_WORKSPACE_ROOT or tool workspaceRoot to the same path as the agent workspace. Agent inner guide is packaged as agent-inner-guide.md. v7 ops surface: self_health, tool_affordance, heartbeat_digest, snapshot:capture, narrative:diff, timeline, restore, runtime_secret_bootstrap, connector:run, guidance_payload.",
|
|
6
|
+
"activation": {
|
|
7
|
+
"onStartup": true,
|
|
8
|
+
"onCapabilities": [
|
|
9
|
+
"tool"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"contracts": {
|
|
13
|
+
"commands": [
|
|
14
|
+
"second-nature"
|
|
15
|
+
],
|
|
16
|
+
"tools": [
|
|
17
|
+
"second_nature_ops"
|
|
18
|
+
],
|
|
19
|
+
"services": [
|
|
20
|
+
"second-nature-runtime",
|
|
21
|
+
"second-nature-lifecycle"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"configSchema": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"additionalProperties": false,
|
|
27
|
+
"properties": {}
|
|
28
|
+
}
|
|
29
|
+
}
|
package/package.json
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@haaaiawd/second-nature",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "OpenClaw native plugin with synchronous registration, a packaged runtime artifact, and operator-facing status/explain flows.",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"openclaw",
|
|
7
|
-
"plugin",
|
|
8
|
-
"agent",
|
|
9
|
-
"continuity",
|
|
10
|
-
"quiet",
|
|
11
|
-
"memory",
|
|
12
|
-
"observability",
|
|
13
|
-
"operator"
|
|
14
|
-
],
|
|
15
|
-
"license": "Apache-2.0",
|
|
16
|
-
"type": "module",
|
|
17
|
-
"main": "./index.js",
|
|
18
|
-
"files": [
|
|
19
|
-
"index.js",
|
|
20
|
-
"workspace-ops-bridge.js",
|
|
21
|
-
"openclaw.plugin.json",
|
|
22
|
-
"SKILL.md",
|
|
23
|
-
"agent-inner-guide.md",
|
|
24
|
-
"runtime/"
|
|
25
|
-
],
|
|
26
|
-
"publishConfig": {
|
|
27
|
-
"access": "public"
|
|
28
|
-
},
|
|
29
|
-
"openclaw": {
|
|
30
|
-
"manifest": "./openclaw.plugin.json",
|
|
31
|
-
"extensions": [
|
|
32
|
-
"./index.js"
|
|
33
|
-
],
|
|
34
|
-
"runtimeExtensions": [
|
|
35
|
-
"./index.js"
|
|
36
|
-
],
|
|
37
|
-
"compat": {
|
|
38
|
-
"pluginApi": ">=2026.5.12"
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
"peerDependencies": {
|
|
42
|
-
"openclaw": ">=2026.5.12"
|
|
43
|
-
},
|
|
44
|
-
"peerDependenciesMeta": {
|
|
45
|
-
"openclaw": {
|
|
46
|
-
"optional": true
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
"dependencies": {
|
|
50
|
-
"drizzle-orm": "^0.45.2",
|
|
51
|
-
"js-yaml": "^4.1.1",
|
|
52
|
-
"sql.js": "^1.14.1",
|
|
53
|
-
"zod": "^4.4.3"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@haaaiawd/second-nature",
|
|
3
|
+
"version": "0.1.39",
|
|
4
|
+
"description": "OpenClaw native plugin with synchronous registration, a packaged runtime artifact, and operator-facing status/explain flows.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"openclaw",
|
|
7
|
+
"plugin",
|
|
8
|
+
"agent",
|
|
9
|
+
"continuity",
|
|
10
|
+
"quiet",
|
|
11
|
+
"memory",
|
|
12
|
+
"observability",
|
|
13
|
+
"operator"
|
|
14
|
+
],
|
|
15
|
+
"license": "Apache-2.0",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "./index.js",
|
|
18
|
+
"files": [
|
|
19
|
+
"index.js",
|
|
20
|
+
"workspace-ops-bridge.js",
|
|
21
|
+
"openclaw.plugin.json",
|
|
22
|
+
"SKILL.md",
|
|
23
|
+
"agent-inner-guide.md",
|
|
24
|
+
"runtime/"
|
|
25
|
+
],
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"openclaw": {
|
|
30
|
+
"manifest": "./openclaw.plugin.json",
|
|
31
|
+
"extensions": [
|
|
32
|
+
"./index.js"
|
|
33
|
+
],
|
|
34
|
+
"runtimeExtensions": [
|
|
35
|
+
"./index.js"
|
|
36
|
+
],
|
|
37
|
+
"compat": {
|
|
38
|
+
"pluginApi": ">=2026.5.12"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"openclaw": ">=2026.5.12"
|
|
43
|
+
},
|
|
44
|
+
"peerDependenciesMeta": {
|
|
45
|
+
"openclaw": {
|
|
46
|
+
"optional": true
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"drizzle-orm": "^0.45.2",
|
|
51
|
+
"js-yaml": "^4.1.1",
|
|
52
|
+
"sql.js": "^1.14.1",
|
|
53
|
+
"zod": "^4.4.3"
|
|
54
|
+
}
|
|
55
|
+
}
|
package/runtime/cli/index.js
CHANGED
|
@@ -186,9 +186,9 @@ function createSecretAnchorDeps(stateDb) {
|
|
|
186
186
|
},
|
|
187
187
|
credentialPort: {
|
|
188
188
|
verifySampleDecrypt: async () => {
|
|
189
|
-
const result = stateDb.sqlite.exec(`SELECT platform_id, encrypted_value
|
|
190
|
-
FROM credential_records
|
|
191
|
-
WHERE encrypted_value IS NOT NULL AND encrypted_value != ''
|
|
189
|
+
const result = stateDb.sqlite.exec(`SELECT platform_id, encrypted_value
|
|
190
|
+
FROM credential_records
|
|
191
|
+
WHERE encrypted_value IS NOT NULL AND encrypted_value != ''
|
|
192
192
|
LIMIT 3`);
|
|
193
193
|
if (result.length === 0 || result[0].values.length === 0) {
|
|
194
194
|
return { status: "ok", checkedIds: [] };
|
|
@@ -1,54 +1,75 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Stable HeartbeatSurfaceResult for second_nature_ops / CLI (T1.1.3, cli-system / ADR-005).
|
|
3
|
-
*
|
|
4
|
-
* S1 scope: carrier / probe / runtime-unavailable / fake control-plane passthrough only.
|
|
5
|
-
* Workspace full runtime: delegates to `runHeartbeatCycle` when read models are wired (US-001 / CH-09-02).
|
|
6
|
-
*/
|
|
7
|
-
import type { SurfaceMode } from "../runtime/runtime-artifact-boundary.js";
|
|
8
|
-
import type { HeartbeatSignal } from "../../core/second-nature/heartbeat/signal.js";
|
|
9
|
-
import type { CliReadModels } from "../read-models/index.js";
|
|
10
|
-
import type { RuntimeDecisionRecorder } from "../../observability/services/runtime-decision-recorder.js";
|
|
11
|
-
import type { StateDatabase } from "../../storage/db/index.js";
|
|
12
|
-
import type { ConnectorExecutor } from "../../core/second-nature/orchestrator/effect-dispatcher.js";
|
|
13
|
-
import type { CapabilityContractRegistry } from "../../connectors/base/manifest.js";
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Stable HeartbeatSurfaceResult for second_nature_ops / CLI (T1.1.3, cli-system / ADR-005).
|
|
3
|
+
*
|
|
4
|
+
* S1 scope: carrier / probe / runtime-unavailable / fake control-plane passthrough only.
|
|
5
|
+
* Workspace full runtime: delegates to `runHeartbeatCycle` when read models are wired (US-001 / CH-09-02).
|
|
6
|
+
*/
|
|
7
|
+
import type { SurfaceMode } from "../runtime/runtime-artifact-boundary.js";
|
|
8
|
+
import type { HeartbeatSignal } from "../../core/second-nature/heartbeat/signal.js";
|
|
9
|
+
import type { CliReadModels } from "../read-models/index.js";
|
|
10
|
+
import type { RuntimeDecisionRecorder } from "../../observability/services/runtime-decision-recorder.js";
|
|
11
|
+
import type { StateDatabase } from "../../storage/db/index.js";
|
|
12
|
+
import type { ConnectorExecutor } from "../../core/second-nature/orchestrator/effect-dispatcher.js";
|
|
13
|
+
import type { CapabilityContractRegistry } from "../../connectors/base/manifest.js";
|
|
14
|
+
import type { AffordanceMap } from "../../shared/types/v7-entities.js";
|
|
15
|
+
import type { ExperienceWriter } from "../../core/second-nature/body/tool-experience/experience-writer.js";
|
|
16
|
+
import type { QuietDreamSchedulePort } from "../../core/second-nature/quiet/run-source-backed-quiet.js";
|
|
17
|
+
import type { HeartbeatDigestAssemblerDeps } from "../../observability/services/heartbeat-digest-assembler.js";
|
|
18
|
+
export type HeartbeatSurfaceStatus = "heartbeat_ok" | "intent_selected" | "denied" | "deferred" | "runtime_carrier_only" | "delivery_unavailable";
|
|
19
|
+
export interface HeartbeatSurfaceResult {
|
|
20
|
+
ok: boolean;
|
|
21
|
+
status: HeartbeatSurfaceStatus;
|
|
22
|
+
surfaceMode: SurfaceMode;
|
|
23
|
+
decisionId?: string;
|
|
24
|
+
deliveryAttemptId?: string;
|
|
25
|
+
capabilityReportRef?: string;
|
|
26
|
+
fallbackRef?: string;
|
|
27
|
+
reasons: string[];
|
|
28
|
+
/** When false, callers must not treat the round as lived-experience loop completion */
|
|
29
|
+
livedExperienceLoopClaimed: boolean;
|
|
30
|
+
/** True when structured fields mirror a fake adapter for schema parity only */
|
|
31
|
+
schemaParityOnly?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface HeartbeatCheckInput {
|
|
34
|
+
probeOnly?: boolean;
|
|
35
|
+
runtimeAvailable: boolean;
|
|
36
|
+
fakeControlPlanePassthrough?: Record<string, unknown>;
|
|
37
|
+
/** When set, full-runtime heartbeat_check runs the control-plane decision loop (US-001). */
|
|
38
|
+
readModels?: CliReadModels;
|
|
39
|
+
/** When set, full-runtime cycles are persisted so `loadStatus` exits unknown (T1.2.3). */
|
|
40
|
+
runtimeRecorder?: RuntimeDecisionRecorder;
|
|
41
|
+
/**
|
|
42
|
+
* T2.2.2: when set together with `workspaceRoot`, life evidence from the state DB is loaded
|
|
43
|
+
* and merged into SnapshotInputs so planner/guard paths see real source-ref truth.
|
|
44
|
+
*/
|
|
45
|
+
state?: StateDatabase;
|
|
46
|
+
workspaceRoot?: string;
|
|
47
|
+
timestamp?: string;
|
|
48
|
+
sessionContext?: string;
|
|
49
|
+
scopeHint?: HeartbeatSignal["scopeHint"];
|
|
50
|
+
/**
|
|
51
|
+
* When present, guard-allowed connector_action intents are dispatched through the
|
|
52
|
+
* connector-system instead of returning connector_dispatch_unwired.
|
|
53
|
+
*/
|
|
54
|
+
connectorExecutor?: ConnectorExecutor;
|
|
55
|
+
/** Capability registry used by planner to avoid platform/capability protocol mismatches. */
|
|
56
|
+
connectorRegistry?: CapabilityContractRegistry;
|
|
57
|
+
/** v7 T-V7C.C.2: affordance map for breaker-aware guard evaluation. */
|
|
58
|
+
affordanceMap?: AffordanceMap;
|
|
59
|
+
/** v7 T-V7C.C.2: experience writer for heartbeat connector attempts. */
|
|
60
|
+
experienceWriter?: ExperienceWriter;
|
|
61
|
+
/**
|
|
62
|
+
* v7 T-V7C.C.6: when present, a successful Quiet write auto-triggers Dream scheduling.
|
|
63
|
+
* Fixes the production-data gap where dream_output_index does not grow after Quiet.
|
|
64
|
+
*/
|
|
65
|
+
dreamSchedulePort?: QuietDreamSchedulePort;
|
|
66
|
+
/**
|
|
67
|
+
* v7 T-V7C.C.6: when present, generates a HeartbeatDigest after each cycle.
|
|
68
|
+
* Fixes the production-data gap where heartbeat_digest does not grow.
|
|
69
|
+
*/
|
|
70
|
+
digestOpts?: {
|
|
71
|
+
assemblerDeps: HeartbeatDigestAssemblerDeps;
|
|
72
|
+
digestWindowHour?: number;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export declare function heartbeatCheck(input: HeartbeatCheckInput): Promise<HeartbeatSurfaceResult>;
|
|
@@ -1,81 +1,97 @@
|
|
|
1
|
-
import { createWorkspaceHeartbeatRunner } from "./workspace-heartbeat-runner.js";
|
|
2
|
-
function mapCycleToSurface(cycle, surfaceMode) {
|
|
3
|
-
const status = cycle.status === "runtime_carrier_only"
|
|
4
|
-
? "runtime_carrier_only"
|
|
5
|
-
: cycle.status;
|
|
6
|
-
return {
|
|
7
|
-
ok: true,
|
|
8
|
-
status,
|
|
9
|
-
surfaceMode,
|
|
10
|
-
decisionId: cycle.decisionId,
|
|
11
|
-
deliveryAttemptId: cycle.deliveryAttemptId,
|
|
12
|
-
fallbackRef: cycle.fallbackRef,
|
|
13
|
-
reasons: cycle.reasons,
|
|
14
|
-
livedExperienceLoopClaimed: false,
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
export async function heartbeatCheck(input) {
|
|
18
|
-
if (!input.runtimeAvailable) {
|
|
19
|
-
return {
|
|
20
|
-
ok: true,
|
|
21
|
-
status: "runtime_carrier_only",
|
|
22
|
-
surfaceMode: "host_safe_carrier",
|
|
23
|
-
reasons: ["runtime_unavailable_packaged_carrier"],
|
|
24
|
-
livedExperienceLoopClaimed: false,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
if (input.probeOnly) {
|
|
28
|
-
return {
|
|
29
|
-
ok: true,
|
|
30
|
-
status: "heartbeat_ok",
|
|
31
|
-
surfaceMode: "capability_probe",
|
|
32
|
-
reasons: ["probe_only"],
|
|
33
|
-
livedExperienceLoopClaimed: false,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
if (input.fakeControlPlanePassthrough) {
|
|
37
|
-
const decisionId = typeof input.fakeControlPlanePassthrough.decisionId === "string"
|
|
38
|
-
? input.fakeControlPlanePassthrough.decisionId
|
|
39
|
-
: undefined;
|
|
40
|
-
return {
|
|
41
|
-
ok: true,
|
|
42
|
-
status: "intent_selected",
|
|
43
|
-
surfaceMode: "host_safe_carrier",
|
|
44
|
-
reasons: ["fake_control_plane_passthrough"],
|
|
45
|
-
decisionId,
|
|
46
|
-
livedExperienceLoopClaimed: false,
|
|
47
|
-
schemaParityOnly: true,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
if (!input.readModels) {
|
|
51
|
-
return {
|
|
52
|
-
ok: true,
|
|
53
|
-
status: "runtime_carrier_only",
|
|
54
|
-
surfaceMode: "host_safe_carrier",
|
|
55
|
-
reasons: ["heartbeat_read_models_unavailable"],
|
|
56
|
-
livedExperienceLoopClaimed: false,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
const timestamp = typeof input.timestamp === "string" && input.timestamp.trim().length > 0
|
|
60
|
-
? input.timestamp.trim()
|
|
61
|
-
: new Date().toISOString();
|
|
62
|
-
const signal = {
|
|
63
|
-
trigger: "heartbeat_bridge",
|
|
64
|
-
scopeHint: input.scopeHint,
|
|
65
|
-
payload: {
|
|
66
|
-
timestamp,
|
|
67
|
-
sessionContext: typeof input.sessionContext === "string"
|
|
68
|
-
? input.sessionContext
|
|
69
|
-
: undefined,
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
const run = createWorkspaceHeartbeatRunner(input.readModels, {
|
|
73
|
-
runtimeRecorder: input.runtimeRecorder,
|
|
74
|
-
state: input.state,
|
|
75
|
-
workspaceRoot: input.workspaceRoot ?? process.cwd(),
|
|
76
|
-
connectorExecutor: input.connectorExecutor,
|
|
77
|
-
connectorRegistry: input.connectorRegistry,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
1
|
+
import { createWorkspaceHeartbeatRunner } from "./workspace-heartbeat-runner.js";
|
|
2
|
+
function mapCycleToSurface(cycle, surfaceMode) {
|
|
3
|
+
const status = cycle.status === "runtime_carrier_only"
|
|
4
|
+
? "runtime_carrier_only"
|
|
5
|
+
: cycle.status;
|
|
6
|
+
return {
|
|
7
|
+
ok: true,
|
|
8
|
+
status,
|
|
9
|
+
surfaceMode,
|
|
10
|
+
decisionId: cycle.decisionId,
|
|
11
|
+
deliveryAttemptId: cycle.deliveryAttemptId,
|
|
12
|
+
fallbackRef: cycle.fallbackRef,
|
|
13
|
+
reasons: cycle.reasons,
|
|
14
|
+
livedExperienceLoopClaimed: false,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export async function heartbeatCheck(input) {
|
|
18
|
+
if (!input.runtimeAvailable) {
|
|
19
|
+
return {
|
|
20
|
+
ok: true,
|
|
21
|
+
status: "runtime_carrier_only",
|
|
22
|
+
surfaceMode: "host_safe_carrier",
|
|
23
|
+
reasons: ["runtime_unavailable_packaged_carrier"],
|
|
24
|
+
livedExperienceLoopClaimed: false,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (input.probeOnly) {
|
|
28
|
+
return {
|
|
29
|
+
ok: true,
|
|
30
|
+
status: "heartbeat_ok",
|
|
31
|
+
surfaceMode: "capability_probe",
|
|
32
|
+
reasons: ["probe_only"],
|
|
33
|
+
livedExperienceLoopClaimed: false,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
if (input.fakeControlPlanePassthrough) {
|
|
37
|
+
const decisionId = typeof input.fakeControlPlanePassthrough.decisionId === "string"
|
|
38
|
+
? input.fakeControlPlanePassthrough.decisionId
|
|
39
|
+
: undefined;
|
|
40
|
+
return {
|
|
41
|
+
ok: true,
|
|
42
|
+
status: "intent_selected",
|
|
43
|
+
surfaceMode: "host_safe_carrier",
|
|
44
|
+
reasons: ["fake_control_plane_passthrough"],
|
|
45
|
+
decisionId,
|
|
46
|
+
livedExperienceLoopClaimed: false,
|
|
47
|
+
schemaParityOnly: true,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (!input.readModels) {
|
|
51
|
+
return {
|
|
52
|
+
ok: true,
|
|
53
|
+
status: "runtime_carrier_only",
|
|
54
|
+
surfaceMode: "host_safe_carrier",
|
|
55
|
+
reasons: ["heartbeat_read_models_unavailable"],
|
|
56
|
+
livedExperienceLoopClaimed: false,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const timestamp = typeof input.timestamp === "string" && input.timestamp.trim().length > 0
|
|
60
|
+
? input.timestamp.trim()
|
|
61
|
+
: new Date().toISOString();
|
|
62
|
+
const signal = {
|
|
63
|
+
trigger: "heartbeat_bridge",
|
|
64
|
+
scopeHint: input.scopeHint,
|
|
65
|
+
payload: {
|
|
66
|
+
timestamp,
|
|
67
|
+
sessionContext: typeof input.sessionContext === "string"
|
|
68
|
+
? input.sessionContext
|
|
69
|
+
: undefined,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
const run = createWorkspaceHeartbeatRunner(input.readModels, {
|
|
73
|
+
runtimeRecorder: input.runtimeRecorder,
|
|
74
|
+
state: input.state,
|
|
75
|
+
workspaceRoot: input.workspaceRoot ?? process.cwd(),
|
|
76
|
+
connectorExecutor: input.connectorExecutor,
|
|
77
|
+
connectorRegistry: input.connectorRegistry,
|
|
78
|
+
affordanceMap: input.affordanceMap,
|
|
79
|
+
experienceWriter: input.experienceWriter,
|
|
80
|
+
dreamSchedulePort: input.dreamSchedulePort,
|
|
81
|
+
digestOpts: input.digestOpts,
|
|
82
|
+
});
|
|
83
|
+
try {
|
|
84
|
+
const cycle = await run(signal);
|
|
85
|
+
return mapCycleToSurface(cycle, "workspace_full_runtime");
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
89
|
+
return {
|
|
90
|
+
ok: false,
|
|
91
|
+
status: "denied",
|
|
92
|
+
surfaceMode: "workspace_full_runtime",
|
|
93
|
+
reasons: [`heartbeat_cycle_exception:${msg.slice(0, 120)}`],
|
|
94
|
+
livedExperienceLoopClaimed: false,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|