@nebutra/agent-runtime 0.2.0 → 0.2.2
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 +21 -676
- package/README.md +2 -0
- package/dist/adapters/dispatcher-sse.js +1 -0
- package/dist/adapters/index.d.ts +24 -5
- package/dist/adapters/index.js +28 -0
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/mcp-catalog.js +1 -0
- package/dist/adapters/prisma-rollout.js +1 -0
- package/dist/chunk-424PT5DM.js +23 -0
- package/dist/chunk-424PT5DM.js.map +1 -0
- package/dist/{chunk-NN7DATXA.js → chunk-4Y25ZTKI.js} +3 -3
- package/dist/chunk-4Y25ZTKI.js.map +1 -0
- package/dist/{chunk-BJBBR3QA.js → chunk-D4YAPLOW.js} +4 -4
- package/dist/chunk-D4YAPLOW.js.map +1 -0
- package/dist/{chunk-ZMYX5VBU.js → chunk-GQZKYWFT.js} +23 -7
- package/dist/chunk-GQZKYWFT.js.map +1 -0
- package/dist/chunk-KCNN4QUQ.js +255 -0
- package/dist/chunk-KCNN4QUQ.js.map +1 -0
- package/dist/{chunk-PGGWSUTM.js → chunk-NI4EDT4T.js} +2 -2
- package/dist/chunk-NI4EDT4T.js.map +1 -0
- package/dist/chunk-Q62VKHIT.js +178 -0
- package/dist/chunk-Q62VKHIT.js.map +1 -0
- package/dist/{chunk-MUF7ZZTO.js → chunk-R5HOSQUW.js} +2 -1
- package/dist/{chunk-MUF7ZZTO.js.map → chunk-R5HOSQUW.js.map} +1 -1
- package/dist/{chunk-5N4644PB.js → chunk-SD2ZJ7XG.js} +4 -4
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +52 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.js +1 -0
- package/dist/definitions.js +1 -0
- package/dist/dispatcher.js +1 -0
- package/dist/durable-turn.js +3 -2
- package/dist/hook-pipeline.js +1 -0
- package/dist/index.d.ts +8 -85
- package/dist/index.js +249 -134
- package/dist/index.js.map +1 -1
- package/dist/loop.d.ts +2 -2
- package/dist/loop.js +3 -2
- package/dist/mcp-bridge.d.ts +3 -3
- package/dist/mcp-bridge.js +3 -2
- package/dist/model.js +1 -0
- package/dist/orchestration.d.ts +84 -0
- package/dist/orchestration.js +16 -0
- package/dist/orchestration.js.map +1 -0
- package/dist/policy.js +1 -0
- package/dist/protocol.js +1 -0
- package/dist/pulsar.d.ts +78 -0
- package/dist/pulsar.js +17 -0
- package/dist/pulsar.js.map +1 -0
- package/dist/rollout-store-persistent.js +1 -0
- package/dist/rollout.js +1 -0
- package/dist/sandbox.js +2 -1
- package/dist/skills.js +2 -1
- package/dist/subagents.js +1 -0
- package/dist/tools.d.ts +4 -3
- package/dist/tools.js +5 -3
- package/package.json +84 -27
- package/.turbo/turbo-build.log +0 -115
- package/.turbo/turbo-test.log +0 -44
- package/.turbo/turbo-typecheck.log +0 -4
- package/CHANGELOG.md +0 -253
- package/dist/chunk-BJBBR3QA.js.map +0 -1
- package/dist/chunk-NN7DATXA.js.map +0 -1
- package/dist/chunk-PGGWSUTM.js.map +0 -1
- package/dist/chunk-ZMYX5VBU.js.map +0 -1
- package/src/adapters/dispatcher-sse.test.ts +0 -218
- package/src/adapters/dispatcher-sse.ts +0 -222
- package/src/adapters/index.ts +0 -18
- package/src/adapters/mcp-catalog.test.ts +0 -213
- package/src/adapters/mcp-catalog.ts +0 -188
- package/src/adapters/prisma-rollout.test.ts +0 -153
- package/src/adapters/prisma-rollout.ts +0 -104
- package/src/agent-runtime.test.ts +0 -176
- package/src/artifact-stream.test.ts +0 -330
- package/src/artifact-stream.ts +0 -453
- package/src/channel-gateway.test.ts +0 -432
- package/src/channel-gateway.ts +0 -357
- package/src/code-review.test.ts +0 -501
- package/src/code-review.ts +0 -495
- package/src/command-suggestions.test.ts +0 -251
- package/src/command-suggestions.ts +0 -338
- package/src/commands.test.ts +0 -184
- package/src/commands.ts +0 -140
- package/src/commit-message.test.ts +0 -249
- package/src/commit-message.ts +0 -180
- package/src/context-compaction.test.ts +0 -522
- package/src/context-compaction.ts +0 -434
- package/src/definitions.test.ts +0 -78
- package/src/definitions.ts +0 -190
- package/src/deployment-status.test.ts +0 -215
- package/src/deployment-status.ts +0 -227
- package/src/design-context.test.ts +0 -195
- package/src/design-context.ts +0 -198
- package/src/dispatcher.test.ts +0 -234
- package/src/dispatcher.ts +0 -189
- package/src/durable-turn.test.ts +0 -209
- package/src/durable-turn.ts +0 -135
- package/src/edit-planner.test.ts +0 -204
- package/src/edit-planner.ts +0 -325
- package/src/fuzzy-match.test.ts +0 -311
- package/src/fuzzy-match.ts +0 -444
- package/src/hook-pipeline.test.ts +0 -279
- package/src/hook-pipeline.ts +0 -373
- package/src/inbound-admission.test.ts +0 -394
- package/src/inbound-admission.ts +0 -246
- package/src/index.ts +0 -47
- package/src/loop.test.ts +0 -161
- package/src/loop.ts +0 -211
- package/src/mcp-bridge.test.ts +0 -165
- package/src/mcp-bridge.ts +0 -76
- package/src/memory-provider.test.ts +0 -232
- package/src/memory-provider.ts +0 -257
- package/src/model.ts +0 -168
- package/src/permission-ruleset.test.ts +0 -301
- package/src/permission-ruleset.ts +0 -200
- package/src/policy.ts +0 -151
- package/src/project-repo.test.ts +0 -232
- package/src/project-repo.ts +0 -311
- package/src/protocol.ts +0 -159
- package/src/rollout-store-persistent.test.ts +0 -217
- package/src/rollout-store-persistent.ts +0 -166
- package/src/rollout.ts +0 -150
- package/src/sandbox.ts +0 -113
- package/src/session-share.test.ts +0 -360
- package/src/session-share.ts +0 -310
- package/src/skill-distillation.test.ts +0 -177
- package/src/skill-distillation.ts +0 -369
- package/src/skills.test.ts +0 -277
- package/src/skills.ts +0 -255
- package/src/subagents.test.ts +0 -290
- package/src/subagents.ts +0 -332
- package/src/tools.ts +0 -126
- package/src/workbench.test.ts +0 -0
- package/src/workbench.ts +0 -0
- package/tsconfig.json +0 -12
- package/tsup.config.ts +0 -33
- /package/dist/{chunk-5N4644PB.js.map → chunk-SD2ZJ7XG.js.map} +0 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// src/orchestration.ts
|
|
2
|
+
import { hasCycleFrom } from "@nebutra/graph-model";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
var budgetCapSchema = z.object({
|
|
5
|
+
durationMs: z.number().positive(),
|
|
6
|
+
costUsd: z.number().nonnegative(),
|
|
7
|
+
tokenLimit: z.number().positive()
|
|
8
|
+
});
|
|
9
|
+
var briefSchema = z.object({
|
|
10
|
+
id: z.string().trim().min(1),
|
|
11
|
+
objective: z.string().trim().min(1),
|
|
12
|
+
outputFormat: z.record(z.string(), z.unknown()),
|
|
13
|
+
allowedTools: z.array(z.string()).min(1),
|
|
14
|
+
contextRefs: z.array(z.string()),
|
|
15
|
+
boundaries: z.array(z.string()).min(1),
|
|
16
|
+
budget: budgetCapSchema,
|
|
17
|
+
dependsOn: z.array(z.string()).optional(),
|
|
18
|
+
model: z.object({
|
|
19
|
+
id: z.string().trim().min(1).optional(),
|
|
20
|
+
reasoningEffort: z.enum(["low", "medium", "high", "xhigh"]).optional(),
|
|
21
|
+
modality: z.enum(["text", "image", "video", "audio", "embedding"]).optional(),
|
|
22
|
+
capabilities: z.object({
|
|
23
|
+
vision: z.boolean().optional(),
|
|
24
|
+
toolCall: z.boolean().optional(),
|
|
25
|
+
reasoning: z.boolean().optional()
|
|
26
|
+
}).optional()
|
|
27
|
+
}).optional()
|
|
28
|
+
});
|
|
29
|
+
function fail(message, suggestion) {
|
|
30
|
+
throw new Error(`${message}. Suggestion: ${suggestion}`);
|
|
31
|
+
}
|
|
32
|
+
var BRIEF_FIELD_FAILURE = {
|
|
33
|
+
id: { message: "brief.id is required", suggestion: "Use a stable role or task id." },
|
|
34
|
+
objective: {
|
|
35
|
+
message: "brief.objective is required",
|
|
36
|
+
suggestion: "Write a concrete objective before dispatching."
|
|
37
|
+
},
|
|
38
|
+
outputFormat: {
|
|
39
|
+
message: "brief.outputFormat is invalid",
|
|
40
|
+
suggestion: "Provide an output schema object the worker must conform to."
|
|
41
|
+
},
|
|
42
|
+
allowedTools: {
|
|
43
|
+
message: "brief.allowedTools is required",
|
|
44
|
+
suggestion: "Constrain each subagent to an explicit tool scope."
|
|
45
|
+
},
|
|
46
|
+
contextRefs: {
|
|
47
|
+
message: "brief.contextRefs is invalid",
|
|
48
|
+
suggestion: "Pass an array of context references (may be empty)."
|
|
49
|
+
},
|
|
50
|
+
boundaries: {
|
|
51
|
+
message: "brief.boundaries is required",
|
|
52
|
+
suggestion: "State at least one boundary for the worker."
|
|
53
|
+
},
|
|
54
|
+
budget: {
|
|
55
|
+
message: "brief.budget is invalid",
|
|
56
|
+
suggestion: "Set positive token/time caps and a non-negative cost cap."
|
|
57
|
+
},
|
|
58
|
+
dependsOn: {
|
|
59
|
+
message: "brief.dependsOn is invalid",
|
|
60
|
+
suggestion: "List dependency brief ids as an array of strings."
|
|
61
|
+
},
|
|
62
|
+
model: {
|
|
63
|
+
message: "brief.model is invalid",
|
|
64
|
+
suggestion: "Use a preset alias or 'provider/model' id, or omit to inherit the run default."
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
function validateBrief(brief) {
|
|
68
|
+
const result = briefSchema.safeParse(brief);
|
|
69
|
+
if (result.success) return;
|
|
70
|
+
const topLevelField = result.error.issues[0]?.path[0];
|
|
71
|
+
const failure = typeof topLevelField === "string" ? BRIEF_FIELD_FAILURE[topLevelField] : void 0;
|
|
72
|
+
if (failure) fail(failure.message, failure.suggestion);
|
|
73
|
+
fail("brief is invalid", "Provide every required brief field with valid values.");
|
|
74
|
+
}
|
|
75
|
+
function dependencySet(briefs) {
|
|
76
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
77
|
+
for (const brief of briefs) {
|
|
78
|
+
for (const dep of brief.dependsOn ?? []) dependencies.add(dep);
|
|
79
|
+
}
|
|
80
|
+
return dependencies;
|
|
81
|
+
}
|
|
82
|
+
function briefEdges(briefs) {
|
|
83
|
+
const ids = new Set(briefs.map((brief) => brief.id));
|
|
84
|
+
const edges = [];
|
|
85
|
+
for (const brief of briefs) {
|
|
86
|
+
for (const dep of brief.dependsOn ?? []) {
|
|
87
|
+
if (ids.has(dep)) edges.push({ from: dep, to: brief.id });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return edges;
|
|
91
|
+
}
|
|
92
|
+
function assertAcyclic(briefs, edges) {
|
|
93
|
+
for (const brief of briefs) {
|
|
94
|
+
if (hasCycleFrom(edges, brief.id)) {
|
|
95
|
+
fail(
|
|
96
|
+
`subagent dependency cycle includes '${brief.id}'`,
|
|
97
|
+
"Remove the cycle or collapse the dependent work into one sequential brief."
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function planWaves(briefs) {
|
|
103
|
+
const edges = briefEdges(briefs);
|
|
104
|
+
assertAcyclic(briefs, edges);
|
|
105
|
+
const byId = new Map(briefs.map((brief) => [brief.id, brief]));
|
|
106
|
+
const done = /* @__PURE__ */ new Set();
|
|
107
|
+
const waves = [];
|
|
108
|
+
while (done.size < briefs.length) {
|
|
109
|
+
const wave = [];
|
|
110
|
+
for (const brief of briefs) {
|
|
111
|
+
if (done.has(brief.id)) continue;
|
|
112
|
+
const deps = (brief.dependsOn ?? []).filter((dep) => byId.has(dep));
|
|
113
|
+
if (deps.every((dep) => done.has(dep))) wave.push(brief);
|
|
114
|
+
}
|
|
115
|
+
if (wave.length === 0) {
|
|
116
|
+
fail(
|
|
117
|
+
"subagent dependencies cannot be resolved into waves",
|
|
118
|
+
"Ensure every dependsOn id references a brief in the set."
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
for (const brief of wave) done.add(brief.id);
|
|
122
|
+
waves.push(wave);
|
|
123
|
+
}
|
|
124
|
+
return waves;
|
|
125
|
+
}
|
|
126
|
+
function topologicalOrder(briefs) {
|
|
127
|
+
return planWaves(briefs).flat();
|
|
128
|
+
}
|
|
129
|
+
function planSubagentDispatch(briefs, options = {}) {
|
|
130
|
+
if (briefs.length === 0) {
|
|
131
|
+
fail("at least one brief is required", "Create a concrete worker brief before dispatching.");
|
|
132
|
+
}
|
|
133
|
+
for (const brief of briefs) validateBrief(brief);
|
|
134
|
+
const dependencies = dependencySet(briefs);
|
|
135
|
+
if ((options.strategy ?? "auto") === "fanout" && dependencies.size > 0) {
|
|
136
|
+
fail(
|
|
137
|
+
"fan-out cannot run briefs that depend on each other",
|
|
138
|
+
"Use sequential dispatch for dependent work or split independent briefs only."
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
const order = topologicalOrder(briefs);
|
|
142
|
+
const strategy = options.strategy === "fanout" || options.strategy === "auto" && dependencies.size === 0 ? "fanout" : "sequential";
|
|
143
|
+
return { strategy, order };
|
|
144
|
+
}
|
|
145
|
+
async function fanOutSubagents(briefs, run) {
|
|
146
|
+
const plan = planSubagentDispatch(briefs, { strategy: "fanout" });
|
|
147
|
+
return Promise.all(plan.order.map((brief) => run(brief)));
|
|
148
|
+
}
|
|
149
|
+
async function runAgentWaves(briefs, run) {
|
|
150
|
+
for (const brief of briefs) validateBrief(brief);
|
|
151
|
+
const results = [];
|
|
152
|
+
for (const wave of planWaves(briefs)) {
|
|
153
|
+
const waveResults = await Promise.all(wave.map((brief) => run(brief)));
|
|
154
|
+
results.push(...waveResults);
|
|
155
|
+
}
|
|
156
|
+
return results;
|
|
157
|
+
}
|
|
158
|
+
function costReport(results) {
|
|
159
|
+
return {
|
|
160
|
+
totalInputTokens: results.reduce((sum, result) => sum + result.usage.inputTokens, 0),
|
|
161
|
+
totalOutputTokens: results.reduce((sum, result) => sum + result.usage.outputTokens, 0),
|
|
162
|
+
totalReasoningTokens: results.reduce(
|
|
163
|
+
(sum, result) => sum + result.usage.reasoningOutputTokens,
|
|
164
|
+
0
|
|
165
|
+
),
|
|
166
|
+
maxDurationMs: results.reduce((max, result) => Math.max(max, result.durationMs), 0),
|
|
167
|
+
subagents: results.length
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export {
|
|
172
|
+
planWaves,
|
|
173
|
+
planSubagentDispatch,
|
|
174
|
+
fanOutSubagents,
|
|
175
|
+
runAgentWaves,
|
|
176
|
+
costReport
|
|
177
|
+
};
|
|
178
|
+
//# sourceMappingURL=chunk-Q62VKHIT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/orchestration.ts"],"sourcesContent":["import { type GraphEdge, hasCycleFrom } from \"@nebutra/graph-model\";\nimport { z } from \"zod\";\nimport type { TurnUsage } from \"./model\";\n\nexport interface BudgetCap {\n readonly durationMs: number;\n readonly costUsd: number;\n readonly tokenLimit: number;\n}\n\n/** Thinking/reasoning effort for a node (maps to provider reasoning controls). */\nexport type ReasoningEffort = \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\n/** Output modality a node produces. Mirrors @nebutra/ai-providers ModelModality. */\nexport type ModelModality = \"text\" | \"image\" | \"video\" | \"audio\" | \"embedding\";\n\n/**\n * Per-node model selection — the full model meta-info a node can declare. ALL\n * fields optional; an unset field inherits the run-level default\n * (WorkflowDefinition.defaultModel / runTurn config). The executor resolves\n * these HINTS against @nebutra/ai-providers/catalog (listModelsByModality /\n * resolveFrontierModel) to a concrete model — so a node can either PIN one\n * (`id`) or DESCRIBE what it needs (\"the latest fast text model with vision\").\n */\nexport interface NodeModelSpec {\n /** Explicit pin: preset alias (`flagship`/`reasoning`/`fast`) or `provider/model` id. */\n readonly id?: string;\n /** Thinking effort: `low` → cheap/quick, `xhigh` → deepest reasoning. */\n readonly reasoningEffort?: ReasoningEffort;\n /** Output modality — selects a model of this modality when `id` is unset. */\n readonly modality?: ModelModality;\n /** Capabilities the selected model MUST have (e.g. a node needing image input). */\n readonly capabilities?: {\n readonly vision?: boolean;\n readonly toolCall?: boolean;\n readonly reasoning?: boolean;\n };\n}\n\nexport interface Brief {\n readonly id: string;\n readonly objective: string;\n readonly outputFormat: Record<string, unknown>;\n readonly allowedTools: readonly string[];\n readonly contextRefs: readonly string[];\n readonly boundaries: readonly string[];\n readonly budget: BudgetCap;\n readonly dependsOn?: readonly string[];\n /** Per-node model meta-info (id/preset · thinking effort · modality · capabilities). */\n readonly model?: NodeModelSpec;\n}\n\n/**\n * Runtime shape + semantic validation for {@link Brief}. The public type keeps\n * its `readonly` immutability contract (see project immutability rules), so we\n * validate against this schema at the boundary rather than deriving the type\n * from it. Each rule mirrors a tailored DX suggestion surfaced via {@link fail}.\n */\nconst budgetCapSchema = z.object({\n durationMs: z.number().positive(),\n costUsd: z.number().nonnegative(),\n tokenLimit: z.number().positive(),\n});\n\nconst briefSchema = z.object({\n id: z.string().trim().min(1),\n objective: z.string().trim().min(1),\n outputFormat: z.record(z.string(), z.unknown()),\n allowedTools: z.array(z.string()).min(1),\n contextRefs: z.array(z.string()),\n boundaries: z.array(z.string()).min(1),\n budget: budgetCapSchema,\n dependsOn: z.array(z.string()).optional(),\n model: z\n .object({\n id: z.string().trim().min(1).optional(),\n reasoningEffort: z.enum([\"low\", \"medium\", \"high\", \"xhigh\"]).optional(),\n modality: z.enum([\"text\", \"image\", \"video\", \"audio\", \"embedding\"]).optional(),\n capabilities: z\n .object({\n vision: z.boolean().optional(),\n toolCall: z.boolean().optional(),\n reasoning: z.boolean().optional(),\n })\n .optional(),\n })\n .optional(),\n});\n\nexport type DispatchStrategy = \"auto\" | \"sequential\" | \"fanout\";\n\nexport interface DispatchPlan {\n readonly strategy: Exclude<DispatchStrategy, \"auto\">;\n readonly order: readonly Brief[];\n}\n\nexport interface DispatchPlanOptions {\n readonly strategy?: DispatchStrategy;\n}\n\nexport interface SubagentResult {\n readonly briefId: string;\n readonly output: unknown;\n readonly usage: TurnUsage;\n readonly durationMs: number;\n}\n\nexport interface SubagentCostReport {\n readonly totalInputTokens: number;\n readonly totalOutputTokens: number;\n readonly totalReasoningTokens: number;\n readonly maxDurationMs: number;\n readonly subagents: number;\n}\n\nfunction fail(message: string, suggestion: string): never {\n throw new Error(`${message}. Suggestion: ${suggestion}`);\n}\n\n/**\n * Per-top-level-field DX messages, keyed by the failing schema path. Keeps the\n * exact \"message. Suggestion: …\" surface the callers (and tests) rely on while\n * the heavy lifting (shape + bounds) moves into {@link briefSchema}.\n */\nconst BRIEF_FIELD_FAILURE: Record<string, { message: string; suggestion: string }> = {\n id: { message: \"brief.id is required\", suggestion: \"Use a stable role or task id.\" },\n objective: {\n message: \"brief.objective is required\",\n suggestion: \"Write a concrete objective before dispatching.\",\n },\n outputFormat: {\n message: \"brief.outputFormat is invalid\",\n suggestion: \"Provide an output schema object the worker must conform to.\",\n },\n allowedTools: {\n message: \"brief.allowedTools is required\",\n suggestion: \"Constrain each subagent to an explicit tool scope.\",\n },\n contextRefs: {\n message: \"brief.contextRefs is invalid\",\n suggestion: \"Pass an array of context references (may be empty).\",\n },\n boundaries: {\n message: \"brief.boundaries is required\",\n suggestion: \"State at least one boundary for the worker.\",\n },\n budget: {\n message: \"brief.budget is invalid\",\n suggestion: \"Set positive token/time caps and a non-negative cost cap.\",\n },\n dependsOn: {\n message: \"brief.dependsOn is invalid\",\n suggestion: \"List dependency brief ids as an array of strings.\",\n },\n model: {\n message: \"brief.model is invalid\",\n suggestion: \"Use a preset alias or 'provider/model' id, or omit to inherit the run default.\",\n },\n};\n\nfunction validateBrief(brief: Brief): void {\n const result = briefSchema.safeParse(brief);\n if (result.success) return;\n\n const topLevelField = result.error.issues[0]?.path[0];\n const failure =\n typeof topLevelField === \"string\" ? BRIEF_FIELD_FAILURE[topLevelField] : undefined;\n if (failure) fail(failure.message, failure.suggestion);\n fail(\"brief is invalid\", \"Provide every required brief field with valid values.\");\n}\n\nfunction dependencySet(briefs: readonly Brief[]): Set<string> {\n const dependencies = new Set<string>();\n for (const brief of briefs) {\n for (const dep of brief.dependsOn ?? []) dependencies.add(dep);\n }\n return dependencies;\n}\n\n/** Dependency edges (dep → brief) over the brief set; refs to unknown ids drop. */\nfunction briefEdges(briefs: readonly Brief[]): GraphEdge[] {\n const ids = new Set(briefs.map((brief) => brief.id));\n const edges: GraphEdge[] = [];\n for (const brief of briefs) {\n for (const dep of brief.dependsOn ?? []) {\n if (ids.has(dep)) edges.push({ from: dep, to: brief.id });\n }\n }\n return edges;\n}\n\n/**\n * Cycle guard via the SINGLE repo-wide cycle-detection algorithm\n * (`@nebutra/graph-model` `hasCycleFrom`). No private DFS cycle-walker lives here.\n */\nfunction assertAcyclic(briefs: readonly Brief[], edges: readonly GraphEdge[]): void {\n for (const brief of briefs) {\n if (hasCycleFrom(edges, brief.id)) {\n fail(\n `subagent dependency cycle includes '${brief.id}'`,\n \"Remove the cycle or collapse the dependent work into one sequential brief.\",\n );\n }\n }\n}\n\n/**\n * Dependency-resolved execution WAVES — the agent node-topology scheduler. Each\n * wave is the set of briefs whose dependencies are satisfied by earlier waves;\n * waves run in order, briefs within a wave run in parallel. Input order is\n * preserved within a wave.\n */\nexport function planWaves(briefs: readonly Brief[]): readonly (readonly Brief[])[] {\n const edges = briefEdges(briefs);\n assertAcyclic(briefs, edges);\n\n const byId = new Map(briefs.map((brief) => [brief.id, brief]));\n const done = new Set<string>();\n const waves: Brief[][] = [];\n\n while (done.size < briefs.length) {\n const wave: Brief[] = [];\n for (const brief of briefs) {\n if (done.has(brief.id)) continue;\n const deps = (brief.dependsOn ?? []).filter((dep) => byId.has(dep));\n if (deps.every((dep) => done.has(dep))) wave.push(brief);\n }\n if (wave.length === 0) {\n // assertAcyclic already ruled out cycles; only a logic bug reaches here.\n fail(\n \"subagent dependencies cannot be resolved into waves\",\n \"Ensure every dependsOn id references a brief in the set.\",\n );\n }\n for (const brief of wave) done.add(brief.id);\n waves.push(wave);\n }\n return waves;\n}\n\nfunction topologicalOrder(briefs: readonly Brief[]): Brief[] {\n return planWaves(briefs).flat();\n}\n\nexport function planSubagentDispatch(\n briefs: readonly Brief[],\n options: DispatchPlanOptions = {},\n): DispatchPlan {\n if (briefs.length === 0) {\n fail(\"at least one brief is required\", \"Create a concrete worker brief before dispatching.\");\n }\n for (const brief of briefs) validateBrief(brief);\n\n const dependencies = dependencySet(briefs);\n if ((options.strategy ?? \"auto\") === \"fanout\" && dependencies.size > 0) {\n fail(\n \"fan-out cannot run briefs that depend on each other\",\n \"Use sequential dispatch for dependent work or split independent briefs only.\",\n );\n }\n\n const order = topologicalOrder(briefs);\n const strategy =\n options.strategy === \"fanout\" || (options.strategy === \"auto\" && dependencies.size === 0)\n ? \"fanout\"\n : \"sequential\";\n return { strategy, order };\n}\n\nexport async function fanOutSubagents(\n briefs: readonly Brief[],\n run: (brief: Brief) => Promise<SubagentResult>,\n): Promise<readonly SubagentResult[]> {\n const plan = planSubagentDispatch(briefs, { strategy: \"fanout\" });\n return Promise.all(plan.order.map((brief) => run(brief)));\n}\n\n/**\n * Execute briefs as a dependency graph: each wave runs in parallel, waves run\n * sequentially. The node-topology execution path — `fanOutSubagents` is the\n * degenerate single-wave (all-independent) case of this.\n */\nexport async function runAgentWaves(\n briefs: readonly Brief[],\n run: (brief: Brief) => Promise<SubagentResult>,\n): Promise<readonly SubagentResult[]> {\n for (const brief of briefs) validateBrief(brief);\n const results: SubagentResult[] = [];\n for (const wave of planWaves(briefs)) {\n const waveResults = await Promise.all(wave.map((brief) => run(brief)));\n results.push(...waveResults);\n }\n return results;\n}\n\nexport function costReport(results: readonly SubagentResult[]): SubagentCostReport {\n return {\n totalInputTokens: results.reduce((sum, result) => sum + result.usage.inputTokens, 0),\n totalOutputTokens: results.reduce((sum, result) => sum + result.usage.outputTokens, 0),\n totalReasoningTokens: results.reduce(\n (sum, result) => sum + result.usage.reasoningOutputTokens,\n 0,\n ),\n maxDurationMs: results.reduce((max, result) => Math.max(max, result.durationMs), 0),\n subagents: results.length,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -18,6 +18,7 @@ var SandboxDelegationError = class extends Error {
|
|
|
18
18
|
this.status = status;
|
|
19
19
|
this.name = "SandboxDelegationError";
|
|
20
20
|
}
|
|
21
|
+
status;
|
|
21
22
|
};
|
|
22
23
|
function createHttpSandbox(baseUrl, fetchImpl = fetch) {
|
|
23
24
|
const endpoint = `${baseUrl.replace(/\/$/, "")}/api/v1/sandbox/exec`;
|
|
@@ -54,4 +55,4 @@ export {
|
|
|
54
55
|
createHttpSandbox,
|
|
55
56
|
assertSafePosture
|
|
56
57
|
};
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
58
|
+
//# sourceMappingURL=chunk-R5HOSQUW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sandbox.ts"],"sourcesContent":["/**\n * External-sandbox delegation seam (PORT — capability #11).\n *\n * Governance decision (dual-track, ExternalSandbox posture): this multi-tenant\n * web runtime NEVER executes untrusted code itself and introduces no isolation\n * infrastructure. It only:\n * 1. carries the capability policy (see ./policy),\n * 2. delegates execution to an external isolator behind this interface\n * (a self-hosted kernel sidecar — Track B — or any other executor),\n * 3. records the outcome as a `command_execution` item (see ./model).\n *\n * The upstream OS enforcers (Seatbelt / Landlock / bubblewrap / Windows\n * restricted token) are deliberately NOT ported — they are single-host and\n * out of scope for a multi-tenant web product.\n */\n\nimport type { CapabilityPolicy } from \"./policy\";\n\nexport interface SandboxExecRequest {\n /** Mandatory tenant scope — every delegated exec is tenant-bound. */\n readonly tenantId: string;\n readonly threadId: string;\n readonly command: string;\n /** The capabilities the external isolator must honor. */\n readonly capabilityPolicy: CapabilityPolicy;\n /** Optional inputs the executor should materialize before running. */\n readonly inputs?: Readonly<Record<string, string>>;\n}\n\nexport interface SandboxExecResult {\n readonly exitCode: number;\n readonly aggregatedOutput: string;\n /** Identifier of the isolator that actually ran the command. */\n readonly executedOn: string;\n}\n\n/**\n * The only thing Track A depends on for execution. Implemented by a decoupled\n * isolator over the ./protocol contract; never implemented in-process here.\n */\nexport interface ExternalSandbox {\n exec(request: SandboxExecRequest): Promise<SandboxExecResult>;\n}\n\n/**\n * Fail-closed default. Wiring this in production requires a real\n * {@link ExternalSandbox}; absent one, untrusted code never runs — by design.\n */\nexport class NoExecutorConfiguredError extends Error {\n constructor() {\n super(\n \"No ExternalSandbox configured. This runtime never executes untrusted \" +\n \"code in-process; delegate to a decoupled isolator (Track B).\",\n );\n this.name = \"NoExecutorConfiguredError\";\n }\n}\n\nexport const REFUSING_SANDBOX: ExternalSandbox = {\n async exec(): Promise<SandboxExecResult> {\n throw new NoExecutorConfiguredError();\n },\n};\n\nexport class SandboxDelegationError extends Error {\n constructor(\n message: string,\n readonly status: number,\n ) {\n super(message);\n this.name = \"SandboxDelegationError\";\n }\n}\n\n/**\n * The concrete Track-B coupling: delegate execution over HTTP to the decoupled\n * Rust isolator (`backends/rust/sandbox`, `POST /api/v1/sandbox/exec`). The\n * isolator is fail-closed; a non-2xx (e.g. 403 refusal) is surfaced as an\n * error and never coerced into a fabricated result.\n */\nexport function createHttpSandbox(\n baseUrl: string,\n fetchImpl: typeof fetch = fetch,\n): ExternalSandbox {\n const endpoint = `${baseUrl.replace(/\\/$/, \"\")}/api/v1/sandbox/exec`;\n return {\n async exec(request: SandboxExecRequest): Promise<SandboxExecResult> {\n const response = await fetchImpl(endpoint, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(request),\n });\n if (!response.ok) {\n const detail = await response.text().catch(() => \"\");\n throw new SandboxDelegationError(\n `Isolator refused execution (${response.status}): ${detail}`,\n response.status,\n );\n }\n return (await response.json()) as SandboxExecResult;\n },\n };\n}\n\n/** Guard: reject the most dangerous posture unless explicitly opted in. */\nexport function assertSafePosture(policy: CapabilityPolicy, allowDanger = false): void {\n if (policy.kind === \"danger_full_access\" && !allowDanger) {\n throw new Error(\n \"danger_full_access capability policy refused: not permitted for \" +\n \"multi-tenant delegation without explicit opt-in.\",\n );\n }\n}\n"],"mappings":";AAgDO,IAAM,4BAAN,cAAwC,MAAM;AAAA,EACnD,cAAc;AACZ;AAAA,MACE;AAAA,IAEF;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,mBAAoC;AAAA,EAC/C,MAAM,OAAmC;AACvC,UAAM,IAAI,0BAA0B;AAAA,EACtC;AACF;AAEO,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAChD,YACE,SACS,QACT;AACA,UAAM,OAAO;AAFJ;AAGT,SAAK,OAAO;AAAA,EACd;
|
|
1
|
+
{"version":3,"sources":["../src/sandbox.ts"],"sourcesContent":["/**\n * External-sandbox delegation seam (PORT — capability #11).\n *\n * Governance decision (dual-track, ExternalSandbox posture): this multi-tenant\n * web runtime NEVER executes untrusted code itself and introduces no isolation\n * infrastructure. It only:\n * 1. carries the capability policy (see ./policy),\n * 2. delegates execution to an external isolator behind this interface\n * (a self-hosted kernel sidecar — Track B — or any other executor),\n * 3. records the outcome as a `command_execution` item (see ./model).\n *\n * The upstream OS enforcers (Seatbelt / Landlock / bubblewrap / Windows\n * restricted token) are deliberately NOT ported — they are single-host and\n * out of scope for a multi-tenant web product.\n */\n\nimport type { CapabilityPolicy } from \"./policy\";\n\nexport interface SandboxExecRequest {\n /** Mandatory tenant scope — every delegated exec is tenant-bound. */\n readonly tenantId: string;\n readonly threadId: string;\n readonly command: string;\n /** The capabilities the external isolator must honor. */\n readonly capabilityPolicy: CapabilityPolicy;\n /** Optional inputs the executor should materialize before running. */\n readonly inputs?: Readonly<Record<string, string>>;\n}\n\nexport interface SandboxExecResult {\n readonly exitCode: number;\n readonly aggregatedOutput: string;\n /** Identifier of the isolator that actually ran the command. */\n readonly executedOn: string;\n}\n\n/**\n * The only thing Track A depends on for execution. Implemented by a decoupled\n * isolator over the ./protocol contract; never implemented in-process here.\n */\nexport interface ExternalSandbox {\n exec(request: SandboxExecRequest): Promise<SandboxExecResult>;\n}\n\n/**\n * Fail-closed default. Wiring this in production requires a real\n * {@link ExternalSandbox}; absent one, untrusted code never runs — by design.\n */\nexport class NoExecutorConfiguredError extends Error {\n constructor() {\n super(\n \"No ExternalSandbox configured. This runtime never executes untrusted \" +\n \"code in-process; delegate to a decoupled isolator (Track B).\",\n );\n this.name = \"NoExecutorConfiguredError\";\n }\n}\n\nexport const REFUSING_SANDBOX: ExternalSandbox = {\n async exec(): Promise<SandboxExecResult> {\n throw new NoExecutorConfiguredError();\n },\n};\n\nexport class SandboxDelegationError extends Error {\n constructor(\n message: string,\n readonly status: number,\n ) {\n super(message);\n this.name = \"SandboxDelegationError\";\n }\n}\n\n/**\n * The concrete Track-B coupling: delegate execution over HTTP to the decoupled\n * Rust isolator (`backends/rust/sandbox`, `POST /api/v1/sandbox/exec`). The\n * isolator is fail-closed; a non-2xx (e.g. 403 refusal) is surfaced as an\n * error and never coerced into a fabricated result.\n */\nexport function createHttpSandbox(\n baseUrl: string,\n fetchImpl: typeof fetch = fetch,\n): ExternalSandbox {\n const endpoint = `${baseUrl.replace(/\\/$/, \"\")}/api/v1/sandbox/exec`;\n return {\n async exec(request: SandboxExecRequest): Promise<SandboxExecResult> {\n const response = await fetchImpl(endpoint, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(request),\n });\n if (!response.ok) {\n const detail = await response.text().catch(() => \"\");\n throw new SandboxDelegationError(\n `Isolator refused execution (${response.status}): ${detail}`,\n response.status,\n );\n }\n return (await response.json()) as SandboxExecResult;\n },\n };\n}\n\n/** Guard: reject the most dangerous posture unless explicitly opted in. */\nexport function assertSafePosture(policy: CapabilityPolicy, allowDanger = false): void {\n if (policy.kind === \"danger_full_access\" && !allowDanger) {\n throw new Error(\n \"danger_full_access capability policy refused: not permitted for \" +\n \"multi-tenant delegation without explicit opt-in.\",\n );\n }\n}\n"],"mappings":";AAgDO,IAAM,4BAAN,cAAwC,MAAM;AAAA,EACnD,cAAc;AACZ;AAAA,MACE;AAAA,IAEF;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,mBAAoC;AAAA,EAC/C,MAAM,OAAmC;AACvC,UAAM,IAAI,0BAA0B;AAAA,EACtC;AACF;AAEO,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAChD,YACE,SACS,QACT;AACA,UAAM,OAAO;AAFJ;AAGT,SAAK,OAAO;AAAA,EACd;AAAA,EAJW;AAKb;AAQO,SAAS,kBACd,SACA,YAA0B,OACT;AACjB,QAAM,WAAW,GAAG,QAAQ,QAAQ,OAAO,EAAE,CAAC;AAC9C,SAAO;AAAA,IACL,MAAM,KAAK,SAAyD;AAClE,YAAM,WAAW,MAAM,UAAU,UAAU;AAAA,QACzC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B,CAAC;AACD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,SAAS,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,EAAE;AACnD,cAAM,IAAI;AAAA,UACR,+BAA+B,SAAS,MAAM,MAAM,MAAM;AAAA,UAC1D,SAAS;AAAA,QACX;AAAA,MACF;AACA,aAAQ,MAAM,SAAS,KAAK;AAAA,IAC9B;AAAA,EACF;AACF;AAGO,SAAS,kBAAkB,QAA0B,cAAc,OAAa;AACrF,MAAI,OAAO,SAAS,wBAAwB,CAAC,aAAa;AACxD,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isTurnTerminal
|
|
3
|
-
} from "./chunk-6EGG2OZC.js";
|
|
4
1
|
import {
|
|
5
2
|
replay
|
|
6
3
|
} from "./chunk-37BBB2P2.js";
|
|
4
|
+
import {
|
|
5
|
+
isTurnTerminal
|
|
6
|
+
} from "./chunk-6EGG2OZC.js";
|
|
7
7
|
|
|
8
8
|
// src/durable-turn.ts
|
|
9
9
|
import { z } from "zod";
|
|
@@ -64,4 +64,4 @@ function createDurableTurn(deps) {
|
|
|
64
64
|
export {
|
|
65
65
|
createDurableTurn
|
|
66
66
|
};
|
|
67
|
-
//# sourceMappingURL=chunk-
|
|
67
|
+
//# sourceMappingURL=chunk-SD2ZJ7XG.js.map
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// src/cli.ts
|
|
2
|
+
import { readCapabilityDebug } from "@nebutra/capability-kit/debug";
|
|
3
|
+
var command = process.argv[2] ?? "doctor";
|
|
4
|
+
if (command === "doctor") {
|
|
5
|
+
process.stdout.write(
|
|
6
|
+
`${JSON.stringify(
|
|
7
|
+
{
|
|
8
|
+
capability: "agent-runtime",
|
|
9
|
+
ok: true,
|
|
10
|
+
checks: ["thread-turn-item", "rollout-store", "pulsar-facade", "subagent-briefs"]
|
|
11
|
+
},
|
|
12
|
+
null,
|
|
13
|
+
2
|
|
14
|
+
)}
|
|
15
|
+
`
|
|
16
|
+
);
|
|
17
|
+
} else if (command === "debug" || command === "replay") {
|
|
18
|
+
const threadId = process.argv[3];
|
|
19
|
+
process.stdout.write(
|
|
20
|
+
`${JSON.stringify(
|
|
21
|
+
{
|
|
22
|
+
capability: "agent-runtime",
|
|
23
|
+
threadId,
|
|
24
|
+
entries: await readCapabilityDebug("agent-runtime", { limit: 20 }),
|
|
25
|
+
suggestion: "Use a RolloutStore-backed host to replay full thread events; this CLI reports local debug lines."
|
|
26
|
+
},
|
|
27
|
+
null,
|
|
28
|
+
2
|
|
29
|
+
)}
|
|
30
|
+
`
|
|
31
|
+
);
|
|
32
|
+
} else if (command === "subagent-trace" || command === "subagent-cost") {
|
|
33
|
+
const threadId = process.argv[3];
|
|
34
|
+
process.stdout.write(
|
|
35
|
+
`${JSON.stringify(
|
|
36
|
+
{
|
|
37
|
+
capability: "agent-runtime",
|
|
38
|
+
command,
|
|
39
|
+
threadId,
|
|
40
|
+
entries: await readCapabilityDebug("agent-runtime", { limit: 20 })
|
|
41
|
+
},
|
|
42
|
+
null,
|
|
43
|
+
2
|
|
44
|
+
)}
|
|
45
|
+
`
|
|
46
|
+
);
|
|
47
|
+
} else {
|
|
48
|
+
process.stderr.write(`Unknown agent-runtime command: ${command}
|
|
49
|
+
`);
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import { readCapabilityDebug } from \"@nebutra/capability-kit/debug\";\n\nconst command = process.argv[2] ?? \"doctor\";\n\nif (command === \"doctor\") {\n process.stdout.write(\n `${JSON.stringify(\n {\n capability: \"agent-runtime\",\n ok: true,\n checks: [\"thread-turn-item\", \"rollout-store\", \"pulsar-facade\", \"subagent-briefs\"],\n },\n null,\n 2,\n )}\\n`,\n );\n} else if (command === \"debug\" || command === \"replay\") {\n const threadId = process.argv[3];\n process.stdout.write(\n `${JSON.stringify(\n {\n capability: \"agent-runtime\",\n threadId,\n entries: await readCapabilityDebug(\"agent-runtime\", { limit: 20 }),\n suggestion:\n \"Use a RolloutStore-backed host to replay full thread events; this CLI reports local debug lines.\",\n },\n null,\n 2,\n )}\\n`,\n );\n} else if (command === \"subagent-trace\" || command === \"subagent-cost\") {\n const threadId = process.argv[3];\n process.stdout.write(\n `${JSON.stringify(\n {\n capability: \"agent-runtime\",\n command,\n threadId,\n entries: await readCapabilityDebug(\"agent-runtime\", { limit: 20 }),\n },\n null,\n 2,\n )}\\n`,\n );\n} else {\n process.stderr.write(`Unknown agent-runtime command: ${command}\\n`);\n process.exitCode = 1;\n}\n"],"mappings":";AAAA,SAAS,2BAA2B;AAEpC,IAAM,UAAU,QAAQ,KAAK,CAAC,KAAK;AAEnC,IAAI,YAAY,UAAU;AACxB,UAAQ,OAAO;AAAA,IACb,GAAG,KAAK;AAAA,MACN;AAAA,QACE,YAAY;AAAA,QACZ,IAAI;AAAA,QACJ,QAAQ,CAAC,oBAAoB,iBAAiB,iBAAiB,iBAAiB;AAAA,MAClF;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA;AAAA,EACH;AACF,WAAW,YAAY,WAAW,YAAY,UAAU;AACtD,QAAM,WAAW,QAAQ,KAAK,CAAC;AAC/B,UAAQ,OAAO;AAAA,IACb,GAAG,KAAK;AAAA,MACN;AAAA,QACE,YAAY;AAAA,QACZ;AAAA,QACA,SAAS,MAAM,oBAAoB,iBAAiB,EAAE,OAAO,GAAG,CAAC;AAAA,QACjE,YACE;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA;AAAA,EACH;AACF,WAAW,YAAY,oBAAoB,YAAY,iBAAiB;AACtE,QAAM,WAAW,QAAQ,KAAK,CAAC;AAC/B,UAAQ,OAAO;AAAA,IACb,GAAG,KAAK;AAAA,MACN;AAAA,QACE,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA,SAAS,MAAM,oBAAoB,iBAAiB,EAAE,OAAO,GAAG,CAAC;AAAA,MACnE;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA;AAAA,EACH;AACF,OAAO;AACL,UAAQ,OAAO,MAAM,kCAAkC,OAAO;AAAA,CAAI;AAClE,UAAQ,WAAW;AACrB;","names":[]}
|
package/dist/commands.js
CHANGED
package/dist/definitions.js
CHANGED
package/dist/dispatcher.js
CHANGED
package/dist/durable-turn.js
CHANGED
package/dist/hook-pipeline.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { BodyLoader, CommandRecord, CommandRegistry, ContentBlock, ExpandedCommand, expandCommand } from './commands.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
+
import { BaseTokenEstimator } from '@nebutra/ai-primitives';
|
|
3
4
|
export { Definition, DefinitionResolver, Frontmatter, ResolveContext, SOURCE_TIERS, SourceTier, frontmatterSchema, parseFrontmatter, substituteArguments } from './definitions.js';
|
|
4
5
|
export { JsonRpcResponse, MethodHandler, NotificationListener, ProtocolDispatcher } from './dispatcher.js';
|
|
5
6
|
export { CreateDurableTurnDeps, DurableTurn, DurableTurnJob, DurableTurnQueuePort, DurableTurnRunner, TurnContext, createDurableTurn } from './durable-turn.js';
|
|
@@ -7,14 +8,17 @@ export { FunctionTransport, HookConfig, HookContext, HookEvent, HookExitResult,
|
|
|
7
8
|
export { ApprovalGate, ModelEmission, ModelInvoker, ModelRoundRequest, ModelRoundResult, RuleEvaluator, RunTurnDeps, runTurn } from './loop.js';
|
|
8
9
|
export { ActivateMcpToolsResult, McpServerCatalogPort, activateMcpTools } from './mcp-bridge.js';
|
|
9
10
|
export { AgentMessageItem, CommandExecutionItem, ErrorItem, FileChangeItem, FileUpdateChange, McpToolCallItem, PatchApplyStatus, PatchChangeKind, ReasoningItem, RunStatus, ThreadError, ThreadEvent, ThreadEventType, ThreadItem, ThreadItemType, TodoEntry, TodoListItem, TurnConfig, TurnConfigOverrides, TurnUsage, WebSearchItem, isTurnTerminal, mergeTurnConfig } from './model.js';
|
|
11
|
+
export { Brief, BudgetCap, DispatchPlan, DispatchPlanOptions, DispatchStrategy, ModelModality, NodeModelSpec, ReasoningEffort, SubagentCostReport, SubagentResult, costReport, fanOutSubagents, planSubagentDispatch, planWaves, runAgentWaves } from './orchestration.js';
|
|
12
|
+
export * from '@nebutra/execution-policy';
|
|
10
13
|
export { ApprovalPolicy, CapabilityPolicy, DEFAULT_APPROVAL_POLICY, DEFAULT_CAPABILITY_POLICY, DENIED, GranularApprovalConfig, NetworkPolicyAmendment, ReviewDecision, RuleAmendment, RuleDecision, WritableRoot, approvalPolicySchema, capabilityPolicySchema, granularApprovalConfigSchema, isApproval, resolveRuleDecision, writableRootSchema } from './policy.js';
|
|
11
14
|
export { METHOD_REGISTRY, MethodName, MethodSpec, NOTIFICATIONS, NotificationName, RequestEnvelope, ScopeRule, SerializationScope, ServerRequest, requestEnvelopeSchema, resolveScope, scopeKey } from './protocol.js';
|
|
15
|
+
export { Pulsar, PulsarBranchRecord, PulsarBuilder, PulsarDeps, PulsarEventInput, PulsarEventLogPort, PulsarThread, StartThreadOptions } from './pulsar.js';
|
|
12
16
|
export { EventPersistenceMode, InMemoryRolloutStore, PERSISTED_OUTPUT_MAX_BYTES, RolloutLine, RolloutStore, ThreadProjection, isPersisted, replay, sanitizeForPersist } from './rollout.js';
|
|
13
17
|
export { PersistentRolloutStore, RolloutPersistencePort, RoundTripError } from './rollout-store-persistent.js';
|
|
14
18
|
export { ExternalSandbox, NoExecutorConfiguredError, REFUSING_SANDBOX, SandboxDelegationError, SandboxExecRequest, SandboxExecResult, assertSafePosture, createHttpSandbox } from './sandbox.js';
|
|
15
19
|
export { ExpandContext, ExpandedSkill, SkillListing, SkillListingEntry, SkillListingOptions, SkillMessage, SkillRecord, buildSkillListing, expandSkill } from './skills.js';
|
|
16
20
|
export { DeferredEnvelope, DispatchCtx, DispatchEnvelope, DispatchMode, PrepareDispatchInput, PreparedDispatch, SettleDeferredTarget, SubagentRecord, SyncEnvelope, TASK_KINDS, TASK_STATUSES, TaskKind, TaskRecord, TaskRegistry, TaskStatus, assertNotPeeking, makeDeferred, prepareDispatch, resolveSubagentTools, settleDeferred } from './subagents.js';
|
|
17
|
-
export { McpClientLike, RegisteredTool, ToolDefinition, ToolDispatchContext, ToolHandler, ToolHooks, ToolOrigin, ToolRegistry, adaptMcpTool } from './tools.js';
|
|
21
|
+
export { McpClientLike, RegisteredTool, RuntimeToolRegistry, ToolDefinition, ToolDispatchContext, ToolHandler, ToolHooks, ToolOrigin, RuntimeToolRegistry as ToolRegistry, adaptMcpTool } from './tools.js';
|
|
18
22
|
|
|
19
23
|
/**
|
|
20
24
|
* Streaming artifact/action protocol.
|
|
@@ -711,6 +715,7 @@ declare function generateCommitMessage(args: {
|
|
|
711
715
|
* transcript plus the injected `summarize` and `base` estimator. The transcript
|
|
712
716
|
* is never mutated; every transformation builds new arrays/strings.
|
|
713
717
|
*/
|
|
718
|
+
|
|
714
719
|
/** Tokenizers undercount real BPE by ~15-30%; scale the base estimate up. */
|
|
715
720
|
declare const TOKEN_CORRECTION = 1.3;
|
|
716
721
|
/** Fraction of the usable window the recap is allowed to occupy. */
|
|
@@ -753,7 +758,7 @@ type Transcript = readonly Message[];
|
|
|
753
758
|
*/
|
|
754
759
|
type Summarize = (prompt: string) => Promise<string>;
|
|
755
760
|
/** Caller-injected cheap token heuristic; defaults to chars/4. */
|
|
756
|
-
type BaseEstimator =
|
|
761
|
+
type BaseEstimator = BaseTokenEstimator;
|
|
757
762
|
/** The eligibility signal this module keys on (also the failure sentinel). */
|
|
758
763
|
declare const COMPACT_SENTINEL = "compact";
|
|
759
764
|
/**
|
|
@@ -1312,88 +1317,6 @@ declare class MemoryManager {
|
|
|
1312
1317
|
shutdown(): Promise<void>;
|
|
1313
1318
|
}
|
|
1314
1319
|
|
|
1315
|
-
/**
|
|
1316
|
-
* Permission ruleset evaluator.
|
|
1317
|
-
*
|
|
1318
|
-
* A small, pure, stateless re-expression of a two-dimensional wildcard
|
|
1319
|
-
* permission model plus a bash-command-prefix extractor. No global state,
|
|
1320
|
-
* no I/O, no mutation of inputs — every function is referentially transparent.
|
|
1321
|
-
*
|
|
1322
|
-
* The model has two independent dimensions per rule:
|
|
1323
|
-
* - `permission` — the capability namespace (e.g. "bash", "edit", "net")
|
|
1324
|
-
* - `pattern` — the concrete subject within that namespace
|
|
1325
|
-
* A rule applies only when BOTH dimensions match the query via {@link wildcardMatch}.
|
|
1326
|
-
*/
|
|
1327
|
-
/** The decision a rule yields. Unknown queries fail safe to "ask". */
|
|
1328
|
-
type Action = "allow" | "deny" | "ask";
|
|
1329
|
-
/** A single permission rule. Both dimensions are matched as wildcard globs. */
|
|
1330
|
-
interface Rule {
|
|
1331
|
-
permission: string;
|
|
1332
|
-
pattern: string;
|
|
1333
|
-
action: Action;
|
|
1334
|
-
}
|
|
1335
|
-
/** An ordered list of rules. Earlier rules take precedence. */
|
|
1336
|
-
type Ruleset = Rule[];
|
|
1337
|
-
/**
|
|
1338
|
-
* Anchored full-string glob matcher.
|
|
1339
|
-
*
|
|
1340
|
-
* Semantics:
|
|
1341
|
-
* - `*` matches any run of characters, including the empty run.
|
|
1342
|
-
* - `?` matches exactly one character.
|
|
1343
|
-
* - Every other character is matched literally (regex metacharacters in
|
|
1344
|
-
* `pattern` carry no special meaning).
|
|
1345
|
-
* - The match is anchored: the entire `str` must be consumed.
|
|
1346
|
-
*
|
|
1347
|
-
* Special rule (ported faithfully): if `pattern` ends with `" *"` (a single
|
|
1348
|
-
* space immediately followed by `*`), that trailing ` *` is OPTIONAL. The
|
|
1349
|
-
* pattern then matches both `"<head> <rest>"` and exactly `"<head>"` with
|
|
1350
|
-
* nothing after it. For example `"git *"` matches `"git"` and `"git status"`.
|
|
1351
|
-
*
|
|
1352
|
-
* Implemented with a backtracking two-pointer scan whose `*` handling uses a
|
|
1353
|
-
* single saved restart position, giving O(|str| * |pattern|) worst case with
|
|
1354
|
-
* no catastrophic blow-up.
|
|
1355
|
-
*/
|
|
1356
|
-
declare function wildcardMatch(str: string, pattern: string): boolean;
|
|
1357
|
-
/**
|
|
1358
|
-
* Resolve a permission query against one or more rulesets.
|
|
1359
|
-
*
|
|
1360
|
-
* Rulesets are concatenated in argument order (no mutation) and scanned
|
|
1361
|
-
* front-to-back. The FIRST rule whose `permission` and `pattern` both match
|
|
1362
|
-
* the query (via {@link wildcardMatch}) is returned. If no rule matches, a
|
|
1363
|
-
* fail-safe default is returned: the queried permission/pattern with action
|
|
1364
|
-
* `"ask"` (unknown → ask, never silently allow).
|
|
1365
|
-
*/
|
|
1366
|
-
declare function evaluate(permission: string, pattern: string, ...rulesets: Ruleset[]): Rule;
|
|
1367
|
-
/**
|
|
1368
|
-
* Built-in command arity table. Maps a (possibly multi-word) command prefix
|
|
1369
|
-
* to the number of leading tokens that constitute its "human-understandable
|
|
1370
|
-
* command" for permission matching. Longest matching prefix wins.
|
|
1371
|
-
*
|
|
1372
|
-
* Frozen so the shared default cannot be mutated by callers.
|
|
1373
|
-
*/
|
|
1374
|
-
declare const BUILTIN_ARITY: Readonly<Record<string, number>>;
|
|
1375
|
-
/**
|
|
1376
|
-
* Extract the human-understandable command from already-split, flag-free
|
|
1377
|
-
* shell tokens.
|
|
1378
|
-
*
|
|
1379
|
-
* Strategy: try the longest prefix first. For `len` from `tokens.length` down
|
|
1380
|
-
* to 1, if `tokens.slice(0, len).join(" ")` is a key in the (merged) arity
|
|
1381
|
-
* table, return `tokens.slice(0, arity[thatPrefix])`. If the tokens are empty,
|
|
1382
|
-
* return `[]`. Otherwise default to the first token only.
|
|
1383
|
-
*
|
|
1384
|
-
* `arity` is shallow-merged OVER the built-in table; neither the caller's
|
|
1385
|
-
* object nor the built-in table is mutated.
|
|
1386
|
-
*/
|
|
1387
|
-
declare function commandPrefix(tokens: string[], arity?: Record<string, number> | undefined): string[];
|
|
1388
|
-
/**
|
|
1389
|
-
* Derive the `pattern` to feed {@link evaluate} for a bash permission.
|
|
1390
|
-
*
|
|
1391
|
-
* Splits `command` on arbitrary whitespace, drops tokens that begin with `-`
|
|
1392
|
-
* (flags are not conceptually part of the command identity), applies
|
|
1393
|
-
* {@link commandPrefix}, and joins the result with single spaces.
|
|
1394
|
-
*/
|
|
1395
|
-
declare function commandPermissionKey(command: string): string;
|
|
1396
|
-
|
|
1397
1320
|
/**
|
|
1398
1321
|
* Git-backed project repository model.
|
|
1399
1322
|
*
|
|
@@ -1871,4 +1794,4 @@ declare class InMemoryProjectStore implements ProjectPersistencePort {
|
|
|
1871
1794
|
get(tenant: string, project: string): Promise<Project | undefined>;
|
|
1872
1795
|
}
|
|
1873
1796
|
|
|
1874
|
-
export { type
|
|
1797
|
+
export { type ActionEvent, type ActionPorts, ActionRunner, type ActionState, type ActionStatus, type AdmissionDeps, type AdmissionPolicy, type AdmissionReason, type AdmissionResult, type AllowlistMatch, type ApplyEditResult, type ArtifactEvent, type ArtifactStreamCallbacks, ArtifactStreamParser, BUDGET_RATIO, type BaseEstimator, type BuildAction, CLIP_TEXT_CHARS, CLIP_TOOL_CHARS, COMPACT_SENTINEL, CONCURRENCY, CONVERSATIONS_DIR, type ChannelAdapter, type ChannelCapabilities, ChannelGateway, type ChannelId, type ChannelMeta, ChannelRegistry, type ChatType, type Clock, CommitMessageError, type CommitRef, type CompactTranscriptInput, type CompiledAllowlist, type CompletionModel, type ConversationSummary, DEFAULT_ABORT_MS, DEFAULT_TEMPERATURE, type DataAction, type DebounceResult, type DeployState, type DeploymentCommitRef, type DeploymentRecord, type DeploymentState, DeploymentStateError, type DeploymentSummary, type DeploymentTimelineEntry, type DeploymentUiStatus, type DesignContext, type DiffFile, type DiffResult, type DistillOptions, type DistilledSkill, type DistilledSkillFrontmatter, type DistilledSkillProvenance, DuplicateChannelError, type EditBlock, type EditIntent, type EditMerger, EditType, type EligibilityOptions, type FileAction, type FileContext, type FileEntry, type FileInfo, type FileKind, type FileManifest, type FileMap, type FileMutationInput, type FuzzyMatch, type FuzzyMatchFn, type GenerateOptions, type GitContext, type GitHostPort, type GroupBinding, type Hunk, type IdMint, InMemoryProjectStore, InMemoryShareStore, InMemorySuggestionHistoryStore, type InboundAttachment, InboundDebouncer, type InboundLike, type InboundMessage, LARGE_SET, type LatestStatusInput, MAX_RETRIES, MEMORY_CONTEXT_BANNER_CLOSE, MEMORY_CONTEXT_BANNER_OPEN, METADATA_PATH, MIN_BUDGET, type MatchClassification, type MatchType, type MemoryContext, MemoryManager, type MemoryProvider, type MentionContext, type Message, type NudgeOptions, OUTPUT_TOKEN_CAP, type OutboundMessage, type OwnsRepoPredicate, type Part, type PlanAction, type Project, type ProjectDiff, type ProjectMetadata, type ProjectPersistencePort, ProjectRepo, type ProjectRepoDeps, ProjectRepoError, type ProjectRepoErrorCode, type ProjectSnapshot, REDUCE_DEPTH, type RankOptions, type RankedFuzzyResult, type RankedSuggestion, type RawScrapeResult, type ReplyOptions, type ReviewFinding, type ReviewModel, ReviewParseError, type ReviewScope, type RunQueueOptions, type ScrapeFormat, type ScrapeProvider, type SessionKeyOptions, type SessionRef, SessionShare, type SessionShareOptions, ShareDisabledError, type ShareRecord, type ShareStore, type ShareSyncEvent, type ShellAction, SnapshotHistory, type StartAction, StreamingContextScrubber, type SuggestionHistoryStore, type SuggestionItem, type SuggestionResults, type SuggestionType, type Summarize, type SyncSink, type Synthesizer, TOKEN_CORRECTION, type TenantContext, TenantMismatchError, type TextPart, type TimelineOpts, type ToolPart, type Trajectory, type TrajectoryStep, type Transcript, UnknownChannelError, type UrlBuilder, type ViewerVerdict, WorkbenchError, admitInbound, advanceState, analyzeEditIntent, appendJsonlLine, applyEditBlock, applyFileMutation, asChannelId, assertTenantContext, buildCommitPrompt, buildDistillationPrompt, buildEditInstructions, buildImprovementPrompt, buildMemoryContextBlock, buildReviewPrompt, classifyMatch, compactTranscript, compileAllowlist, computeBudget, constantTimeEquals, dedupeByText, deriveLatestStatus, deriveTimelineFromCommits, diffProjects, distillSkill, domainForCommit, emptyFileMap, emptyProjectMetadata, estimateTokens, fallbackMerger, generateCommitMessage, getDeploymentStatus, getDeploymentTimeline, getFile, hasMention, historyCandidates, improveSkill, ingestDesignContext, isDistillable, kebab, listFiles, makeProject, matchIndices, matchIndicesCaseInsensitive, matchIndicesCaseInsensitiveIgnoreSpaces, matchWildcardPattern, matchWildcardPatternCaseInsensitive, matchesAllowlist, nextMode, normalizeScrapeResult, parseDiff, parseEditBlocks, parseFindings, parseJsonl, planEdit, rankByFuzzy, rankSuggestions, recordHistory, removeFile, renderClipped, replyTo, requiresMention, resolveBranchBase, resolveSessionKey, restore, runReview, sanitizeContext, selectFilesForEdit, setFile, shouldCompact, shouldNudgePersist, snapshot, split, stripFencedWrapper, stripFormatting, toGenerationSeed, unescapeEntities };
|