@lumenflow/cli 3.17.7 → 3.18.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 +44 -43
- package/dist/chunk-2D2VOCA4.js +37 -0
- package/dist/chunk-2D5KFYGX.js +284 -0
- package/dist/chunk-2GXVIN57.js +14072 -0
- package/dist/chunk-2MQ7HZWZ.js +26 -0
- package/dist/chunk-2UFQ3A3C.js +643 -0
- package/dist/chunk-3RG5ZIWI.js +10 -0
- package/dist/chunk-4N74J3UT.js +15 -0
- package/dist/chunk-5GTOXFYR.js +392 -0
- package/dist/chunk-5VY6MQMC.js +240 -0
- package/dist/chunk-67XVPMRY.js +1297 -0
- package/dist/chunk-6HO4GWJE.js +164 -0
- package/dist/chunk-6W5XHWYV.js +1890 -0
- package/dist/chunk-6X4EMYJQ.js +64 -0
- package/dist/chunk-6XYXI2NQ.js +772 -0
- package/dist/chunk-7ANSOV6Q.js +285 -0
- package/dist/chunk-A624LFLB.js +1380 -0
- package/dist/chunk-ADN5NHG4.js +126 -0
- package/dist/chunk-B7YJYJKG.js +33 -0
- package/dist/chunk-CCLHCPKG.js +210 -0
- package/dist/chunk-CK36VROC.js +1584 -0
- package/dist/chunk-D3UOFRSB.js +81 -0
- package/dist/chunk-DFR4DJBM.js +230 -0
- package/dist/chunk-DSYBDHYH.js +79 -0
- package/dist/chunk-DWMLTXKQ.js +1176 -0
- package/dist/chunk-E3REJTAJ.js +28 -0
- package/dist/chunk-EA3IVO64.js +633 -0
- package/dist/chunk-EK2AKZKD.js +55 -0
- package/dist/chunk-ELD7JTTT.js +343 -0
- package/dist/chunk-EX6TT2XI.js +195 -0
- package/dist/chunk-EXINSFZE.js +82 -0
- package/dist/chunk-EZ6ZBYBM.js +510 -0
- package/dist/chunk-FBKAPTJ2.js +16 -0
- package/dist/chunk-FVLV5RYH.js +1118 -0
- package/dist/chunk-GDNSBQVK.js +2485 -0
- package/dist/chunk-GPQHMBNN.js +278 -0
- package/dist/chunk-GTFJB67L.js +68 -0
- package/dist/chunk-HANJXVKW.js +1127 -0
- package/dist/chunk-HEVS5YLD.js +269 -0
- package/dist/chunk-HMEVZKPQ.js +9 -0
- package/dist/chunk-HRGSYNLM.js +3511 -0
- package/dist/chunk-ISZR5N4K.js +60 -0
- package/dist/chunk-J6SUPR2C.js +226 -0
- package/dist/chunk-JERYVEIZ.js +244 -0
- package/dist/chunk-JHHWGL2N.js +87 -0
- package/dist/chunk-JONWQUB5.js +775 -0
- package/dist/chunk-K2DIWWDM.js +1766 -0
- package/dist/chunk-KY4PGL5V.js +969 -0
- package/dist/chunk-L737LQ4C.js +1285 -0
- package/dist/chunk-LFTWYIB2.js +497 -0
- package/dist/chunk-LV47RFNJ.js +41 -0
- package/dist/chunk-MKSAITI7.js +15 -0
- package/dist/chunk-MZ7RKIX4.js +212 -0
- package/dist/chunk-NAP6CFSO.js +84 -0
- package/dist/chunk-ND6MY37M.js +16 -0
- package/dist/chunk-NMG736UR.js +683 -0
- package/dist/chunk-NRAXROED.js +32 -0
- package/dist/chunk-NRIZR3A7.js +690 -0
- package/dist/chunk-NX43BG3M.js +233 -0
- package/dist/chunk-O645XLSI.js +297 -0
- package/dist/chunk-OMJD6A3S.js +235 -0
- package/dist/chunk-QB6SJD4T.js +430 -0
- package/dist/chunk-QFSTL4J3.js +276 -0
- package/dist/chunk-QLGDFMFX.js +212 -0
- package/dist/chunk-RIAAGL2E.js +13 -0
- package/dist/chunk-RWO5XMZ6.js +86 -0
- package/dist/chunk-RXRKBBSM.js +149 -0
- package/dist/chunk-RZOZMML6.js +363 -0
- package/dist/chunk-U7I7FS7T.js +113 -0
- package/dist/chunk-UI42RODY.js +717 -0
- package/dist/chunk-UTVMVSCO.js +519 -0
- package/dist/chunk-V6OJGLBA.js +1746 -0
- package/dist/chunk-W2JHVH7D.js +152 -0
- package/dist/chunk-WD3Y7VQN.js +280 -0
- package/dist/chunk-WOCTQ5MS.js +303 -0
- package/dist/chunk-WZR3ZUNN.js +696 -0
- package/dist/chunk-XGI665H7.js +150 -0
- package/dist/chunk-XKY65P2T.js +304 -0
- package/dist/chunk-Y4CQZY65.js +57 -0
- package/dist/chunk-YFEXKLVE.js +194 -0
- package/dist/chunk-YHO3HS5X.js +287 -0
- package/dist/chunk-YLS7AZSX.js +738 -0
- package/dist/chunk-ZE473AO6.js +49 -0
- package/dist/chunk-ZF747T3O.js +644 -0
- package/dist/chunk-ZHCZHZH3.js +43 -0
- package/dist/chunk-ZZNZX2XY.js +87 -0
- package/dist/config-set.js +10 -1
- package/dist/config-set.js.map +1 -1
- package/dist/constants-7QAP3VQ4.js +23 -0
- package/dist/dist-IY3UUMWK.js +33 -0
- package/dist/gate-co-change.js +5 -2
- package/dist/gate-co-change.js.map +1 -1
- package/dist/init-detection.js +5 -3
- package/dist/init-detection.js.map +1 -1
- package/dist/init-templates.js +4 -4
- package/dist/init-templates.js.map +1 -1
- package/dist/initiative-edit.js +8 -3
- package/dist/initiative-edit.js.map +1 -1
- package/dist/initiative-plan.js +1 -1
- package/dist/initiative-plan.js.map +1 -1
- package/dist/invariants-runner-W5RGHCSU.js +27 -0
- package/dist/lane-lock-6J36HD5O.js +35 -0
- package/dist/lumenflow-upgrade.js +49 -0
- package/dist/lumenflow-upgrade.js.map +1 -1
- package/dist/mem-checkpoint-core-EANG2GVN.js +14 -0
- package/dist/mem-signal-core-2LZ2WYHW.js +19 -0
- package/dist/memory-store-OLB5FO7K.js +18 -0
- package/dist/pre-commit-check.js +1 -1
- package/dist/pre-commit-check.js.map +1 -1
- package/dist/service-6BYCOCO5.js +13 -0
- package/dist/spawn-policy-resolver-NTSZYQ6R.js +17 -0
- package/dist/spawn-task-builder-R4E2BHSW.js +22 -0
- package/dist/wu-done-pr-WLFFFEPJ.js +25 -0
- package/dist/wu-done-validation-3J5E36FE.js +30 -0
- package/dist/wu-duplicate-id-detector-5S7JHELK.js +232 -0
- package/dist/wu-edit-operations.js +4 -0
- package/dist/wu-edit-operations.js.map +1 -1
- package/dist/wu-edit-validators.js +4 -0
- package/dist/wu-edit-validators.js.map +1 -1
- package/dist/wu-edit.js +11 -0
- package/dist/wu-edit.js.map +1 -1
- package/dist/wu-spawn-strategy-resolver.js +13 -1
- package/dist/wu-spawn-strategy-resolver.js.map +1 -1
- package/package.json +8 -8
- package/packs/agent-runtime/.turbo/turbo-build.log +4 -0
- package/packs/agent-runtime/README.md +147 -0
- package/packs/agent-runtime/capability-factory.ts +104 -0
- package/packs/agent-runtime/config.schema.json +87 -0
- package/packs/agent-runtime/constants.ts +21 -0
- package/packs/agent-runtime/index.ts +11 -0
- package/packs/agent-runtime/manifest.ts +207 -0
- package/packs/agent-runtime/manifest.yaml +193 -0
- package/packs/agent-runtime/orchestration.ts +1787 -0
- package/packs/agent-runtime/pack-registration.ts +110 -0
- package/packs/agent-runtime/package.json +57 -0
- package/packs/agent-runtime/policy-factory.ts +165 -0
- package/packs/agent-runtime/tool-impl/agent-turn-tools.ts +793 -0
- package/packs/agent-runtime/tool-impl/index.ts +5 -0
- package/packs/agent-runtime/tool-impl/provider-adapters.ts +1245 -0
- package/packs/agent-runtime/tools/index.ts +4 -0
- package/packs/agent-runtime/tools/types.ts +47 -0
- package/packs/agent-runtime/tsconfig.json +20 -0
- package/packs/agent-runtime/types.ts +128 -0
- package/packs/agent-runtime/vitest.config.ts +11 -0
- package/packs/sidekick/.turbo/turbo-build.log +1 -1
- package/packs/sidekick/.turbo/turbo-test.log +12 -0
- package/packs/sidekick/.turbo/turbo-typecheck.log +4 -0
- package/packs/sidekick/package.json +1 -1
- package/packs/software-delivery/.turbo/turbo-build.log +1 -1
- package/packs/software-delivery/.turbo/turbo-typecheck.log +4 -0
- package/packs/software-delivery/package.json +1 -1
- package/templates/core/.lumenflow/rules/wu-workflow.md.template +1 -1
- package/templates/core/ai/onboarding/first-wu-mistakes.md.template +2 -2
- package/templates/core/ai/onboarding/quick-ref-commands.md.template +1 -1
- package/templates/core/ai/onboarding/starting-prompt.md.template +1 -1
- package/templates/vendors/claude/.claude/skills/frontend-design/SKILL.md.template +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lumenflow/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.18.1",
|
|
4
4
|
"description": "Command-line interface for LumenFlow workflow framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lumenflow",
|
|
@@ -185,13 +185,13 @@
|
|
|
185
185
|
"xstate": "^5.28.0",
|
|
186
186
|
"yaml": "^2.8.2",
|
|
187
187
|
"zod": "^4.3.6",
|
|
188
|
-
"@lumenflow/agent": "3.
|
|
189
|
-
"@lumenflow/
|
|
190
|
-
"@lumenflow/
|
|
191
|
-
"@lumenflow/
|
|
192
|
-
"@lumenflow/
|
|
193
|
-
"@lumenflow/
|
|
194
|
-
"@lumenflow/
|
|
188
|
+
"@lumenflow/agent": "3.18.1",
|
|
189
|
+
"@lumenflow/memory": "3.18.1",
|
|
190
|
+
"@lumenflow/control-plane-sdk": "3.18.1",
|
|
191
|
+
"@lumenflow/core": "3.18.1",
|
|
192
|
+
"@lumenflow/metrics": "3.18.1",
|
|
193
|
+
"@lumenflow/initiatives": "3.18.1",
|
|
194
|
+
"@lumenflow/kernel": "3.18.1"
|
|
195
195
|
},
|
|
196
196
|
"devDependencies": {
|
|
197
197
|
"@vitest/coverage-v8": "^4.0.18",
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Agent Runtime Pack
|
|
2
|
+
|
|
3
|
+
The governed `agent-runtime` pack provides a host-driven agent loop with kernel-enforced tool gating.
|
|
4
|
+
|
|
5
|
+
Current scope:
|
|
6
|
+
|
|
7
|
+
- `agent:execute-turn` performs one provider-backed model turn and returns the governed turn contract
|
|
8
|
+
- `policy_factory` converts configured intents into kernel-enforced allow, deny, and `approval_required` rules
|
|
9
|
+
- `runGovernedAgentLoop()` shows how CLI, HTTP, or programmatic hosts can keep orchestration outside the pack while still feeding requested tools back through the kernel
|
|
10
|
+
- `startGovernedAgentSession()` and `resumeGovernedAgentSession()` persist linear session state for long-running governed turns
|
|
11
|
+
- `startGovernedAgentWorkflow()` and `resumeGovernedAgentWorkflow()` add pack-owned branch, join, and scheduled-wakeup orchestration inside the same `agent-session`
|
|
12
|
+
- `createHostContextMessages()` lets a host add task and memory context without depending on any other pack's storage internals
|
|
13
|
+
|
|
14
|
+
## Config shape
|
|
15
|
+
|
|
16
|
+
```yaml
|
|
17
|
+
agent_runtime:
|
|
18
|
+
default_model: default
|
|
19
|
+
models:
|
|
20
|
+
default:
|
|
21
|
+
provider: openai_compatible
|
|
22
|
+
model: demo-model
|
|
23
|
+
api_key_env: AGENT_RUNTIME_API_KEY
|
|
24
|
+
base_url_env: AGENT_RUNTIME_BASE_URL
|
|
25
|
+
intents:
|
|
26
|
+
scheduling:
|
|
27
|
+
description: Schedule or reschedule work
|
|
28
|
+
allow_tools:
|
|
29
|
+
- calendar:create-event
|
|
30
|
+
approval_required_tools:
|
|
31
|
+
- calendar:create-event
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Orchestration boundary
|
|
35
|
+
|
|
36
|
+
The kernel remains responsible for:
|
|
37
|
+
|
|
38
|
+
- tool execution
|
|
39
|
+
- policy evaluation
|
|
40
|
+
- scope enforcement
|
|
41
|
+
- evidence receipts for every governed tool call
|
|
42
|
+
|
|
43
|
+
The pack owns only `agent-session` orchestration concerns:
|
|
44
|
+
|
|
45
|
+
- persisted session and workflow state under `.agent-runtime/workflow/`
|
|
46
|
+
- branch and join readiness
|
|
47
|
+
- scheduled wakeups for routine-style follow-up nodes
|
|
48
|
+
- workflow-level continuation records that explain why the next governed turn ran
|
|
49
|
+
|
|
50
|
+
This keeps scheduled and resumed execution inside the existing `agent-session` task model rather than inventing a new execution class.
|
|
51
|
+
|
|
52
|
+
## Host loop sketch
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import {
|
|
56
|
+
createApprovalResolutionMessage,
|
|
57
|
+
createHostContextMessages,
|
|
58
|
+
runGovernedAgentLoop,
|
|
59
|
+
resumeGovernedAgentWorkflow,
|
|
60
|
+
startGovernedAgentWorkflow,
|
|
61
|
+
} from '@lumenflow/packs-agent-runtime';
|
|
62
|
+
|
|
63
|
+
const seedMessages = [
|
|
64
|
+
...createHostContextMessages({
|
|
65
|
+
task_summary: 'Reschedule the weekly review.',
|
|
66
|
+
memory_summary: 'The reviewer prefers mornings.',
|
|
67
|
+
}),
|
|
68
|
+
{ role: 'user', content: 'Please sort out the next slot.' },
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
const result = await runGovernedAgentLoop({
|
|
72
|
+
runtime,
|
|
73
|
+
executeTurnInput: {
|
|
74
|
+
session_id: executionContext.session_id,
|
|
75
|
+
model_profile: 'default',
|
|
76
|
+
url: 'https://model-provider.invalid/',
|
|
77
|
+
messages: seedMessages,
|
|
78
|
+
},
|
|
79
|
+
createContext: (metadata) => ({
|
|
80
|
+
...executionContext,
|
|
81
|
+
metadata,
|
|
82
|
+
}),
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
if (result.kind === 'approval_required') {
|
|
86
|
+
await runtime.resolveApproval({
|
|
87
|
+
request_id: result.pending_request_id,
|
|
88
|
+
approved: true,
|
|
89
|
+
approved_by: 'operator@example.com',
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const approvalMessage = createApprovalResolutionMessage({
|
|
93
|
+
requestId: result.pending_request_id,
|
|
94
|
+
approved: true,
|
|
95
|
+
approvedBy: 'operator@example.com',
|
|
96
|
+
toolName: result.requested_tool.name,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Append approvalMessage to the next execute-turn call and continue the loop.
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The pack keeps tool gating in the kernel. Hosts only decide when to start the loop, when to resolve approvals, and what external context to inject into the conversation.
|
|
104
|
+
|
|
105
|
+
## Workflow sketch
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
const workflow = await startGovernedAgentWorkflow({
|
|
109
|
+
runtime,
|
|
110
|
+
storageRoot: workspaceRoot,
|
|
111
|
+
workflow: {
|
|
112
|
+
session_id: executionContext.session_id,
|
|
113
|
+
nodes: [
|
|
114
|
+
{
|
|
115
|
+
id: 'collect',
|
|
116
|
+
execute_turn_input: {
|
|
117
|
+
session_id: executionContext.session_id,
|
|
118
|
+
model_profile: 'default',
|
|
119
|
+
url: 'https://model-provider.invalid/',
|
|
120
|
+
messages: [{ role: 'user', content: 'Collect the constraints.' }],
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: 'follow-up',
|
|
125
|
+
depends_on: ['collect'],
|
|
126
|
+
wake_at: '2026-03-13T09:00:00.000Z',
|
|
127
|
+
execute_turn_input: {
|
|
128
|
+
session_id: executionContext.session_id,
|
|
129
|
+
model_profile: 'default',
|
|
130
|
+
url: 'https://model-provider.invalid/',
|
|
131
|
+
messages: [{ role: 'user', content: 'Perform the scheduled follow-up.' }],
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
},
|
|
136
|
+
createContext: (metadata) => ({ ...executionContext, metadata }),
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
if (workflow.kind === 'scheduled') {
|
|
140
|
+
await resumeGovernedAgentWorkflow({
|
|
141
|
+
runtime,
|
|
142
|
+
storageRoot: workspaceRoot,
|
|
143
|
+
sessionId: executionContext.session_id,
|
|
144
|
+
createContext: (metadata) => ({ ...executionContext, metadata }),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
```
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
|
|
4
|
+
import type { PackCapabilityFactory } from '@lumenflow/kernel';
|
|
5
|
+
import { AGENT_RUNTIME_TOOL_NAMES } from './types.js';
|
|
6
|
+
import type { AgentRuntimeModelProfileConfig, AgentRuntimePackConfig } from './types.js';
|
|
7
|
+
|
|
8
|
+
export const createAgentRuntimeCapabilityFactory: PackCapabilityFactory = async (input) => {
|
|
9
|
+
if (input.tool.name !== AGENT_RUNTIME_TOOL_NAMES.EXECUTE_TURN) {
|
|
10
|
+
return {};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const packConfig = normalizePackConfig(input.packConfig);
|
|
14
|
+
if (!packConfig) {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const requiredEnv = new Set<string>();
|
|
19
|
+
const providerHosts = new Set<string>();
|
|
20
|
+
|
|
21
|
+
for (const [profileName, profile] of Object.entries(packConfig.models)) {
|
|
22
|
+
requiredEnv.add(profile.api_key_env);
|
|
23
|
+
if (profile.base_url_env) {
|
|
24
|
+
requiredEnv.add(profile.base_url_env);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const resolvedBaseUrl = resolveProfileBaseUrl(profileName, profile);
|
|
28
|
+
if (!resolvedBaseUrl) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
providerHosts.add(toNetworkAllowlistEntry(profileName, resolvedBaseUrl));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
...(requiredEnv.size > 0 ? { required_env: [...requiredEnv].sort() } : {}),
|
|
36
|
+
...(providerHosts.size > 0
|
|
37
|
+
? {
|
|
38
|
+
required_scopes: [
|
|
39
|
+
{
|
|
40
|
+
type: 'network' as const,
|
|
41
|
+
posture: 'allowlist' as const,
|
|
42
|
+
allowlist_entries: [...providerHosts].sort(),
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
}
|
|
46
|
+
: {}),
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
function normalizePackConfig(value: unknown): AgentRuntimePackConfig | null {
|
|
51
|
+
if (!isRecord(value) || !isRecord(value.models)) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return value as unknown as AgentRuntimePackConfig;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function resolveProfileBaseUrl(
|
|
59
|
+
profileName: string,
|
|
60
|
+
profile: AgentRuntimeModelProfileConfig,
|
|
61
|
+
): string | null {
|
|
62
|
+
if (typeof profile.base_url === 'string' && profile.base_url.trim().length > 0) {
|
|
63
|
+
return profile.base_url.trim();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!profile.base_url_env) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const environmentValue = process.env[profile.base_url_env];
|
|
71
|
+
if (typeof environmentValue !== 'string' || environmentValue.trim().length === 0) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
`agent_runtime.models.${profileName}.base_url_env references "${profile.base_url_env}" but it is not set.`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return environmentValue.trim();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function toNetworkAllowlistEntry(profileName: string, baseUrl: string): string {
|
|
81
|
+
let parsed: URL;
|
|
82
|
+
try {
|
|
83
|
+
parsed = new URL(baseUrl);
|
|
84
|
+
} catch (error) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
`agent_runtime.models.${profileName} must resolve to a valid absolute base URL, got "${baseUrl}".`,
|
|
87
|
+
{ cause: error },
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const port =
|
|
92
|
+
parsed.port || (parsed.protocol === 'https:' ? '443' : parsed.protocol === 'http:' ? '80' : '');
|
|
93
|
+
if (!port) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
`agent_runtime.models.${profileName} uses protocol "${parsed.protocol}" without an explicit port.`,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return `${parsed.hostname}:${port}`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
103
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
104
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "object",
|
|
3
|
+
"properties": {
|
|
4
|
+
"default_model": {
|
|
5
|
+
"type": "string",
|
|
6
|
+
"minLength": 1
|
|
7
|
+
},
|
|
8
|
+
"models": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"additionalProperties": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"properties": {
|
|
13
|
+
"provider": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"enum": ["openai_compatible", "messages_compatible"]
|
|
16
|
+
},
|
|
17
|
+
"model": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"minLength": 1
|
|
20
|
+
},
|
|
21
|
+
"api_key_env": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"pattern": "^[A-Z_][A-Z0-9_]*$"
|
|
24
|
+
},
|
|
25
|
+
"base_url": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"format": "uri"
|
|
28
|
+
},
|
|
29
|
+
"base_url_env": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"pattern": "^[A-Z_][A-Z0-9_]*$"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"required": ["provider", "model", "api_key_env"],
|
|
35
|
+
"additionalProperties": false
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"intents": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"additionalProperties": {
|
|
41
|
+
"type": "object",
|
|
42
|
+
"properties": {
|
|
43
|
+
"description": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"minLength": 1
|
|
46
|
+
},
|
|
47
|
+
"allow_tools": {
|
|
48
|
+
"type": "array",
|
|
49
|
+
"items": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"minLength": 1
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"approval_required_tools": {
|
|
55
|
+
"type": "array",
|
|
56
|
+
"items": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"minLength": 1
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"required": ["description", "allow_tools"],
|
|
63
|
+
"additionalProperties": false
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"limits": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"properties": {
|
|
69
|
+
"max_turns_per_session": {
|
|
70
|
+
"type": "integer",
|
|
71
|
+
"minimum": 1
|
|
72
|
+
},
|
|
73
|
+
"max_tool_calls_per_session": {
|
|
74
|
+
"type": "integer",
|
|
75
|
+
"minimum": 1
|
|
76
|
+
},
|
|
77
|
+
"max_input_bytes": {
|
|
78
|
+
"type": "integer",
|
|
79
|
+
"minimum": 1
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"additionalProperties": false
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"required": ["default_model", "models"],
|
|
86
|
+
"additionalProperties": false
|
|
87
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
|
|
4
|
+
export const AGENT_RUNTIME_PACK_ID = 'agent-runtime' as const;
|
|
5
|
+
export const AGENT_RUNTIME_PACK_VERSION = '0.1.0' as const;
|
|
6
|
+
export const AGENT_RUNTIME_DOMAIN = AGENT_RUNTIME_PACK_ID;
|
|
7
|
+
export const AGENT_RUNTIME_CONFIG_KEY = 'agent_runtime' as const;
|
|
8
|
+
export const AGENT_RUNTIME_POLICY_ID_PREFIX = `${AGENT_RUNTIME_PACK_ID}.policy` as const;
|
|
9
|
+
export const AGENT_RUNTIME_MANIFEST_FILE_NAME = 'manifest.yaml' as const;
|
|
10
|
+
export const AGENT_RUNTIME_CONFIG_SCHEMA_FILE = 'config.schema.json' as const;
|
|
11
|
+
export const SHA256_ALGORITHM = 'sha256' as const;
|
|
12
|
+
export const UTF8_ENCODING = 'utf8' as const;
|
|
13
|
+
export const AGENT_RUNTIME_STORAGE_PATTERN = '.agent-runtime/**' as const;
|
|
14
|
+
export const AGENT_RUNTIME_API_KEY_ENV = 'AGENT_RUNTIME_API_KEY' as const;
|
|
15
|
+
export const AGENT_RUNTIME_BASE_URL_ENV = 'AGENT_RUNTIME_BASE_URL' as const;
|
|
16
|
+
export const AGENT_RUNTIME_STATIC_PROVIDER_ALLOWLIST = ['model-provider.invalid:443'] as const;
|
|
17
|
+
export const AGENT_RUNTIME_STATIC_PROVIDER_URLS = ['https://model-provider.invalid/'] as const;
|
|
18
|
+
export const AGENT_RUNTIME_AGENT_INTENT_METADATA_KEY = 'agent_intent' as const;
|
|
19
|
+
export const AGENT_RUNTIME_AGENT_TURN_INDEX_METADATA_KEY = 'agent_turn_index' as const;
|
|
20
|
+
export const AGENT_RUNTIME_AGENT_TOOL_CALL_COUNT_METADATA_KEY = 'agent_tool_call_count' as const;
|
|
21
|
+
export const AGENT_RUNTIME_AGENT_WORKFLOW_NODE_ID_METADATA_KEY = 'agent_workflow_node_id' as const;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
|
|
4
|
+
export * from './constants.js';
|
|
5
|
+
export * from './capability-factory.js';
|
|
6
|
+
export * from './manifest.js';
|
|
7
|
+
export * from './orchestration.js';
|
|
8
|
+
export * from './pack-registration.js';
|
|
9
|
+
export * from './policy-factory.js';
|
|
10
|
+
export * from './types.js';
|
|
11
|
+
export * from './tools/index.js';
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
DomainPackManifestSchema,
|
|
6
|
+
POLICY_TRIGGERS,
|
|
7
|
+
type DomainPackManifest,
|
|
8
|
+
} from '@lumenflow/kernel';
|
|
9
|
+
import {
|
|
10
|
+
AGENT_RUNTIME_API_KEY_ENV,
|
|
11
|
+
AGENT_RUNTIME_BASE_URL_ENV,
|
|
12
|
+
AGENT_RUNTIME_CONFIG_KEY,
|
|
13
|
+
AGENT_RUNTIME_CONFIG_SCHEMA_FILE,
|
|
14
|
+
AGENT_RUNTIME_PACK_ID,
|
|
15
|
+
AGENT_RUNTIME_PACK_VERSION,
|
|
16
|
+
AGENT_RUNTIME_POLICY_ID_PREFIX,
|
|
17
|
+
AGENT_RUNTIME_STATIC_PROVIDER_ALLOWLIST,
|
|
18
|
+
AGENT_RUNTIME_STATIC_PROVIDER_URLS,
|
|
19
|
+
AGENT_RUNTIME_STORAGE_PATTERN,
|
|
20
|
+
} from './constants.js';
|
|
21
|
+
import {
|
|
22
|
+
AGENT_RUNTIME_PROVIDER_KINDS,
|
|
23
|
+
AGENT_RUNTIME_TOOL_NAMES,
|
|
24
|
+
AGENT_RUNTIME_TURN_STATUSES,
|
|
25
|
+
type AgentRuntimeToolName,
|
|
26
|
+
} from './types.js';
|
|
27
|
+
|
|
28
|
+
const EXECUTE_TURN_TOOL_ENTRY = 'tool-impl/agent-turn-tools.ts#agentExecuteTurnTool';
|
|
29
|
+
const CAPABILITY_FACTORY_ENTRY = 'capability-factory.ts#createAgentRuntimeCapabilityFactory';
|
|
30
|
+
const POLICY_FACTORY_ENTRY = 'policy-factory.ts#createAgentRuntimePolicyFactory';
|
|
31
|
+
|
|
32
|
+
const EXECUTE_TURN_INPUT_SCHEMA: Record<string, unknown> = {
|
|
33
|
+
type: 'object',
|
|
34
|
+
properties: {
|
|
35
|
+
session_id: { type: 'string', minLength: 1 },
|
|
36
|
+
model_profile: { type: 'string', minLength: 1 },
|
|
37
|
+
url: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
enum: [...AGENT_RUNTIME_STATIC_PROVIDER_URLS],
|
|
40
|
+
},
|
|
41
|
+
stream: {
|
|
42
|
+
type: 'boolean',
|
|
43
|
+
},
|
|
44
|
+
messages: {
|
|
45
|
+
type: 'array',
|
|
46
|
+
minItems: 1,
|
|
47
|
+
items: {
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: {
|
|
50
|
+
role: {
|
|
51
|
+
type: 'string',
|
|
52
|
+
enum: ['system', 'user', 'assistant', 'tool'],
|
|
53
|
+
},
|
|
54
|
+
content: { type: 'string' },
|
|
55
|
+
tool_name: { type: 'string' },
|
|
56
|
+
tool_call_id: { type: 'string' },
|
|
57
|
+
},
|
|
58
|
+
required: ['role', 'content'],
|
|
59
|
+
additionalProperties: false,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
tool_catalog: {
|
|
63
|
+
type: 'array',
|
|
64
|
+
items: {
|
|
65
|
+
type: 'object',
|
|
66
|
+
properties: {
|
|
67
|
+
name: { type: 'string', minLength: 1 },
|
|
68
|
+
description: { type: 'string', minLength: 1 },
|
|
69
|
+
input_schema: {
|
|
70
|
+
type: 'object',
|
|
71
|
+
additionalProperties: true,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
required: ['name', 'description'],
|
|
75
|
+
additionalProperties: false,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
intent_catalog: {
|
|
79
|
+
type: 'array',
|
|
80
|
+
items: {
|
|
81
|
+
type: 'object',
|
|
82
|
+
properties: {
|
|
83
|
+
id: { type: 'string', minLength: 1 },
|
|
84
|
+
description: { type: 'string', minLength: 1 },
|
|
85
|
+
},
|
|
86
|
+
required: ['id', 'description'],
|
|
87
|
+
additionalProperties: false,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
limits: {
|
|
91
|
+
type: 'object',
|
|
92
|
+
properties: {
|
|
93
|
+
max_turns_per_session: { type: 'integer', minimum: 1 },
|
|
94
|
+
max_tool_calls_per_session: { type: 'integer', minimum: 1 },
|
|
95
|
+
max_input_bytes: { type: 'integer', minimum: 1 },
|
|
96
|
+
},
|
|
97
|
+
additionalProperties: false,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
required: ['session_id', 'model_profile', 'url', 'messages'],
|
|
101
|
+
additionalProperties: false,
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const EXECUTE_TURN_OUTPUT_SCHEMA: Record<string, unknown> = {
|
|
105
|
+
type: 'object',
|
|
106
|
+
properties: {
|
|
107
|
+
status: {
|
|
108
|
+
type: 'string',
|
|
109
|
+
enum: Object.values(AGENT_RUNTIME_TURN_STATUSES),
|
|
110
|
+
},
|
|
111
|
+
intent: { type: 'string', minLength: 1 },
|
|
112
|
+
assistant_message: { type: 'string' },
|
|
113
|
+
requested_tool: {
|
|
114
|
+
type: 'object',
|
|
115
|
+
properties: {
|
|
116
|
+
name: { type: 'string', minLength: 1 },
|
|
117
|
+
input: {
|
|
118
|
+
type: 'object',
|
|
119
|
+
additionalProperties: true,
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
required: ['name', 'input'],
|
|
123
|
+
additionalProperties: false,
|
|
124
|
+
},
|
|
125
|
+
provider: {
|
|
126
|
+
type: 'object',
|
|
127
|
+
properties: {
|
|
128
|
+
kind: {
|
|
129
|
+
type: 'string',
|
|
130
|
+
enum: Object.values(AGENT_RUNTIME_PROVIDER_KINDS),
|
|
131
|
+
},
|
|
132
|
+
model: { type: 'string', minLength: 1 },
|
|
133
|
+
},
|
|
134
|
+
required: ['kind', 'model'],
|
|
135
|
+
additionalProperties: false,
|
|
136
|
+
},
|
|
137
|
+
usage: {
|
|
138
|
+
type: 'object',
|
|
139
|
+
properties: {
|
|
140
|
+
input_tokens: { type: 'integer', minimum: 0 },
|
|
141
|
+
output_tokens: { type: 'integer', minimum: 0 },
|
|
142
|
+
total_tokens: { type: 'integer', minimum: 0 },
|
|
143
|
+
},
|
|
144
|
+
additionalProperties: false,
|
|
145
|
+
},
|
|
146
|
+
finish_reason: { type: 'string', minLength: 1 },
|
|
147
|
+
},
|
|
148
|
+
required: ['status', 'intent', 'assistant_message', 'provider', 'finish_reason'],
|
|
149
|
+
additionalProperties: false,
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const MANIFEST_TOOL_DEFINITIONS = [
|
|
153
|
+
{
|
|
154
|
+
name: AGENT_RUNTIME_TOOL_NAMES.EXECUTE_TURN,
|
|
155
|
+
entry: EXECUTE_TURN_TOOL_ENTRY,
|
|
156
|
+
permission: 'write',
|
|
157
|
+
required_scopes: [
|
|
158
|
+
{ type: 'path', pattern: AGENT_RUNTIME_STORAGE_PATTERN, access: 'read' },
|
|
159
|
+
{ type: 'path', pattern: AGENT_RUNTIME_STORAGE_PATTERN, access: 'write' },
|
|
160
|
+
{
|
|
161
|
+
type: 'network',
|
|
162
|
+
posture: 'allowlist',
|
|
163
|
+
allowlist_entries: [...AGENT_RUNTIME_STATIC_PROVIDER_ALLOWLIST],
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
required_env: [AGENT_RUNTIME_API_KEY_ENV, AGENT_RUNTIME_BASE_URL_ENV],
|
|
167
|
+
input_schema: EXECUTE_TURN_INPUT_SCHEMA,
|
|
168
|
+
output_schema: EXECUTE_TURN_OUTPUT_SCHEMA,
|
|
169
|
+
},
|
|
170
|
+
] as const;
|
|
171
|
+
|
|
172
|
+
export const AGENT_RUNTIME_MANIFEST = DomainPackManifestSchema.parse({
|
|
173
|
+
id: AGENT_RUNTIME_PACK_ID,
|
|
174
|
+
version: AGENT_RUNTIME_PACK_VERSION,
|
|
175
|
+
config_key: AGENT_RUNTIME_CONFIG_KEY,
|
|
176
|
+
config_schema: AGENT_RUNTIME_CONFIG_SCHEMA_FILE,
|
|
177
|
+
capability_factory: CAPABILITY_FACTORY_ENTRY,
|
|
178
|
+
policy_factory: POLICY_FACTORY_ENTRY,
|
|
179
|
+
task_types: ['agent-session'],
|
|
180
|
+
tools: MANIFEST_TOOL_DEFINITIONS,
|
|
181
|
+
policies: [
|
|
182
|
+
{
|
|
183
|
+
id: `${AGENT_RUNTIME_POLICY_ID_PREFIX}.default`,
|
|
184
|
+
trigger: POLICY_TRIGGERS.ON_TOOL_REQUEST,
|
|
185
|
+
decision: 'allow',
|
|
186
|
+
reason: 'Pack baseline allow; dynamic intent gating is applied by the pack policy factory.',
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
evidence_types: ['agent-runtime.turn', 'agent-runtime.provider-call'],
|
|
190
|
+
state_aliases: {
|
|
191
|
+
paused: 'waiting',
|
|
192
|
+
},
|
|
193
|
+
lane_templates: [],
|
|
194
|
+
}) satisfies DomainPackManifest;
|
|
195
|
+
|
|
196
|
+
export type AgentRuntimePackManifest = typeof AGENT_RUNTIME_MANIFEST;
|
|
197
|
+
export type AgentRuntimeManifestTool = AgentRuntimePackManifest['tools'][number];
|
|
198
|
+
|
|
199
|
+
export const AGENT_RUNTIME_MANIFEST_TOOL_NAMES = AGENT_RUNTIME_MANIFEST.tools.map(
|
|
200
|
+
(tool) => tool.name,
|
|
201
|
+
) as readonly AgentRuntimeToolName[];
|
|
202
|
+
|
|
203
|
+
export function getAgentRuntimeManifestToolByName(
|
|
204
|
+
name: string,
|
|
205
|
+
): AgentRuntimeManifestTool | undefined {
|
|
206
|
+
return AGENT_RUNTIME_MANIFEST.tools.find((tool) => tool.name === name);
|
|
207
|
+
}
|