@xemahq/agent-session-runtime 0.6.5 → 0.6.7
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/LICENSE +176 -175
- package/dist/lib/agent-workspace-manifest.d.ts.map +1 -1
- package/dist/lib/agent-workspace-manifest.js +1 -1
- package/dist/lib/agent-workspace-manifest.js.map +1 -1
- package/dist/lib/composition-resolution.d.ts +43 -0
- package/dist/lib/composition-resolution.d.ts.map +1 -0
- package/dist/lib/composition-resolution.js +236 -0
- package/dist/lib/composition-resolution.js.map +1 -0
- package/dist/lib/composition-workspace-manifest.d.ts +51 -0
- package/dist/lib/composition-workspace-manifest.d.ts.map +1 -0
- package/dist/lib/composition-workspace-manifest.js +178 -0
- package/dist/lib/composition-workspace-manifest.js.map +1 -0
- package/dist/lib/lifecycle-state.d.ts +2 -22
- package/dist/lib/lifecycle-state.d.ts.map +1 -1
- package/dist/lib/lifecycle-state.js +10 -67
- package/dist/lib/lifecycle-state.js.map +1 -1
- package/package.json +14 -3
- package/src/lib/agent-workspace-manifest.ts +15 -6
- package/src/lib/composer.ts +2 -2
- package/src/lib/drift-detector.ts +2 -2
- package/src/lib/environment-resolver.ts +3 -3
- package/src/lib/lifecycle-state.ts +25 -134
- package/src/lib/skill-bundle-template-resolver.ts +1 -1
- package/src/lib/types.ts +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
2
2
|
// ── Agent → CompiledWorkspaceManifest reconstruction ──
|
|
3
3
|
//
|
|
4
|
-
//
|
|
4
|
+
// The composer turns a
|
|
5
5
|
// `CompiledWorkspaceManifest` into a `WorkspaceMountPlan`; before this
|
|
6
6
|
// module the only way to obtain that compiled manifest was to fetch the
|
|
7
7
|
// `WorkspaceManifest` row from `workspace-manifests-api` and run
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
type ManifestSeedFile,
|
|
48
48
|
type ManifestSubAgent,
|
|
49
49
|
type ManifestWorkingFile,
|
|
50
|
-
type
|
|
50
|
+
type AgentWorkspaceSpec as DslWorkspaceManifest,
|
|
51
51
|
type WorkspaceManifestSpec,
|
|
52
52
|
} from '@xemahq/dsl/workspace-manifest';
|
|
53
53
|
|
|
@@ -359,10 +359,19 @@ export function compileAgentWorkspaceManifest(
|
|
|
359
359
|
metadata: {
|
|
360
360
|
slug,
|
|
361
361
|
version,
|
|
362
|
-
//
|
|
363
|
-
//
|
|
364
|
-
//
|
|
365
|
-
|
|
362
|
+
// A manifest RECONSTRUCTED from a bare `agentRef` carries no inherent
|
|
363
|
+
// surface restriction — the SAME agent (e.g. `demo-runner`,
|
|
364
|
+
// `requirements-coordinator`) is legitimately driven on BOTH the
|
|
365
|
+
// agent-session surface (interactive bootstrap) AND the workflow surface
|
|
366
|
+
// (pipeline `xema/agent@v1` jobs). Defaulting to AGENT_SESSION only made
|
|
367
|
+
// every workflow agent run fail `assertSurfaceCompat` with
|
|
368
|
+
// "surfaceCompat=[agent-session] but was resolved on 'workflow'". Mirror
|
|
369
|
+
// the DSL compiler's permissive `DEFAULT_SURFACE_COMPAT` ([workflow,
|
|
370
|
+
// agent-session]); the runtime EnvironmentResolver still re-asserts the
|
|
371
|
+
// ACTUAL surface, so widening the reconstructed set cannot let an agent
|
|
372
|
+
// run somewhere its real manifest forbids — an authored manifest that
|
|
373
|
+
// explicitly narrows `surfaceCompat` is parsed via the DSL path, not here.
|
|
374
|
+
surfaceCompat: [ManifestSurface.WORKFLOW, ManifestSurface.AGENT_SESSION],
|
|
366
375
|
},
|
|
367
376
|
spec,
|
|
368
377
|
};
|
package/src/lib/composer.ts
CHANGED
|
@@ -328,8 +328,8 @@ export class DefaultWorkspaceImageComposer implements WorkspaceImageComposer {
|
|
|
328
328
|
// `/<skillKey>` in a session loads and applies that skill natively.
|
|
329
329
|
//
|
|
330
330
|
// Kernel-shipped System skills are PREPENDED to whatever skills the
|
|
331
|
-
// caller already named in `agentContext.skills` (
|
|
332
|
-
//
|
|
331
|
+
// caller already named in `agentContext.skills` (per the skill
|
|
332
|
+
// composition rules — `SkillSpace.System`
|
|
333
333
|
// skills are auto-injected into every agent's mounted bundle).
|
|
334
334
|
// `dedupe` collapses any overlap so a caller that re-mentions a
|
|
335
335
|
// System skill in `agentContext.skills` does not double-mount it.
|
|
@@ -57,8 +57,8 @@ export enum DriftKind {
|
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* Advisory drift severity — `info` (benign) or `warning` (worth a look).
|
|
60
|
-
* There is deliberately no `critical`: resume is non-blocking by design
|
|
61
|
-
*
|
|
60
|
+
* There is deliberately no `critical`: resume is non-blocking by design,
|
|
61
|
+
* so severity only drives how the operator's drift
|
|
62
62
|
* toast renders, never whether the session resumes.
|
|
63
63
|
*/
|
|
64
64
|
export type DriftSeverity = 'info' | 'warning';
|
|
@@ -124,7 +124,7 @@ export interface EnvironmentResolverRequest {
|
|
|
124
124
|
*/
|
|
125
125
|
readonly systemSkillSlugs?: readonly string[];
|
|
126
126
|
/**
|
|
127
|
-
* Optional MCP stanza resolver
|
|
127
|
+
* Optional MCP stanza resolver. Translates the manifest's
|
|
128
128
|
* `toolSelection` into a `mcpServers` map suitable for direct write
|
|
129
129
|
* into `opencode.jsonc:mcp`. When absent, the resolved environment
|
|
130
130
|
* carries no MCP stanzas — appropriate for workflow surfaces today
|
|
@@ -205,7 +205,7 @@ export interface ResolvedEnvironment {
|
|
|
205
205
|
readonly mountPlan: WorkspaceMountPlan;
|
|
206
206
|
readonly env: readonly { readonly name: string; readonly value: string }[];
|
|
207
207
|
/**
|
|
208
|
-
*
|
|
208
|
+
* Resolved `mcpServers` map ready to drop into
|
|
209
209
|
* `opencode.jsonc:mcp`. Empty `{}` when the manifest declares no
|
|
210
210
|
* toolSelection or when the request omits an `mcpResolver`. Keeps
|
|
211
211
|
* the snapshot self-contained so downstream callers (workflow
|
|
@@ -279,7 +279,7 @@ export class DefaultEnvironmentResolver implements EnvironmentResolver {
|
|
|
279
279
|
req.briefcase?.mcpTools,
|
|
280
280
|
);
|
|
281
281
|
|
|
282
|
-
//
|
|
282
|
+
// Capability federation. When an `mcpResolver` is wired
|
|
283
283
|
// (session-boot, workflow-runtime-worker) the resolver ALWAYS runs —
|
|
284
284
|
// the returned stanza is the fixed three meta-tool surface
|
|
285
285
|
// (`xema-capabilities-{list,describe,invoke}`), regardless of
|
|
@@ -1,139 +1,30 @@
|
|
|
1
1
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
-
// ── Agent-session lifecycle state machine ──
|
|
2
|
+
// ── Agent-session lifecycle state machine — re-export of the kernel SSOT ──
|
|
3
3
|
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
4
|
+
// This file is a thin re-export surface. The closed `SessionLifecycleState` /
|
|
5
|
+
// `SessionOwnerKind` value sets, the transition FSM (`canTransition`), and the
|
|
6
|
+
// `isTerminal` / `isPausable` / `isResumable` predicates are the canonical
|
|
7
|
+
// Layer-0 contract owned by `@xemahq/kernel-contracts/agent-session`. The former
|
|
8
|
+
// hand-maintained copy that lived here was collapsed into that single source of
|
|
9
|
+
// truth; this module is retained ONLY so the package's public surface
|
|
10
|
+
// (re-exported from `src/index.ts`) is unchanged.
|
|
8
11
|
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
// call so misuse fails fast at compile time rather than as a 409 from
|
|
13
|
-
// the service.
|
|
12
|
+
// Prisma cannot import a TS value, so the agent-session-api schema re-declares
|
|
13
|
+
// the same members and CI guards parity
|
|
14
|
+
// (`tooling/boundaries/check-session-enum-parity.mjs`).
|
|
14
15
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
} as const;
|
|
31
|
-
|
|
32
|
-
export type SessionLifecycleStateValue =
|
|
33
|
-
(typeof SessionLifecycleState)[keyof typeof SessionLifecycleState];
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Who created the session row. Mirrors the persisted `SessionOwnerKind`.
|
|
37
|
-
*
|
|
38
|
-
* - `interactive_session` — user-facing chat sessions
|
|
39
|
-
* - `pipeline_run` — workflow-runtime-worker redraft loop spines
|
|
40
|
-
* - `chat_thread` — reserved (no dispatcher today)
|
|
41
|
-
*
|
|
42
|
-
* The CI enum-parity check verifies this stays in lockstep with the
|
|
43
|
-
* persisted enum.
|
|
44
|
-
*/
|
|
45
|
-
export const SessionOwnerKind = {
|
|
46
|
-
interactive_session: 'interactive_session',
|
|
47
|
-
pipeline_run: 'pipeline_run',
|
|
48
|
-
chat_thread: 'chat_thread',
|
|
49
|
-
} as const;
|
|
50
|
-
|
|
51
|
-
export type SessionOwnerKindValue =
|
|
52
|
-
(typeof SessionOwnerKind)[keyof typeof SessionOwnerKind];
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Per-state transition matrix. `canTransition(from, to)` returns true
|
|
56
|
-
* iff the transition is valid.
|
|
57
|
-
*
|
|
58
|
-
* Notable transitions:
|
|
59
|
-
* - `paused → recovering` (resume claim)
|
|
60
|
-
* - `recovering → active` (resume success)
|
|
61
|
-
* - `recovering → paused` (resume rollback)
|
|
62
|
-
* - `active → completing → completed` (terminal success)
|
|
63
|
-
* - any-non-terminal → `failed` (terminal failure)
|
|
64
|
-
* - `paused | completed | failed → archived` (cleanup sweep)
|
|
65
|
-
*/
|
|
66
|
-
const TRANSITIONS: Readonly<
|
|
67
|
-
Record<SessionLifecycleStateValue, ReadonlySet<SessionLifecycleStateValue>>
|
|
68
|
-
> = {
|
|
69
|
-
creating: new Set([
|
|
70
|
-
SessionLifecycleState.provisioning,
|
|
71
|
-
SessionLifecycleState.failed,
|
|
72
|
-
]),
|
|
73
|
-
provisioning: new Set([
|
|
74
|
-
SessionLifecycleState.active,
|
|
75
|
-
SessionLifecycleState.failed,
|
|
76
|
-
]),
|
|
77
|
-
active: new Set([
|
|
78
|
-
SessionLifecycleState.paused,
|
|
79
|
-
SessionLifecycleState.completing,
|
|
80
|
-
SessionLifecycleState.failed,
|
|
81
|
-
]),
|
|
82
|
-
paused: new Set([
|
|
83
|
-
SessionLifecycleState.recovering,
|
|
84
|
-
SessionLifecycleState.archived,
|
|
85
|
-
SessionLifecycleState.failed,
|
|
86
|
-
]),
|
|
87
|
-
recovering: new Set([
|
|
88
|
-
SessionLifecycleState.active,
|
|
89
|
-
SessionLifecycleState.paused,
|
|
90
|
-
SessionLifecycleState.failed,
|
|
91
|
-
]),
|
|
92
|
-
completing: new Set([
|
|
93
|
-
SessionLifecycleState.completed,
|
|
94
|
-
SessionLifecycleState.failed,
|
|
95
|
-
]),
|
|
96
|
-
completed: new Set([SessionLifecycleState.archived]),
|
|
97
|
-
failed: new Set([SessionLifecycleState.archived]),
|
|
98
|
-
archived: new Set(),
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
export function canTransition(
|
|
102
|
-
from: SessionLifecycleStateValue,
|
|
103
|
-
to: SessionLifecycleStateValue,
|
|
104
|
-
): boolean {
|
|
105
|
-
return TRANSITIONS[from].has(to);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Terminal states — no further transitions possible (except the
|
|
110
|
-
* `completed | failed → archived` cleanup sweep). Callers use this to
|
|
111
|
-
* short-circuit "is this session done?" checks.
|
|
112
|
-
*/
|
|
113
|
-
export function isTerminal(state: SessionLifecycleStateValue): boolean {
|
|
114
|
-
return (
|
|
115
|
-
state === SessionLifecycleState.completed ||
|
|
116
|
-
state === SessionLifecycleState.failed ||
|
|
117
|
-
state === SessionLifecycleState.archived
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Pausable states — the session has a live worker that can be told to
|
|
123
|
-
* snapshot. `provisioning` is intentionally excluded: the worker isn't
|
|
124
|
-
* ready yet, so a pause request would 409. Callers receiving such a
|
|
125
|
-
* 409 should retry with backoff once `active` is reached.
|
|
126
|
-
*/
|
|
127
|
-
export function isPausable(state: SessionLifecycleStateValue): boolean {
|
|
128
|
-
return state === SessionLifecycleState.active;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Resumable states. `paused` is the canonical case. `failed` rows are
|
|
133
|
-
* NOT resumable from here — they require explicit operator action
|
|
134
|
-
* (the resume API would 409). `recovering` is a transient state owned
|
|
135
|
-
* by an in-flight resume; another caller observing it should back off.
|
|
136
|
-
*/
|
|
137
|
-
export function isResumable(state: SessionLifecycleStateValue): boolean {
|
|
138
|
-
return state === SessionLifecycleState.paused;
|
|
139
|
-
}
|
|
17
|
+
export {
|
|
18
|
+
SessionLifecycleState,
|
|
19
|
+
SessionOwnerKind,
|
|
20
|
+
canTransition,
|
|
21
|
+
isTerminal,
|
|
22
|
+
isPausable,
|
|
23
|
+
isResumable,
|
|
24
|
+
SessionLifecycleStateSchema,
|
|
25
|
+
SessionOwnerKindSchema,
|
|
26
|
+
} from '@xemahq/kernel-contracts/agent-session';
|
|
27
|
+
export type {
|
|
28
|
+
SessionLifecycleStateValue,
|
|
29
|
+
SessionOwnerKindValue,
|
|
30
|
+
} from '@xemahq/kernel-contracts/agent-session';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
2
2
|
// ── Skill-bundle-backed TemplateResolver ──
|
|
3
3
|
//
|
|
4
|
-
//
|
|
4
|
+
// Seed-file templates used to
|
|
5
5
|
// live in `workspace-manifests-api` (the `workspace_manifest_templates` table)
|
|
6
6
|
// and were fetched by name. They are now SKILL-BUNDLE RESOURCES served by
|
|
7
7
|
// `skill-registry-api` (`GET /skills/bundle`): a biome that ships templates
|
package/src/lib/types.ts
CHANGED
|
@@ -69,7 +69,7 @@ export interface ComposeWorkspaceImageRequest {
|
|
|
69
69
|
readonly templateResolver?: TemplateResolver;
|
|
70
70
|
/**
|
|
71
71
|
* Kernel-shipped System-scope skill slugs to PREPEND to the composer's
|
|
72
|
-
* mounted skill set. Per
|
|
72
|
+
* mounted skill set. Per the skill composition rules,
|
|
73
73
|
* skills owned by `SkillSpace.System` are auto-injected into every
|
|
74
74
|
* agent's mounted bundle — they ship from `@xemahq/system-skills`
|
|
75
75
|
* via the System-tier seeder in `skill-registry-api`. The caller
|