@vimhead.dev/norn-cli 0.1.0-tip.35390859630.1 → 0.1.0-tip.35436871363.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/assets/README.md +8 -4
- package/assets/docs/README.md +4 -4
- package/assets/docs/agents.md +37 -9
- package/assets/docs/cli.md +3 -3
- package/assets/docs/composition.md +12 -12
- package/assets/docs/persistence.md +31 -17
- package/assets/docs/providers.md +2 -2
- package/assets/docs/workflows.md +15 -10
- package/assets/examples/agent-then-analysis/README.md +8 -8
- package/assets/examples/agent-then-analysis/plugin.ts +18 -16
- package/assets/examples/caller-selected-continuation/README.md +11 -10
- package/assets/examples/caller-selected-continuation/caller.ts +12 -10
- package/assets/examples/caller-selected-continuation/producer.ts +9 -6
- package/assets/examples/coordinating-multiple-agents/README.md +26 -16
- package/assets/examples/coordinating-multiple-agents/plugin.ts +58 -35
- package/assets/examples/coordinating-multiple-agents/queue-tools.ts +43 -0
- package/assets/examples/coordinating-multiple-agents/work-queue.ts +60 -65
- package/assets/examples/getting-started/README.md +2 -2
- package/assets/examples/getting-started/plugin.ts +7 -3
- package/assets/examples/minimal-workflow/README.md +5 -4
- package/assets/examples/minimal-workflow/plugin.ts +7 -4
- package/assets/examples/shared-state/README.md +5 -5
- package/assets/examples/shared-state/plugin.ts +35 -22
- package/assets/examples/shared-state/shared-state.ts +30 -49
- package/assets/examples/shared-state/state-tools.ts +68 -0
- package/assets/examples/worktree-development-loop/README.md +14 -12
- package/assets/examples/worktree-development-loop/workflows/development-loop/execute.ts +2 -2
- package/assets/examples/worktree-development-loop/workflows/development-loop/repository.ts +5 -3
- package/assets/examples/worktree-development-loop/workflows/implementation/execute.ts +8 -7
- package/assets/examples/worktree-development-loop/workflows/implementation/schema.ts +2 -3
- package/assets/examples/worktree-development-loop/workflows/planning/execute.ts +8 -4
- package/assets/examples/worktree-development-loop/workflows/review/execute.ts +10 -7
- package/assets/examples/worktree-development-loop/workflows/review/schema.ts +1 -2
- package/assets/examples/worktree-development-loop/workflows/review-router/execute.ts +15 -14
- package/assets/examples/worktree-development-loop/workflows/review-router/schema.ts +1 -2
- package/assets/package.json +1 -1
- package/assets/packages/cli/src/cli.ts +9 -3
- package/assets/packages/cli/src/generated-build-info.ts +2 -2
- package/assets/packages/cli/src/internal/agents.ts +24 -32
- package/assets/packages/cli/src/internal/commands.ts +2 -14
- package/assets/packages/cli/src/internal/engine.ts +30 -44
- package/assets/packages/cli/src/internal/logs.ts +1 -1
- package/assets/packages/cli/src/internal/run-log.ts +1 -1
- package/assets/packages/cli/src/internal/run-state.ts +7 -2
- package/assets/packages/cli/src/internal/run.ts +2 -57
- package/assets/packages/cli/src/internal/worker-directory.ts +17 -0
- package/assets/packages/cli/src/internal/workflow-registry.ts +20 -8
- package/assets/packages/cli/src/internal/working-directory.ts +6 -0
- package/assets/packages/cli/src/workflow-loader.ts +1 -2
- package/assets/packages/sdk/src/api.ts +27 -59
- package/assets/packages/sdk/src/index.ts +0 -3
- package/assets/tests/workflow-ref.test.ts +6 -7
- package/dist/cli.js +8 -3
- package/dist/generated-build-info.d.ts +2 -2
- package/dist/generated-build-info.js +2 -2
- package/dist/internal/agents.d.ts +0 -4
- package/dist/internal/agents.js +30 -46
- package/dist/internal/commands.d.ts +0 -4
- package/dist/internal/commands.js +2 -10
- package/dist/internal/engine.js +26 -40
- package/dist/internal/file-coordinator.d.ts +17 -0
- package/dist/internal/file-coordinator.js +162 -0
- package/dist/internal/logs.d.ts +1 -1
- package/dist/internal/run-log.d.ts +1 -1
- package/dist/internal/run-state.d.ts +2 -0
- package/dist/internal/run-state.js +5 -2
- package/dist/internal/run.d.ts +2 -20
- package/dist/internal/run.js +1 -45
- package/dist/internal/worker-directory.d.ts +1 -0
- package/dist/internal/worker-directory.js +26 -0
- package/dist/internal/workflow-registry.d.ts +13 -3
- package/dist/internal/workflow-registry.js +8 -6
- package/dist/internal/working-directory.d.ts +1 -0
- package/dist/internal/working-directory.js +9 -0
- package/dist/workflow-loader.js +1 -2
- package/package.json +2 -2
- package/assets/docs/resources.md +0 -46
- package/assets/examples/coordinating-multiple-agents/queue-adapter.ts +0 -51
- package/assets/examples/shared-state/state-adapter.ts +0 -76
- package/assets/packages/cli/src/internal/artifacts.ts +0 -26
- package/assets/packages/cli/src/internal/resource-bindings.ts +0 -35
- package/assets/packages/cli/src/resources.ts +0 -69
- package/assets/packages/sdk/src/agent-resource-adapter.ts +0 -11
- package/assets/packages/sdk/src/resources.ts +0 -20
- package/dist/internal/artifacts.d.ts +0 -10
- package/dist/internal/artifacts.js +0 -29
- package/dist/internal/resource-bindings.d.ts +0 -13
- package/dist/internal/resource-bindings.js +0 -34
- package/dist/resources.d.ts +0 -11
- package/dist/resources.js +0 -100
- /package/assets/packages/{sdk/src/files.ts → cli/src/internal/file-coordinator.ts} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isWorkflowComplete, isWorkflowDeclaration, isWorkflowFail, isWorkflowNext, type NornAnyWorkflowDeclaration, type NornDispose, type NornInspectedWorkflowInfo, type NornRegisteredWorkflowInfo, type NornRunComplete, type NornRunFail, type
|
|
1
|
+
import { isWorkflowComplete, isWorkflowDeclaration, isWorkflowFail, isWorkflowNext, type NornAnyWorkflowDeclaration, type NornDispose, type NornInspectedWorkflowInfo, type NornRegisteredWorkflowInfo, type NornRunComplete, type NornRunFail, type NornRun, type NornRunNext, type NornWorkflowPaths, type NornWorkflowContext, type NornWorkflowGateInfo, type NornWorkflowSource, type NornWorkflowScopeInfo, type NornProjectConfigurationInfo } from "@vimhead.dev/norn";
|
|
2
2
|
import { assertWorkflowMetadata, inspectSchema, isPlainObject, schemaShape, schemaType, unwrapSchema } from "@vimhead.dev/norn/schema";
|
|
3
3
|
import type { TSchema } from "typebox";
|
|
4
4
|
import { Value } from "typebox/value";
|
|
@@ -42,6 +42,15 @@ export type NornWorkflowStepResult =
|
|
|
42
42
|
| { readonly type: "complete"; readonly workflow: NornAnyWorkflowDeclaration; readonly metadata?: NornRunComplete["metadata"] }
|
|
43
43
|
| { readonly type: "fail"; readonly workflow: NornAnyWorkflowDeclaration; readonly metadata: NornRunFail["metadata"] };
|
|
44
44
|
|
|
45
|
+
type NornExecutionContextInput = {
|
|
46
|
+
readonly run: NornRun;
|
|
47
|
+
readonly paths: NornWorkflowPaths;
|
|
48
|
+
readonly args: unknown;
|
|
49
|
+
readonly configOverride: unknown;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
type NornWorkflowExecutionInput = NornExecutionContextInput & { readonly workflow: NornAnyWorkflowDeclaration };
|
|
53
|
+
|
|
45
54
|
export class NornWorkflowRegistry {
|
|
46
55
|
private readonly entries = new Map<string, NornRegisteredWorkflow>();
|
|
47
56
|
private readonly scopes = new Map<string, NornRegisteredScope>();
|
|
@@ -99,31 +108,34 @@ export class NornWorkflowRegistry {
|
|
|
99
108
|
launchableEntries(): NornRegisteredWorkflow[] { return this.sortedEntries().filter(({ workflow }) => workflow.isEntrypoint); }
|
|
100
109
|
workflowById(workflowId: string): NornAnyWorkflowDeclaration | undefined { return this.entries.get(workflowId)?.workflow; }
|
|
101
110
|
|
|
102
|
-
async describeGate
|
|
111
|
+
async describeGate(input: NornWorkflowExecutionInput): Promise<string> {
|
|
112
|
+
const { workflow } = input;
|
|
103
113
|
const entry = this.requireEntry(workflow.id);
|
|
104
114
|
if (!workflow.gate) throw new Error(`Workflow is not gated: ${workflow.id}`);
|
|
105
|
-
const context = this.createExecutionContext({
|
|
115
|
+
const context = this.createExecutionContext({ ...input, entry });
|
|
106
116
|
const description = await entry.workflow.gate?.describe?.(context) ?? workflow.id;
|
|
107
117
|
if (typeof description !== "string" || description.trim().length === 0) throw new Error(`Workflow gate description must not be empty: ${workflow.id}`);
|
|
108
118
|
return description.trim();
|
|
109
119
|
}
|
|
110
120
|
|
|
111
|
-
async execute
|
|
121
|
+
async execute(input: NornWorkflowExecutionInput): Promise<NornWorkflowStepResult> {
|
|
122
|
+
const { workflow } = input;
|
|
112
123
|
const entry = this.requireEntry(workflow.id);
|
|
113
|
-
const result = await entry.workflow.execute(this.createExecutionContext({
|
|
124
|
+
const result = await entry.workflow.execute(this.createExecutionContext({ ...input, entry }));
|
|
114
125
|
if (isWorkflowNext(result)) return result;
|
|
115
126
|
if (isWorkflowComplete(result)) return { type: "complete", workflow, metadata: result.metadata };
|
|
116
127
|
if (isWorkflowFail(result)) return { type: "fail", workflow, metadata: result.metadata };
|
|
117
128
|
throw new Error(`Workflow returned invalid control result: ${workflow.id}`);
|
|
118
129
|
}
|
|
119
130
|
|
|
120
|
-
private createExecutionContext(input: { readonly entry: NornRegisteredWorkflow
|
|
121
|
-
const { entry, run, configOverride } = input;
|
|
131
|
+
private createExecutionContext(input: NornExecutionContextInput & { readonly entry: NornRegisteredWorkflow }): NornWorkflowContext {
|
|
132
|
+
const { entry, run, paths, configOverride } = input;
|
|
122
133
|
const scope = entry.scopeId ? this.scopes.get(entry.scopeId) : undefined;
|
|
123
134
|
return {
|
|
124
135
|
args: Value.Decode(entry.workflow.args, input.args),
|
|
125
136
|
config: parseExecutionConfig(entry.configuration, configOverride),
|
|
126
137
|
...(scope ? { scope: { id: scope.definition.id, config: parseExecutionConfig(scope.configuration, configOverride) } } : {}),
|
|
138
|
+
paths,
|
|
127
139
|
run,
|
|
128
140
|
};
|
|
129
141
|
}
|
|
@@ -175,7 +187,7 @@ function assertGateWorkflow(workflow: NornAnyWorkflowDeclaration): void {
|
|
|
175
187
|
function workflowInfo(entry: NornRegisteredWorkflow): NornRegisteredWorkflowInfo {
|
|
176
188
|
return {
|
|
177
189
|
id: entry.workflow.id, instructions: entry.workflow.instructions, isEntrypoint: entry.workflow.isEntrypoint,
|
|
178
|
-
|
|
190
|
+
source: entry.source,
|
|
179
191
|
configKey: entry.workflow.id,
|
|
180
192
|
scope: entry.scopeId ? { id: entry.scopeId } : undefined,
|
|
181
193
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { isAbsolute, resolve } from "node:path";
|
|
2
|
+
|
|
3
|
+
export function requireAbsoluteWorkingDirectory(cwd: string): string {
|
|
4
|
+
if (typeof cwd !== "string" || !isAbsolute(cwd)) throw new Error("Working directory (cwd) must be an absolute path");
|
|
5
|
+
return resolve(cwd);
|
|
6
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as nornModule from "@vimhead.dev/norn";
|
|
2
2
|
import { isWorkflowDeclaration, type NornAnyWorkflowDeclaration, type NornDispose, type NornWorkflowDiagnostic, type NornProjectInfo, type NornProjectInspection, type NornProjectConfigurationInfo, type NornWorkflowCatalogInfo, type NornWorkflowInspection, type NornWorkflowSource } from "@vimhead.dev/norn";
|
|
3
3
|
import { isNodeError } from "@vimhead.dev/norn-core/errors";
|
|
4
|
-
import * as nornFilesModule from "@vimhead.dev/norn/files";
|
|
5
4
|
import * as nornSchemaModule from "@vimhead.dev/norn/schema";
|
|
6
5
|
import { inspectSchema, isPlainObject } from "@vimhead.dev/norn/schema";
|
|
7
6
|
import { createJiti, type ModuleCache } from "jiti/static";
|
|
@@ -178,7 +177,7 @@ function createDiagnostic(input: { readonly source: NornWorkflowSource; readonly
|
|
|
178
177
|
return { configPath: input.source.configPath, modulePath: input.source.path, scopeId: input.scopeId, workflowId: input.workflowId, stage: input.stage, message: errorMessage(input.error), issues: input.error instanceof AssertError ? input.error.cause.errors : [] };
|
|
179
178
|
}
|
|
180
179
|
function nornWorkflowVirtualModules(): Record<string, unknown> {
|
|
181
|
-
return { "@vimhead.dev/norn": nornModule, "@vimhead.dev/norn/
|
|
180
|
+
return { "@vimhead.dev/norn": nornModule, "@vimhead.dev/norn/schema": nornSchemaModule, typebox: typeboxModule, "typebox/value": typeboxValueModule, "typebox/compile": typeboxCompileModule, "typebox/schema": typeboxSchemaModule };
|
|
182
181
|
}
|
|
183
182
|
function mergeProjectConfig(files: readonly NornConfigFile[]): Record<string, unknown> {
|
|
184
183
|
const [project, ...reusable] = files;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CreateAgentSessionOptions, EventBus, PromptOptions } from "@earendil-works/pi-coding-agent";
|
|
1
|
+
import type { CreateAgentSessionOptions, EventBus, PromptOptions, ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Type, type StaticDecode, type StaticEncode, type TCodec, type TSchema } from "typebox";
|
|
3
3
|
import type { TLocalizedValidationError } from "typebox/error";
|
|
4
4
|
import { createWorkflowTransition } from "@vimhead.dev/norn-core/workflow-transition";
|
|
@@ -15,16 +15,17 @@ export type NornWorkflowAnyGate = {
|
|
|
15
15
|
readonly fields?: readonly string[];
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
export type
|
|
18
|
+
export type NornWorkflowPaths = {
|
|
19
|
+
/** Absolute project root. Excluded from run checkpoints and rollback. */
|
|
20
|
+
readonly project: string;
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
readonly
|
|
22
|
+
/** Absolute, initially empty workspace. Saved in run checkpoints and restored on rollback. */
|
|
23
|
+
readonly workspace: string;
|
|
22
24
|
};
|
|
23
25
|
|
|
24
26
|
export type NornWorkflowDeclaration<
|
|
25
27
|
Id extends string = string,
|
|
26
28
|
ArgsSchema extends TSchema = TSchema,
|
|
27
|
-
IsolationMode extends NornWorkflowIsolationMode = NornWorkflowIsolationMode,
|
|
28
29
|
ConfigSchema extends TSchema | undefined = TSchema | undefined,
|
|
29
30
|
Scope extends NornWorkflowScopeInfo | undefined = NornWorkflowScopeInfo | undefined,
|
|
30
31
|
> = {
|
|
@@ -35,12 +36,11 @@ export type NornWorkflowDeclaration<
|
|
|
35
36
|
readonly instructions?: string;
|
|
36
37
|
readonly args: ArgsSchema;
|
|
37
38
|
readonly gate?: NornWorkflowGate<ArgsSchema> & {
|
|
38
|
-
describe?(context: NornWorkflowContext<ArgsSchema,
|
|
39
|
+
describe?(context: NornWorkflowContext<ArgsSchema, ConfigSchema, Scope>): MaybePromise<string>;
|
|
39
40
|
};
|
|
40
|
-
readonly isolation: NornWorkflowIsolation<IsolationMode>;
|
|
41
41
|
readonly config?: ConfigSchema;
|
|
42
42
|
readonly scope: Scope;
|
|
43
|
-
execute(context: NornWorkflowContext<ArgsSchema,
|
|
43
|
+
execute(context: NornWorkflowContext<ArgsSchema, ConfigSchema, Scope>): MaybePromise<WorkflowResult>;
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
export type NornAnyWorkflowDeclaration = Pick<NornWorkflowDeclaration, keyof NornWorkflowDeclaration> & ((args: never) => NornRunNext);
|
|
@@ -69,18 +69,17 @@ type NornWorkflowInstructions =
|
|
|
69
69
|
| { readonly isEntrypoint: true; readonly instructions: string }
|
|
70
70
|
| { readonly isEntrypoint: false; readonly instructions?: string };
|
|
71
71
|
|
|
72
|
-
type RunForIsolation<Mode extends NornWorkflowIsolationMode> = Mode extends "project" ? NornProjectRun : NornRun;
|
|
73
72
|
type WorkflowConfig<Schema extends TSchema | undefined> = Schema extends TSchema ? StaticDecode<Schema> : undefined;
|
|
74
73
|
|
|
75
74
|
export type NornWorkflowContext<
|
|
76
75
|
ArgsSchema extends TSchema = TSchema,
|
|
77
|
-
Mode extends NornWorkflowIsolationMode = NornWorkflowIsolationMode,
|
|
78
76
|
ConfigSchema extends TSchema | undefined = TSchema | undefined,
|
|
79
77
|
Scope extends NornWorkflowScopeInfo | undefined = NornWorkflowScopeInfo | undefined,
|
|
80
78
|
> = {
|
|
81
79
|
readonly args: StaticDecode<ArgsSchema>;
|
|
82
80
|
readonly config: WorkflowConfig<ConfigSchema>;
|
|
83
|
-
readonly
|
|
81
|
+
readonly paths: NornWorkflowPaths;
|
|
82
|
+
readonly run: NornRun;
|
|
84
83
|
} & (Scope extends NornWorkflowScopeInfo ? {
|
|
85
84
|
readonly scope: { readonly id: Scope["id"]; readonly config: WorkflowConfig<Scope["config"]> };
|
|
86
85
|
} : {});
|
|
@@ -88,18 +87,16 @@ export type NornWorkflowContext<
|
|
|
88
87
|
export type NornWorkflowDefinition<
|
|
89
88
|
Id extends string = string,
|
|
90
89
|
ArgsSchema extends TSchema = TSchema,
|
|
91
|
-
IsolationMode extends NornWorkflowIsolationMode = NornWorkflowIsolationMode,
|
|
92
90
|
ConfigSchema extends TSchema | undefined = undefined,
|
|
93
91
|
Scope extends NornWorkflowScopeInfo | undefined = undefined,
|
|
94
92
|
> = {
|
|
95
93
|
readonly id: Id;
|
|
96
94
|
readonly args: ArgsSchema;
|
|
97
95
|
readonly config?: ConfigSchema;
|
|
98
|
-
readonly isolation?: NornWorkflowIsolation<IsolationMode>;
|
|
99
96
|
readonly gate?: NornWorkflowGate<ArgsSchema> & {
|
|
100
|
-
describe?(context: NornWorkflowContext<ArgsSchema,
|
|
97
|
+
describe?(context: NornWorkflowContext<ArgsSchema, ConfigSchema, Scope>): MaybePromise<string>;
|
|
101
98
|
};
|
|
102
|
-
execute(context: NornWorkflowContext<ArgsSchema,
|
|
99
|
+
execute(context: NornWorkflowContext<ArgsSchema, ConfigSchema, Scope>): MaybePromise<WorkflowResult>;
|
|
103
100
|
} & NornWorkflowInstructions;
|
|
104
101
|
|
|
105
102
|
export type NornWorkflowScopeInfo = {
|
|
@@ -110,31 +107,29 @@ export type NornWorkflowScopeInfo = {
|
|
|
110
107
|
export type NornWorkflowScope<Id extends string, ConfigSchema extends TSchema | undefined> = {
|
|
111
108
|
readonly id: Id;
|
|
112
109
|
readonly config: ConfigSchema;
|
|
113
|
-
workflow<const LocalId extends string, ArgsSchema extends TSchema,
|
|
114
|
-
definition: NornWorkflowDefinition<LocalId, ArgsSchema,
|
|
115
|
-
): NornWorkflowDeclaration<`${Id}.${LocalId}`, ArgsSchema,
|
|
110
|
+
workflow<const LocalId extends string, ArgsSchema extends TSchema, LocalConfig extends TSchema | undefined = undefined>(
|
|
111
|
+
definition: NornWorkflowDefinition<LocalId, ArgsSchema, LocalConfig, { readonly id: Id; readonly config: ConfigSchema }>,
|
|
112
|
+
): NornWorkflowDeclaration<`${Id}.${LocalId}`, ArgsSchema, LocalConfig, { readonly id: Id; readonly config: ConfigSchema }>;
|
|
116
113
|
};
|
|
117
114
|
|
|
118
115
|
export function workflow<
|
|
119
116
|
const Id extends string,
|
|
120
117
|
ArgsSchema extends TSchema,
|
|
121
|
-
const Mode extends NornWorkflowIsolationMode = "runWorkspace",
|
|
122
118
|
ConfigSchema extends TSchema | undefined = undefined,
|
|
123
|
-
>(definition: NornWorkflowDefinition<Id, ArgsSchema,
|
|
119
|
+
>(definition: NornWorkflowDefinition<Id, ArgsSchema, ConfigSchema>): NornWorkflowDeclaration<Id, ArgsSchema, ConfigSchema, undefined> {
|
|
124
120
|
return createWorkflow({ definition, scope: undefined });
|
|
125
121
|
}
|
|
126
122
|
|
|
127
|
-
function createWorkflow<Id extends string, ArgsSchema extends TSchema,
|
|
128
|
-
input: { readonly definition: NornWorkflowDefinition<Id, ArgsSchema,
|
|
129
|
-
): NornWorkflowDeclaration<Id, ArgsSchema,
|
|
123
|
+
function createWorkflow<Id extends string, ArgsSchema extends TSchema, ConfigSchema extends TSchema | undefined, Scope extends NornWorkflowScopeInfo | undefined>(
|
|
124
|
+
input: { readonly definition: NornWorkflowDefinition<Id, ArgsSchema, ConfigSchema, Scope>; readonly scope: Scope },
|
|
125
|
+
): NornWorkflowDeclaration<Id, ArgsSchema, ConfigSchema, Scope> {
|
|
130
126
|
const { definition, scope } = input;
|
|
131
127
|
assertDeclarationId(definition.id);
|
|
132
128
|
const callable = (args: StaticEncode<ArgsSchema>): NornRunNext => createWorkflowTransition({ workflowId: definition.id, args });
|
|
133
129
|
const result = Object.assign(callable, definition, {
|
|
134
130
|
kind: WORKFLOW_DECLARATION_KIND,
|
|
135
131
|
scope,
|
|
136
|
-
|
|
137
|
-
}) as NornWorkflowDeclaration<Id, ArgsSchema, Mode, ConfigSchema, Scope>;
|
|
132
|
+
}) as NornWorkflowDeclaration<Id, ArgsSchema, ConfigSchema, Scope>;
|
|
138
133
|
if (!isWorkflowDeclaration(result)) throw new Error(`Invalid workflow definition: ${definition.id}`);
|
|
139
134
|
assertWorkflowMetadata(result);
|
|
140
135
|
return result;
|
|
@@ -163,7 +158,6 @@ export type NornRunNext = {
|
|
|
163
158
|
|
|
164
159
|
export type NornRunOutcomeMetadata = {
|
|
165
160
|
readonly summary?: string;
|
|
166
|
-
readonly artifacts?: Record<string, NornArtifactRef>;
|
|
167
161
|
readonly logs?: Record<string, NornLogRef>;
|
|
168
162
|
readonly data?: Record<string, unknown>;
|
|
169
163
|
};
|
|
@@ -180,10 +174,6 @@ export type NornRunFail = {
|
|
|
180
174
|
|
|
181
175
|
export type WorkflowResult = NornRunNext | NornRunComplete | NornRunFail;
|
|
182
176
|
|
|
183
|
-
export type NornRunFor<TWorkflow extends NornAnyWorkflowDeclaration> = TWorkflow extends { readonly isolation: { readonly mode: "project" } }
|
|
184
|
-
? NornProjectRun
|
|
185
|
-
: NornRun;
|
|
186
|
-
|
|
187
177
|
export type NornRunStartOptions = {
|
|
188
178
|
readonly id?: string;
|
|
189
179
|
readonly name?: string;
|
|
@@ -270,6 +260,7 @@ export type NornRunInfo = {
|
|
|
270
260
|
readonly id: string;
|
|
271
261
|
readonly name: string;
|
|
272
262
|
readonly path: string;
|
|
263
|
+
readonly paths: NornWorkflowPaths;
|
|
273
264
|
readonly entrypointWorkflowId: string;
|
|
274
265
|
readonly currentWorkflowId?: string;
|
|
275
266
|
readonly status: NornRunStatus;
|
|
@@ -298,17 +289,11 @@ export type NornRunCheckpoint = {
|
|
|
298
289
|
export type NornCommandRunInput = {
|
|
299
290
|
readonly label: string;
|
|
300
291
|
readonly command: string | readonly [string, ...string[]];
|
|
301
|
-
readonly cwd
|
|
292
|
+
readonly cwd: string;
|
|
302
293
|
readonly env?: Record<string, string>;
|
|
303
294
|
readonly timeoutMs?: number;
|
|
304
295
|
};
|
|
305
296
|
|
|
306
|
-
export const artifactRefSchema = Type.Object({
|
|
307
|
-
path: Type.String(),
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
export type NornArtifactRef = StaticDecode<typeof artifactRefSchema>;
|
|
311
|
-
|
|
312
297
|
const emptyWorkflowRefArgsSchema = Type.Object({});
|
|
313
298
|
const workflowReferenceInputSchema = Type.Union([
|
|
314
299
|
Type.String({ minLength: 1 }),
|
|
@@ -350,9 +335,9 @@ export type NornAgentBeforeSessionStartContext = {
|
|
|
350
335
|
};
|
|
351
336
|
|
|
352
337
|
export type NornAgentCreateSessionInput = {
|
|
353
|
-
readonly
|
|
338
|
+
readonly customTools?: readonly ToolDefinition[];
|
|
354
339
|
readonly label: string;
|
|
355
|
-
readonly cwd
|
|
340
|
+
readonly cwd: string;
|
|
356
341
|
readonly tools?: string[];
|
|
357
342
|
readonly beforeSessionStart?: (context: NornAgentBeforeSessionStartContext) => MaybePromise<void>;
|
|
358
343
|
readonly model?: CreateAgentSessionOptions["model"];
|
|
@@ -477,26 +462,11 @@ export type NornAgentSession = {
|
|
|
477
462
|
dispose(): Promise<void>;
|
|
478
463
|
};
|
|
479
464
|
|
|
480
|
-
export type NornRun =
|
|
481
|
-
|
|
482
|
-
export type NornProjectRun = NornRunBase & {
|
|
483
|
-
projectRoot: string;
|
|
484
|
-
projectPath(relativePath: string): string;
|
|
485
|
-
};
|
|
486
|
-
|
|
487
|
-
type NornRunBase = {
|
|
465
|
+
export type NornRun = {
|
|
488
466
|
id: string;
|
|
489
|
-
workspace: string;
|
|
490
|
-
cwd: string;
|
|
491
|
-
path(relativePath: string): string;
|
|
492
467
|
next(workflowId: string, args: unknown): NornRunNext;
|
|
493
468
|
complete(metadata?: NornRunOutcomeMetadata): NornRunComplete;
|
|
494
469
|
fail(metadata: NornRunOutcomeMetadata & { readonly summary: string }): NornRunFail;
|
|
495
|
-
resources: import("./resources.ts").NornResources;
|
|
496
|
-
artifacts: {
|
|
497
|
-
write(path: string, content: string): Promise<NornArtifactRef>;
|
|
498
|
-
read(ref: NornArtifactRef): Promise<string>;
|
|
499
|
-
};
|
|
500
470
|
logs: {
|
|
501
471
|
read(log: NornLogRef): Promise<string>;
|
|
502
472
|
};
|
|
@@ -525,7 +495,6 @@ export type NornRegisteredWorkflowInfo = {
|
|
|
525
495
|
readonly id: string;
|
|
526
496
|
readonly instructions?: string;
|
|
527
497
|
readonly isEntrypoint: boolean;
|
|
528
|
-
readonly isolation: NornWorkflowIsolation;
|
|
529
498
|
readonly scope?: { readonly id: string };
|
|
530
499
|
readonly source?: NornWorkflowSource;
|
|
531
500
|
readonly configKey: string;
|
|
@@ -589,7 +558,7 @@ function assertDeclarationId(id: string): void {
|
|
|
589
558
|
|
|
590
559
|
export function isWorkflowDeclaration(value: unknown): value is NornAnyWorkflowDeclaration {
|
|
591
560
|
if (typeof value !== "function") return false;
|
|
592
|
-
const candidate = value as { kind?: unknown; id?: unknown; instructions?: unknown; isEntrypoint?: unknown; args?: unknown; execute?: unknown
|
|
561
|
+
const candidate = value as { kind?: unknown; id?: unknown; instructions?: unknown; isEntrypoint?: unknown; args?: unknown; execute?: unknown };
|
|
593
562
|
return (
|
|
594
563
|
candidate.kind === WORKFLOW_DECLARATION_KIND &&
|
|
595
564
|
typeof candidate.id === "string" &&
|
|
@@ -597,8 +566,7 @@ export function isWorkflowDeclaration(value: unknown): value is NornAnyWorkflowD
|
|
|
597
566
|
(candidate.instructions === undefined || typeof candidate.instructions === "string") &&
|
|
598
567
|
typeof candidate.isEntrypoint === "boolean" &&
|
|
599
568
|
Boolean(candidate.args) &&
|
|
600
|
-
typeof candidate.execute === "function"
|
|
601
|
-
(candidate.isolation?.mode === "runWorkspace" || candidate.isolation?.mode === "project")
|
|
569
|
+
typeof candidate.execute === "function"
|
|
602
570
|
);
|
|
603
571
|
}
|
|
604
572
|
|
|
@@ -1,5 +1,2 @@
|
|
|
1
1
|
export type { CreateAgentSessionOptions, EventBus, PromptOptions, ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
export * from "./api.ts";
|
|
3
|
-
export { NornFileCoordinator } from "./files.ts";
|
|
4
|
-
export * from "./resources.ts";
|
|
5
|
-
export * from "./agent-resource-adapter.ts";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { workflow, isWorkflowDeclaration, workflowRefSchema, type NornWorkflowRefSchemaOptions } from "@vimhead.dev/norn";
|
|
2
2
|
import { inspectSchema } from "@vimhead.dev/norn/schema";
|
|
3
3
|
import assert from "node:assert/strict";
|
|
4
4
|
import { Type } from "typebox";
|
|
@@ -15,7 +15,6 @@ test("callable declarations retain metadata and construct transitions without ex
|
|
|
15
15
|
assert.equal(isWorkflowDeclaration(target), true);
|
|
16
16
|
assert.equal(isWorkflowDeclaration(() => undefined), false);
|
|
17
17
|
assert.equal(Value.Check(target.args, { report: "done" }), true);
|
|
18
|
-
assert.deepEqual(target.isolation, { mode: "runWorkspace" });
|
|
19
18
|
assert.deepEqual(target({ report: "done" }), { type: "next", workflowId: target.id, args: { report: "done" } });
|
|
20
19
|
});
|
|
21
20
|
|
|
@@ -57,7 +56,7 @@ test("optional reference properties remain optional in validation and inspection
|
|
|
57
56
|
test("inspection advertises encoded contributions and invocation does not decode them", () => {
|
|
58
57
|
let decodes = 0;
|
|
59
58
|
const contributions = Type.Object({
|
|
60
|
-
records:
|
|
59
|
+
records: Type.String(),
|
|
61
60
|
count: Type.Decode(Type.String(), value => { decodes++; return Number(value); }),
|
|
62
61
|
label: Type.Optional(Type.String({ default: "collected" })),
|
|
63
62
|
});
|
|
@@ -72,10 +71,10 @@ test("inspection advertises encoded contributions and invocation does not decode
|
|
|
72
71
|
expect(inspected).toHaveProperty("properties.next.x-norn-workflow-ref.contributedArgsSchema.properties.count.type", "string");
|
|
73
72
|
const forwardArgs = { taskId: "task-42", nested: { labels: ["one", "two"], enabled: false, absent: null } };
|
|
74
73
|
const next = Value.Decode(schema, { next: { workflow: "refs.finish", forwardArgs } }).next;
|
|
75
|
-
const contribution = { records:
|
|
74
|
+
const contribution = { records: "records.json", count: "2" };
|
|
76
75
|
assert.deepEqual(next(contribution).args, { ...forwardArgs, ...contribution });
|
|
77
76
|
assert.equal(decodes, 0);
|
|
78
|
-
assert.throws(() => Reflect.apply(next, undefined, [{ records:
|
|
77
|
+
assert.throws(() => Reflect.apply(next, undefined, [{ records: "records.json", count: 2 }]));
|
|
79
78
|
});
|
|
80
79
|
|
|
81
80
|
test("references without contributions advertise an empty object schema", () => {
|
|
@@ -100,10 +99,10 @@ test("optional, nullable and array references retain annotations and callable co
|
|
|
100
99
|
|
|
101
100
|
test("nested references retain encoded payloads in contributed parameters", () => {
|
|
102
101
|
const finalContributions = Type.Object({ summary: Type.String() });
|
|
103
|
-
const contributions = Type.Object({ records:
|
|
102
|
+
const contributions = Type.Object({ records: Type.String(), next: workflowRefSchema({ args: finalContributions }) });
|
|
104
103
|
const reference = workflowRefSchema({ args: contributions });
|
|
105
104
|
expect(inspectSchema(reference)).toHaveProperty("x-norn-workflow-ref.contributedArgsSchema.properties.next.x-norn-workflow-ref.contributedArgsSchema", inspectSchema(finalContributions));
|
|
106
|
-
const args = { records:
|
|
105
|
+
const args = { records: "records.json", next: { workflow: "refs.finish", forwardArgs: { batch: 1 } } };
|
|
107
106
|
const transition = Value.Decode(reference, "intermediate")(args);
|
|
108
107
|
assert.deepEqual(transition.args, args);
|
|
109
108
|
assert.deepEqual(Value.Decode(contributions, transition.args).next({ summary: "done" }).args, { batch: 1, summary: "done" });
|
package/dist/cli.js
CHANGED
|
@@ -18,6 +18,7 @@ import { Value } from "typebox/value";
|
|
|
18
18
|
import { NORN_BUILD_INFO } from "./build-info.js";
|
|
19
19
|
import { renderNornDocumentationIntro, resolveDocumentationCacheRoot, resolveNornDocumentation } from "./documentation.js";
|
|
20
20
|
import { NornEngine } from "./internal/engine.js";
|
|
21
|
+
import { resolveNornAgentDirectory } from "./internal/agent-directory.js";
|
|
21
22
|
import { errorMessage, NornProjectLoadError, NornRunStoppedError } from "./internal/errors.js";
|
|
22
23
|
import { clearRunResumeRequest, readRunLaunchRequest, readRunResumeRequest, writeRunLaunchRequest, writeRunResumeRequest } from "./internal/launch-request.js";
|
|
23
24
|
import { readRunMetrics } from "./internal/metrics.js";
|
|
@@ -25,6 +26,7 @@ import { getRunLeaseOwner, NornRunLease } from "./internal/run-lease.js";
|
|
|
25
26
|
import { generateRunName } from "./internal/run-names.js";
|
|
26
27
|
import { assertRunVersion, getRunInfo, listRuns, mergeInterruptedWorkflowArgs, resolveRunRoot } from "./internal/run-state.js";
|
|
27
28
|
import { NornRunStore } from "./internal/run-store.js";
|
|
29
|
+
import { prepareRunWorkerDirectory } from "./internal/worker-directory.js";
|
|
28
30
|
import { discoverNornProject, findNornProject, inspectNornWorkflow, loadNornProject, NORN_PROJECT_FILE_NAME } from "./workflow-loader.js";
|
|
29
31
|
var RUNS_ROOT = join(".norn", "runs");
|
|
30
32
|
var RUN_WAIT_INTERVAL_MS = 1e3;
|
|
@@ -715,7 +717,7 @@ async function startRun(workflowId, commandArgs) {
|
|
|
715
717
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
716
718
|
await writeRunLaunchRequest(runRoot, { version: 2, type: "run", id, name, workflowId, args, configOverride, createdAt });
|
|
717
719
|
await startDetachedExecuteRun(id, project.projectRoot);
|
|
718
|
-
writeJson({ run: startedRunInfo({ id, name, workflow, runRoot, createdAt }) });
|
|
720
|
+
writeJson({ run: startedRunInfo({ id, name, workflow, runRoot, projectRoot: project.projectRoot, createdAt }) });
|
|
719
721
|
}
|
|
720
722
|
async function resumeRun(run, args) {
|
|
721
723
|
assertNoStructuredInputArgs("runs resume", args);
|
|
@@ -822,8 +824,10 @@ async function executeRun(runId) {
|
|
|
822
824
|
const runRoot = resolve(location.projectRoot, RUNS_ROOT, runId);
|
|
823
825
|
const request = await readOptionalRunLaunchRequest(runRoot) ?? await readRunResumeRequest(runRoot);
|
|
824
826
|
try {
|
|
825
|
-
const
|
|
826
|
-
|
|
827
|
+
const agentDir = resolveNornAgentDirectory({ home: homedir(), environment: process.env });
|
|
828
|
+
process.chdir(await prepareRunWorkerDirectory(runRoot));
|
|
829
|
+
const project = await loadNornProject(location.projectRoot);
|
|
830
|
+
const engine = new NornEngine({ cwd: project.projectRoot, agentDir, signal: abortController.signal, gateMode: "pause", config: project.projectConfig });
|
|
827
831
|
engine.registerWorkflows(project.definitions);
|
|
828
832
|
if (request.type === "run") {
|
|
829
833
|
const workflow = project.registry.workflowById(request.workflowId);
|
|
@@ -918,6 +922,7 @@ function startedRunInfo(input) {
|
|
|
918
922
|
id: input.id,
|
|
919
923
|
name: input.name,
|
|
920
924
|
path: input.runRoot,
|
|
925
|
+
paths: { project: input.projectRoot, workspace: join(input.runRoot, "current", "workspace") },
|
|
921
926
|
entrypointWorkflowId: input.workflow.id,
|
|
922
927
|
currentWorkflowId: input.workflow.id,
|
|
923
928
|
status: "running",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare const NORN_GENERATED_BUILD_INFO: {
|
|
2
2
|
readonly kind: "npm-registry";
|
|
3
|
-
readonly version: "0.1.0-tip.
|
|
4
|
-
readonly commit: "
|
|
3
|
+
readonly version: "0.1.0-tip.35436871363.1";
|
|
4
|
+
readonly commit: "49b14d0ed0c9633fc6ee530a557ec7babbf52b22";
|
|
5
5
|
readonly packageSpec: "@vimhead.dev/norn-cli@tip";
|
|
6
6
|
readonly upgrade: {
|
|
7
7
|
readonly supported: false;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// src/generated-build-info.ts
|
|
2
2
|
var NORN_GENERATED_BUILD_INFO = {
|
|
3
3
|
"kind": "npm-registry",
|
|
4
|
-
"version": "0.1.0-tip.
|
|
5
|
-
"commit": "
|
|
4
|
+
"version": "0.1.0-tip.35436871363.1",
|
|
5
|
+
"commit": "49b14d0ed0c9633fc6ee530a557ec7babbf52b22",
|
|
6
6
|
"packageSpec": "@vimhead.dev/norn-cli@tip",
|
|
7
7
|
"upgrade": {
|
|
8
8
|
"supported": false,
|
|
@@ -7,9 +7,6 @@ import type { NornRunLogger } from "./run-log.ts";
|
|
|
7
7
|
type NornAgentRunnerInput = {
|
|
8
8
|
readonly id: string;
|
|
9
9
|
readonly runRoot: string;
|
|
10
|
-
readonly boundaryRoot: string;
|
|
11
|
-
readonly boundaryName: string;
|
|
12
|
-
readonly cwd: string;
|
|
13
10
|
readonly signal?: AbortSignal;
|
|
14
11
|
readonly model?: CreateAgentSessionOptions["model"];
|
|
15
12
|
readonly thinkingLevel?: CreateAgentSessionOptions["thinkingLevel"];
|
|
@@ -24,6 +21,5 @@ export declare class NornAgentRunner {
|
|
|
24
21
|
constructor(input: NornAgentRunnerInput);
|
|
25
22
|
createSession(agentInput: NornAgentCreateSessionInput): Promise<NornAgentSession>;
|
|
26
23
|
prompt<ResponseSchema extends TSchema>(agentInput: NornAgentSinglePromptInput<ResponseSchema>): Promise<StaticDecode<ResponseSchema>>;
|
|
27
|
-
private resolveFromCwd;
|
|
28
24
|
}
|
|
29
25
|
export {};
|
package/dist/internal/agents.js
CHANGED
|
@@ -14,17 +14,16 @@ import { inspectSchema } from "@vimhead.dev/norn/schema";
|
|
|
14
14
|
import { randomUUID } from "node:crypto";
|
|
15
15
|
import { mkdir } from "node:fs/promises";
|
|
16
16
|
import { homedir } from "node:os";
|
|
17
|
-
import {
|
|
17
|
+
import { resolve } from "node:path";
|
|
18
|
+
import { requireAbsoluteWorkingDirectory } from "./working-directory.js";
|
|
18
19
|
import { resolveNornAgentDirectory } from "./agent-directory.js";
|
|
19
20
|
import {
|
|
20
21
|
NornAgentResponseToolFactory
|
|
21
22
|
} from "./agent-response-tool.js";
|
|
22
23
|
import { errorMessage } from "./errors.js";
|
|
23
24
|
import { safeFileName } from "./file-names.js";
|
|
24
|
-
import { NornSessionResourceBindings } from "./resource-bindings.js";
|
|
25
25
|
import { agentUsageFromValue, emptyAgentUsage, totalAgentUsage } from "./usage.js";
|
|
26
26
|
var DEFAULT_AGENT_ATTEMPTS = 3;
|
|
27
|
-
var DEFAULT_AGENT_TOOL_ALLOWLIST = ["read", "bash", "edit", "write", AGENT_RESPONSE_TOOL_NAME];
|
|
28
27
|
var NornAgentRunner = class {
|
|
29
28
|
constructor(input) {
|
|
30
29
|
this.input = input;
|
|
@@ -33,7 +32,7 @@ var NornAgentRunner = class {
|
|
|
33
32
|
input;
|
|
34
33
|
responseToolFactory;
|
|
35
34
|
async createSession(agentInput) {
|
|
36
|
-
const cwd =
|
|
35
|
+
const cwd = requireAbsoluteWorkingDirectory(agentInput.cwd);
|
|
37
36
|
const sessionDir = resolve(this.input.runRoot, "sessions");
|
|
38
37
|
await mkdir(sessionDir, { recursive: true });
|
|
39
38
|
const eventBus = createEventBus();
|
|
@@ -53,31 +52,29 @@ var NornAgentRunner = class {
|
|
|
53
52
|
...loader.getExtensions().errors.map((error) => `Failed to load extension ${error.path}: ${error.error}`)
|
|
54
53
|
];
|
|
55
54
|
if (errors.length > 0) throw new Error(errors.join("\n"));
|
|
56
|
-
const
|
|
55
|
+
const customTools = agentInput.customTools ?? [];
|
|
56
|
+
assertCustomToolNames({
|
|
57
|
+
tools: customTools,
|
|
58
|
+
reservedNames: [
|
|
59
|
+
"read",
|
|
60
|
+
"bash",
|
|
61
|
+
"edit",
|
|
62
|
+
"write",
|
|
63
|
+
"grep",
|
|
64
|
+
"find",
|
|
65
|
+
"ls",
|
|
66
|
+
"powershell",
|
|
67
|
+
AGENT_RESPONSE_TOOL_NAME,
|
|
68
|
+
...loader.getExtensions().extensions.flatMap((extension) => [...extension.tools.keys()])
|
|
69
|
+
]
|
|
70
|
+
});
|
|
57
71
|
let session;
|
|
58
72
|
try {
|
|
59
|
-
await resourceBindings.bind({
|
|
60
|
-
adapters: agentInput.resourceAdapters ?? [],
|
|
61
|
-
runId: this.input.id,
|
|
62
|
-
label: agentInput.label,
|
|
63
|
-
reservedTools: [
|
|
64
|
-
"read",
|
|
65
|
-
"bash",
|
|
66
|
-
"edit",
|
|
67
|
-
"write",
|
|
68
|
-
"grep",
|
|
69
|
-
"find",
|
|
70
|
-
"ls",
|
|
71
|
-
"powershell",
|
|
72
|
-
AGENT_RESPONSE_TOOL_NAME,
|
|
73
|
-
...loader.getExtensions().extensions.flatMap((extension) => [...extension.tools.keys()])
|
|
74
|
-
]
|
|
75
|
-
});
|
|
76
73
|
({ session } = await createAgentSessionFromServices({
|
|
77
74
|
services,
|
|
78
75
|
sessionManager: SessionManager.create(cwd, sessionDir),
|
|
79
|
-
tools:
|
|
80
|
-
customTools: [this.responseToolFactory.create(), ...
|
|
76
|
+
tools: withAgentResponseTool(agentInput.tools),
|
|
77
|
+
customTools: [this.responseToolFactory.create(), ...customTools],
|
|
81
78
|
model: agentInput.model ?? this.input.model,
|
|
82
79
|
thinkingLevel: agentInput.thinkingLevel ?? this.input.thinkingLevel
|
|
83
80
|
}));
|
|
@@ -89,7 +86,6 @@ var NornAgentRunner = class {
|
|
|
89
86
|
label: agentInput.label,
|
|
90
87
|
cwd,
|
|
91
88
|
session,
|
|
92
|
-
resourceBindings,
|
|
93
89
|
events: eventBus
|
|
94
90
|
});
|
|
95
91
|
} catch (error) {
|
|
@@ -99,12 +95,7 @@ var NornAgentRunner = class {
|
|
|
99
95
|
} catch (cleanupError) {
|
|
100
96
|
errors2.push(cleanupError);
|
|
101
97
|
}
|
|
102
|
-
|
|
103
|
-
await resourceBindings.dispose();
|
|
104
|
-
} catch (cleanupError) {
|
|
105
|
-
errors2.push(cleanupError);
|
|
106
|
-
}
|
|
107
|
-
if (errors2.length > 1) throw new AggregateError(errors2, "Agent creation and resource cleanup failed");
|
|
98
|
+
if (errors2.length > 1) throw new AggregateError(errors2, "Agent creation and cleanup failed");
|
|
108
99
|
throw error;
|
|
109
100
|
}
|
|
110
101
|
}
|
|
@@ -116,14 +107,6 @@ var NornAgentRunner = class {
|
|
|
116
107
|
await agent.dispose();
|
|
117
108
|
}
|
|
118
109
|
}
|
|
119
|
-
resolveFromCwd(path) {
|
|
120
|
-
const resolvedPath = isAbsolute(path) ? path : resolve(this.input.cwd, path);
|
|
121
|
-
const pathFromBoundary = relative(this.input.boundaryRoot, resolvedPath);
|
|
122
|
-
if (pathFromBoundary === ".." || pathFromBoundary.startsWith(`..${sep}`) || isAbsolute(pathFromBoundary)) {
|
|
123
|
-
throw new Error(`Agent cwd escapes ${this.input.boundaryName} isolation: ${path}`);
|
|
124
|
-
}
|
|
125
|
-
return resolvedPath;
|
|
126
|
-
}
|
|
127
110
|
};
|
|
128
111
|
function systemPromptOverride(agentInput) {
|
|
129
112
|
const systemPrompt = agentInput.systemPrompt;
|
|
@@ -223,11 +206,6 @@ var CreatedNornAgentSession = class {
|
|
|
223
206
|
} catch (error) {
|
|
224
207
|
errors.push(error);
|
|
225
208
|
}
|
|
226
|
-
try {
|
|
227
|
-
await this.input.resourceBindings.dispose();
|
|
228
|
-
} catch (error) {
|
|
229
|
-
errors.push(error);
|
|
230
|
-
}
|
|
231
209
|
if (errors.length) throw new AggregateError(errors, "Agent disposal failed");
|
|
232
210
|
await this.input.logger.record({ type: "agent.disposed", label: this.label });
|
|
233
211
|
}
|
|
@@ -328,8 +306,14 @@ function withResponseToolFinalizationInstruction(responseSchema, label, response
|
|
|
328
306
|
].join("\n");
|
|
329
307
|
}
|
|
330
308
|
function withAgentResponseTool(tools) {
|
|
331
|
-
|
|
332
|
-
|
|
309
|
+
return tools === void 0 ? void 0 : Array.from(/* @__PURE__ */ new Set([...tools, AGENT_RESPONSE_TOOL_NAME]));
|
|
310
|
+
}
|
|
311
|
+
function assertCustomToolNames(input) {
|
|
312
|
+
const names = new Set(input.reservedNames);
|
|
313
|
+
for (const tool of input.tools) {
|
|
314
|
+
if (names.has(tool.name)) throw new Error(`Custom tool name collision: ${tool.name}`);
|
|
315
|
+
names.add(tool.name);
|
|
316
|
+
}
|
|
333
317
|
}
|
|
334
318
|
export {
|
|
335
319
|
NornAgentRunner
|
|
@@ -2,9 +2,6 @@ import type { NornCommandRunInput, NornCommandRunResult } from "@vimhead.dev/nor
|
|
|
2
2
|
import type { NornRunLogs } from "./logs.ts";
|
|
3
3
|
import type { NornRunLogger } from "./run-log.ts";
|
|
4
4
|
type NornCommandRunnerInput = {
|
|
5
|
-
readonly boundaryRoot: string;
|
|
6
|
-
readonly boundaryName: string;
|
|
7
|
-
readonly cwd: string;
|
|
8
5
|
readonly signal?: AbortSignal;
|
|
9
6
|
readonly logs: NornRunLogs;
|
|
10
7
|
readonly logger: NornRunLogger;
|
|
@@ -13,6 +10,5 @@ export declare class NornCommandRunner {
|
|
|
13
10
|
private readonly input;
|
|
14
11
|
constructor(input: NornCommandRunnerInput);
|
|
15
12
|
run(commandInput: NornCommandRunInput): Promise<NornCommandRunResult>;
|
|
16
|
-
private resolveFromCwd;
|
|
17
13
|
}
|
|
18
14
|
export {};
|