@corenel/harness 0.1.0
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/dist/compression.d.ts +11 -0
- package/dist/compression.d.ts.map +1 -0
- package/dist/compression.js +27 -0
- package/dist/compression.js.map +1 -0
- package/dist/conversation.d.ts +29 -0
- package/dist/conversation.d.ts.map +1 -0
- package/dist/conversation.js +25 -0
- package/dist/conversation.js.map +1 -0
- package/dist/core/loop.d.ts +31 -0
- package/dist/core/loop.d.ts.map +1 -0
- package/dist/core/loop.js +237 -0
- package/dist/core/loop.js.map +1 -0
- package/dist/dag/executeNode.d.ts +41 -0
- package/dist/dag/executeNode.d.ts.map +1 -0
- package/dist/dag/executeNode.js +81 -0
- package/dist/dag/executeNode.js.map +1 -0
- package/dist/fileSchema.d.ts +7 -0
- package/dist/fileSchema.d.ts.map +1 -0
- package/dist/fileSchema.js +40 -0
- package/dist/fileSchema.js.map +1 -0
- package/dist/guardrail/builtins.d.ts +9 -0
- package/dist/guardrail/builtins.d.ts.map +1 -0
- package/dist/guardrail/builtins.js +61 -0
- package/dist/guardrail/builtins.js.map +1 -0
- package/dist/guardrail/glob.d.ts +3 -0
- package/dist/guardrail/glob.d.ts.map +1 -0
- package/dist/guardrail/glob.js +33 -0
- package/dist/guardrail/glob.js.map +1 -0
- package/dist/guardrail/guardrail.d.ts +25 -0
- package/dist/guardrail/guardrail.d.ts.map +1 -0
- package/dist/guardrail/guardrail.js +67 -0
- package/dist/guardrail/guardrail.js.map +1 -0
- package/dist/guardrail/index.d.ts +9 -0
- package/dist/guardrail/index.d.ts.map +1 -0
- package/dist/guardrail/index.js +11 -0
- package/dist/guardrail/index.js.map +1 -0
- package/dist/guardrail/permission-service.d.ts +53 -0
- package/dist/guardrail/permission-service.d.ts.map +1 -0
- package/dist/guardrail/permission-service.js +147 -0
- package/dist/guardrail/permission-service.js.map +1 -0
- package/dist/guardrail/serialize.d.ts +9 -0
- package/dist/guardrail/serialize.d.ts.map +1 -0
- package/dist/guardrail/serialize.js +53 -0
- package/dist/guardrail/serialize.js.map +1 -0
- package/dist/guardrail/store.d.ts +26 -0
- package/dist/guardrail/store.d.ts.map +1 -0
- package/dist/guardrail/store.js +109 -0
- package/dist/guardrail/store.js.map +1 -0
- package/dist/guardrail/validate.d.ts +8 -0
- package/dist/guardrail/validate.d.ts.map +1 -0
- package/dist/guardrail/validate.js +105 -0
- package/dist/guardrail/validate.js.map +1 -0
- package/dist/guards.d.ts +37 -0
- package/dist/guards.d.ts.map +1 -0
- package/dist/guards.js +45 -0
- package/dist/guards.js.map +1 -0
- package/dist/log.d.ts +4 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +22 -0
- package/dist/log.js.map +1 -0
- package/dist/promptCompiler.d.ts +18 -0
- package/dist/promptCompiler.d.ts.map +1 -0
- package/dist/promptCompiler.js +11 -0
- package/dist/promptCompiler.js.map +1 -0
- package/dist/prompts/config.d.ts +63 -0
- package/dist/prompts/config.d.ts.map +1 -0
- package/dist/prompts/config.js +268 -0
- package/dist/prompts/config.js.map +1 -0
- package/dist/prompts/host.d.ts +30 -0
- package/dist/prompts/host.d.ts.map +1 -0
- package/dist/prompts/host.js +11 -0
- package/dist/prompts/host.js.map +1 -0
- package/dist/prompts/index.d.ts +50 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +105 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/library/defaults.generated.d.ts +2 -0
- package/dist/prompts/library/defaults.generated.d.ts.map +1 -0
- package/dist/prompts/library/defaults.generated.js +31 -0
- package/dist/prompts/library/defaults.generated.js.map +1 -0
- package/dist/prompts/library/index.d.ts +8 -0
- package/dist/prompts/library/index.d.ts.map +1 -0
- package/dist/prompts/library/index.js +28 -0
- package/dist/prompts/library/index.js.map +1 -0
- package/dist/providers/gateway.d.ts +58 -0
- package/dist/providers/gateway.d.ts.map +1 -0
- package/dist/providers/gateway.js +145 -0
- package/dist/providers/gateway.js.map +1 -0
- package/dist/services.d.ts +29 -0
- package/dist/services.d.ts.map +1 -0
- package/dist/services.js +22 -0
- package/dist/services.js.map +1 -0
- package/dist/sidecar/host.d.ts +69 -0
- package/dist/sidecar/host.d.ts.map +1 -0
- package/dist/sidecar/host.js +228 -0
- package/dist/sidecar/host.js.map +1 -0
- package/dist/sidecar/server.d.ts +42 -0
- package/dist/sidecar/server.d.ts.map +1 -0
- package/dist/sidecar/server.js +267 -0
- package/dist/sidecar/server.js.map +1 -0
- package/dist/skills.d.ts +39 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +216 -0
- package/dist/skills.js.map +1 -0
- package/dist/systemParts.d.ts +10 -0
- package/dist/systemParts.d.ts.map +1 -0
- package/dist/systemParts.js +21 -0
- package/dist/systemParts.js.map +1 -0
- package/dist/todos.d.ts +34 -0
- package/dist/todos.d.ts.map +1 -0
- package/dist/todos.js +112 -0
- package/dist/todos.js.map +1 -0
- package/dist/tools/builtins.d.ts +20 -0
- package/dist/tools/builtins.d.ts.map +1 -0
- package/dist/tools/builtins.js +335 -0
- package/dist/tools/builtins.js.map +1 -0
- package/dist/tools/files.d.ts +11 -0
- package/dist/tools/files.d.ts.map +1 -0
- package/dist/tools/files.js +161 -0
- package/dist/tools/files.js.map +1 -0
- package/dist/tools/http.d.ts +3 -0
- package/dist/tools/http.d.ts.map +1 -0
- package/dist/tools/http.js +71 -0
- package/dist/tools/http.js.map +1 -0
- package/dist/tools/namespaces.d.ts +27 -0
- package/dist/tools/namespaces.d.ts.map +1 -0
- package/dist/tools/namespaces.js +83 -0
- package/dist/tools/namespaces.js.map +1 -0
- package/dist/tools/registry.d.ts +8 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +14 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/sessions.d.ts +3 -0
- package/dist/tools/sessions.d.ts.map +1 -0
- package/dist/tools/sessions.js +149 -0
- package/dist/tools/sessions.js.map +1 -0
- package/dist/tools/todo.d.ts +3 -0
- package/dist/tools/todo.d.ts.map +1 -0
- package/dist/tools/todo.js +38 -0
- package/dist/tools/todo.js.map +1 -0
- package/dist/tools/urlGuard.d.ts +9 -0
- package/dist/tools/urlGuard.d.ts.map +1 -0
- package/dist/tools/urlGuard.js +80 -0
- package/dist/tools/urlGuard.js.map +1 -0
- package/dist/tools/web.d.ts +3 -0
- package/dist/tools/web.d.ts.map +1 -0
- package/dist/tools/web.js +35 -0
- package/dist/tools/web.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CompressionMode, OffloadRef } from '@corenel/protocol';
|
|
2
|
+
export type { CompressionMode, CompressionConfig, OffloadRef } from '@corenel/protocol';
|
|
3
|
+
/** How much of an offloaded output to keep inline as a preview. */
|
|
4
|
+
export declare const PREVIEW_BYTES = 800;
|
|
5
|
+
/** Threshold for a given fill ratio (0–1). As the window fills, offload sooner. */
|
|
6
|
+
export declare function effectiveThreshold(mode: CompressionMode, fill?: number): number;
|
|
7
|
+
/** The self-describing reference that replaces a large output in the history.
|
|
8
|
+
* Carries enough (tool, size, preview, recall instruction) for the model to
|
|
9
|
+
* decide whether to pull the full content back. */
|
|
10
|
+
export declare function formatOffloadRef(ref: OffloadRef): string;
|
|
11
|
+
//# sourceMappingURL=compression.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compression.d.ts","sourceRoot":"","sources":["../compression.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACrE,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAExF,mEAAmE;AACnE,eAAO,MAAM,aAAa,MAAM,CAAC;AAOjC,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,EAAE,IAAI,SAAI,GAAG,MAAM,CAI1E;AAED;;mDAEmD;AACnD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAGxD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/* Context compression config (rung-1 lossless offload).
|
|
2
|
+
*
|
|
3
|
+
* One preset controls how readily large tool outputs are offloaded to the
|
|
4
|
+
* RecallStore. It's adaptive: given the model's context window, the loop computes
|
|
5
|
+
* a fill ratio and lowers the threshold as the window fills — "more aggressive the
|
|
6
|
+
* fuller it gets," entirely within lossless offload. See docs/CONTEXT-COMPRESSION.md. */
|
|
7
|
+
/** How much of an offloaded output to keep inline as a preview. */
|
|
8
|
+
export const PREVIEW_BYTES = 800;
|
|
9
|
+
// Base byte thresholds (output larger than this offloads) and a floor the ramp
|
|
10
|
+
// won't go below, per preset.
|
|
11
|
+
const BASE = { off: Infinity, conservative: 24000, balanced: 12000, aggressive: 6000 };
|
|
12
|
+
const FLOOR = { off: Infinity, conservative: 8000, balanced: 4000, aggressive: 2000 };
|
|
13
|
+
/** Threshold for a given fill ratio (0–1). As the window fills, offload sooner. */
|
|
14
|
+
export function effectiveThreshold(mode, fill = 0) {
|
|
15
|
+
if (mode === 'off')
|
|
16
|
+
return Infinity;
|
|
17
|
+
const factor = fill < 0.5 ? 1 : fill < 0.7 ? 0.7 : fill < 0.85 ? 0.5 : 0.35;
|
|
18
|
+
return Math.max(FLOOR[mode], Math.round(BASE[mode] * factor));
|
|
19
|
+
}
|
|
20
|
+
/** The self-describing reference that replaces a large output in the history.
|
|
21
|
+
* Carries enough (tool, size, preview, recall instruction) for the model to
|
|
22
|
+
* decide whether to pull the full content back. */
|
|
23
|
+
export function formatOffloadRef(ref) {
|
|
24
|
+
const head = `[offloaded tool result · ${ref.toolName} · ${ref.bytes.toLocaleString()} bytes · recall the full content with recall_result({ id: "${ref.id}" })]`;
|
|
25
|
+
return ref.preview ? `${head}\n--- preview ---\n${ref.preview}${ref.bytes > ref.preview.length ? '\n…(truncated)' : ''}` : head;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=compression.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compression.js","sourceRoot":"","sources":["../compression.ts"],"names":[],"mappings":"AAAA;;;;;yFAKyF;AAOzF,mEAAmE;AACnE,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC;AAEjC,+EAA+E;AAC/E,8BAA8B;AAC9B,MAAM,IAAI,GAAoC,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAM,EAAE,QAAQ,EAAE,KAAM,EAAE,UAAU,EAAE,IAAK,EAAE,CAAC;AAC3H,MAAM,KAAK,GAAoC,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAK,EAAE,QAAQ,EAAE,IAAK,EAAE,UAAU,EAAE,IAAK,EAAE,CAAC;AAE1H,mFAAmF;AACnF,MAAM,UAAU,kBAAkB,CAAC,IAAqB,EAAE,IAAI,GAAG,CAAC;IAChE,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,QAAQ,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5E,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;mDAEmD;AACnD,MAAM,UAAU,gBAAgB,CAAC,GAAe;IAC9C,MAAM,IAAI,GAAG,4BAA4B,GAAG,CAAC,QAAQ,MAAM,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,8DAA8D,GAAG,CAAC,EAAE,OAAO,CAAC;IACjK,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,sBAAsB,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAClI,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ChatCompletionMessageParam } from 'openai/resources/chat/completions';
|
|
2
|
+
/** Per-turn telemetry shown under an assistant turn (tokens / cost / wall-clock). */
|
|
3
|
+
export interface TurnStats {
|
|
4
|
+
inTok: number;
|
|
5
|
+
outTok: number;
|
|
6
|
+
cost: number;
|
|
7
|
+
ms: number;
|
|
8
|
+
}
|
|
9
|
+
/** One assistant conversation turn — the live-buffer data shape. Owned by the
|
|
10
|
+
* kernel (the UI Transcript renders it; runtime/AgentPanel pass it around). */
|
|
11
|
+
export interface ConversationTurn {
|
|
12
|
+
id: string;
|
|
13
|
+
included: boolean;
|
|
14
|
+
messages: ChatCompletionMessageParam[];
|
|
15
|
+
/** Token/cost/latency for the assistant response, once the turn settles. */
|
|
16
|
+
stats?: TurnStats;
|
|
17
|
+
}
|
|
18
|
+
export declare function getTurns(): ConversationTurn[];
|
|
19
|
+
/** React-style setter: accepts a value or an updater. */
|
|
20
|
+
export declare function setTurns(next: ConversationTurn[] | ((prev: ConversationTurn[]) => ConversationTurn[])): void;
|
|
21
|
+
/** Toggle a turn's include flag (warm-context inclusion — before compression). */
|
|
22
|
+
export declare function toggleInclude(id: string): void;
|
|
23
|
+
/** Subscribe a component to the live turns. */
|
|
24
|
+
export declare function useConversation(): {
|
|
25
|
+
turns: ConversationTurn[];
|
|
26
|
+
setTurns: typeof setTurns;
|
|
27
|
+
toggleInclude: typeof toggleInclude;
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=conversation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../conversation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAEpF,qFAAqF;AACrF,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;+EAC+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,4EAA4E;IAC5E,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAMD,wBAAgB,QAAQ,IAAI,gBAAgB,EAAE,CAAkB;AAEhE,yDAAyD;AACzD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,CAAC,GAAG,IAAI,CAG5G;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,+CAA+C;AAC/C,wBAAgB,eAAe,IAAI;IACjC,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,aAAa,EAAE,OAAO,aAAa,CAAC;CACrC,CAIA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* Shared conversation store — the assistant's live turns, lifted out of AgentPanel
|
|
2
|
+
* so sibling surfaces (the Context Manager dock panel) can read them and toggle
|
|
3
|
+
* include/exclude. Module-level + reactive (same pattern as lib/usage, recall).
|
|
4
|
+
* Session load/save still lives in AgentPanel; this is just the live buffer. */
|
|
5
|
+
import { useEffect, useReducer } from 'react';
|
|
6
|
+
let turns = [];
|
|
7
|
+
const listeners = new Set();
|
|
8
|
+
const notify = () => { listeners.forEach((fn) => fn()); };
|
|
9
|
+
export function getTurns() { return turns; }
|
|
10
|
+
/** React-style setter: accepts a value or an updater. */
|
|
11
|
+
export function setTurns(next) {
|
|
12
|
+
turns = typeof next === 'function' ? next(turns) : next;
|
|
13
|
+
notify();
|
|
14
|
+
}
|
|
15
|
+
/** Toggle a turn's include flag (warm-context inclusion — before compression). */
|
|
16
|
+
export function toggleInclude(id) {
|
|
17
|
+
setTurns((t) => t.map((x) => (x.id === id ? { ...x, included: !x.included } : x)));
|
|
18
|
+
}
|
|
19
|
+
/** Subscribe a component to the live turns. */
|
|
20
|
+
export function useConversation() {
|
|
21
|
+
const [, force] = useReducer((x) => x + 1, 0);
|
|
22
|
+
useEffect(() => { listeners.add(force); return () => { listeners.delete(force); }; }, []);
|
|
23
|
+
return { turns, setTurns, toggleInclude };
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=conversation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.js","sourceRoot":"","sources":["../conversation.ts"],"names":[],"mappings":"AAAA;;;gFAGgF;AAChF,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAqB9C,IAAI,KAAK,GAAuB,EAAE,CAAC;AACnC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;AACxC,MAAM,MAAM,GAAG,GAAS,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhE,MAAM,UAAU,QAAQ,KAAyB,OAAO,KAAK,CAAC,CAAC,CAAC;AAEhE,yDAAyD;AACzD,MAAM,UAAU,QAAQ,CAAC,IAA6E;IACpG,KAAK,GAAG,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAE,IAAsD,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3G,MAAM,EAAE,CAAC;AACX,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,aAAa,CAAC,EAAU;IACtC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrF,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,eAAe;IAK7B,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACtD,SAAS,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1F,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type OpenAI from 'openai';
|
|
2
|
+
import type { ChatCompletionMessageParam } from 'openai/resources/chat/completions';
|
|
3
|
+
import type { AgentTool, ToolContext, AgentEvent, Usage } from '@corenel/protocol';
|
|
4
|
+
import type { Policy } from '@corenel/protocol';
|
|
5
|
+
import type { PermissionService } from '../guardrail/permission-service';
|
|
6
|
+
import { type CompressionConfig } from '../compression';
|
|
7
|
+
export interface RunAgentArgs {
|
|
8
|
+
client: OpenAI;
|
|
9
|
+
model: string;
|
|
10
|
+
system?: string;
|
|
11
|
+
messages: ChatCompletionMessageParam[];
|
|
12
|
+
tools: AgentTool[];
|
|
13
|
+
toolCtx: ToolContext;
|
|
14
|
+
maxTurns?: number;
|
|
15
|
+
/** Governance policy for the run (guardrail gates). Defaults to STANDARD_POLICY. */
|
|
16
|
+
policy?: Policy;
|
|
17
|
+
/** Per-tool permission resolver. When omitted, tools run without an approval gate. */
|
|
18
|
+
permission?: PermissionService;
|
|
19
|
+
/** Context-compression config (rung-1 offload). Omit to disable. */
|
|
20
|
+
compression?: CompressionConfig;
|
|
21
|
+
signal?: AbortSignal;
|
|
22
|
+
onEvent?: (e: AgentEvent) => void;
|
|
23
|
+
}
|
|
24
|
+
export interface RunAgentResult {
|
|
25
|
+
messages: ChatCompletionMessageParam[];
|
|
26
|
+
text: string;
|
|
27
|
+
usage: Usage;
|
|
28
|
+
stopReason: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function runAgent(args: RunAgentArgs): Promise<RunAgentResult>;
|
|
31
|
+
//# sourceMappingURL=loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../core/loop.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,0BAA0B,EAAsB,MAAM,mCAAmC,CAAC;AACxG,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAOnF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAwC,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE9F,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,oEAAoE;IACpE,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CA6M1E"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { streamCompletion } from '../providers/gateway';
|
|
2
|
+
import { alog } from '../log';
|
|
3
|
+
import { initialState, evaluateTurnStart, evaluateToolCall, evaluateCompletion } from '../guardrail/guardrail';
|
|
4
|
+
import { checkFeature } from '../guards';
|
|
5
|
+
import { STANDARD_POLICY } from '../guardrail/builtins';
|
|
6
|
+
import { toolAddress } from '../tools/namespaces';
|
|
7
|
+
import { effectiveThreshold, formatOffloadRef } from '../compression';
|
|
8
|
+
export async function runAgent(args) {
|
|
9
|
+
const { client, model, system, tools, toolCtx } = args;
|
|
10
|
+
const policy = args.policy ?? STANDARD_POLICY;
|
|
11
|
+
const permission = args.permission;
|
|
12
|
+
const compression = args.compression;
|
|
13
|
+
const ctxWindow = compression?.contextWindow;
|
|
14
|
+
let fill = 0; // window fill ratio; drives the adaptive offload threshold
|
|
15
|
+
const maxTurns = policy.maxTurns ?? args.maxTurns ?? 8;
|
|
16
|
+
const signal = args.signal ?? new AbortController().signal;
|
|
17
|
+
const emit = (e) => args.onEvent?.(e);
|
|
18
|
+
const gstate = initialState();
|
|
19
|
+
const messages = [...args.messages];
|
|
20
|
+
if (system && !messages.some((m) => m.role === 'system')) {
|
|
21
|
+
messages.unshift({ role: 'system', content: system });
|
|
22
|
+
}
|
|
23
|
+
const toolDefs = tools.map((t) => ({
|
|
24
|
+
type: 'function',
|
|
25
|
+
function: { name: t.name, description: t.description, parameters: t.parameters },
|
|
26
|
+
}));
|
|
27
|
+
const toolByName = new Map(tools.map((t) => [t.name, t]));
|
|
28
|
+
const usage = { promptTokens: 0, completionTokens: 0 };
|
|
29
|
+
let text = '';
|
|
30
|
+
let stopReason = 'stop';
|
|
31
|
+
let lastToolSig = null;
|
|
32
|
+
for (let turn = 1; turn <= maxTurns; turn++) {
|
|
33
|
+
if (signal.aborted) {
|
|
34
|
+
stopReason = 'aborted';
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
emit({ type: 'turn', turn });
|
|
38
|
+
// Turn-budget guardrail (gstate.turn = completed turns).
|
|
39
|
+
gstate.turn = turn - 1;
|
|
40
|
+
const turnGate = evaluateTurnStart(policy, gstate);
|
|
41
|
+
if (!turnGate.ok) {
|
|
42
|
+
emit({ type: 'policy-violation', kind: turnGate.violation.kind, message: turnGate.violation.message, action: turnGate.action, tool: turnGate.violation.tool });
|
|
43
|
+
if (turnGate.action === 'stop') {
|
|
44
|
+
stopReason = 'policy';
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
let streamed;
|
|
49
|
+
try {
|
|
50
|
+
streamed = await streamCompletion(client, {
|
|
51
|
+
model,
|
|
52
|
+
messages,
|
|
53
|
+
tools: toolDefs.length ? toolDefs : undefined,
|
|
54
|
+
tool_choice: toolDefs.length ? 'auto' : undefined,
|
|
55
|
+
}, signal, (delta) => emit({ type: 'assistant-delta', delta }));
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
if (signal.aborted || e?.name === 'AbortError') {
|
|
59
|
+
stopReason = 'aborted';
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
emit({ type: 'error', message: String(e?.message || e) });
|
|
63
|
+
stopReason = 'error';
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
usage.promptTokens += streamed.usage.promptTokens;
|
|
67
|
+
usage.completionTokens += streamed.usage.completionTokens;
|
|
68
|
+
if (ctxWindow && ctxWindow > 0 && streamed.usage.promptTokens) {
|
|
69
|
+
fill = Math.min(1, streamed.usage.promptTokens / ctxWindow);
|
|
70
|
+
}
|
|
71
|
+
emit({ type: 'usage', usage: streamed.usage });
|
|
72
|
+
// Commit the assistant message to history (with tool_calls if any).
|
|
73
|
+
const assistantMsg = streamed.toolCalls.length
|
|
74
|
+
? {
|
|
75
|
+
role: 'assistant',
|
|
76
|
+
content: streamed.content || null,
|
|
77
|
+
tool_calls: streamed.toolCalls.map((t) => ({
|
|
78
|
+
id: t.id,
|
|
79
|
+
type: 'function',
|
|
80
|
+
function: { name: t.name, arguments: t.arguments },
|
|
81
|
+
})),
|
|
82
|
+
}
|
|
83
|
+
: { role: 'assistant', content: streamed.content };
|
|
84
|
+
messages.push(assistantMsg);
|
|
85
|
+
if (streamed.content) {
|
|
86
|
+
text = streamed.content;
|
|
87
|
+
emit({ type: 'assistant', content: streamed.content });
|
|
88
|
+
}
|
|
89
|
+
if (streamed.toolCalls.length === 0) {
|
|
90
|
+
stopReason = streamed.finishReason || 'stop';
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
// No-progress guard: identical tool calls to the previous turn => stuck.
|
|
94
|
+
const sig = JSON.stringify(streamed.toolCalls.map((t) => ({ n: t.name, a: t.arguments })));
|
|
95
|
+
if (sig === lastToolSig) {
|
|
96
|
+
emit({ type: 'error', message: 'Stopped: the model repeated the same tool call without making progress.' });
|
|
97
|
+
stopReason = 'stuck';
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
lastToolSig = sig;
|
|
101
|
+
let policyStop = false;
|
|
102
|
+
for (const call of streamed.toolCalls) {
|
|
103
|
+
let parsed = {};
|
|
104
|
+
try {
|
|
105
|
+
parsed = call.arguments ? JSON.parse(call.arguments) : {};
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
messages.push({ role: 'tool', tool_call_id: call.id, content: `Error: arguments were not valid JSON: ${call.arguments}` });
|
|
109
|
+
emit({ type: 'tool-result', id: call.id, name: call.name, result: 'invalid JSON arguments', isError: true });
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
alog('tool', call.name, parsed);
|
|
113
|
+
emit({ type: 'tool-call', id: call.id, name: call.name, args: parsed });
|
|
114
|
+
const tool = toolByName.get(call.name);
|
|
115
|
+
if (!tool) {
|
|
116
|
+
messages.push({ role: 'tool', tool_call_id: call.id, content: `Error: unknown tool "${call.name}"` });
|
|
117
|
+
emit({ type: 'tool-result', id: call.id, name: call.name, result: 'unknown tool', isError: true });
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
// Policy address (namespace:name) so guardrail/permission globs can target
|
|
121
|
+
// a whole namespace (fs:*) or one tool, while bare names still match.
|
|
122
|
+
const address = toolAddress(tool);
|
|
123
|
+
// Guardrail gate: allow/deny lists + tool-call budget.
|
|
124
|
+
const gate = evaluateToolCall(policy, gstate, { name: call.name, exists: true, address });
|
|
125
|
+
if (!gate.ok) {
|
|
126
|
+
const msg = `Blocked by policy "${policy.name}": ${gate.violation.message}`;
|
|
127
|
+
messages.push({ role: 'tool', tool_call_id: call.id, content: `Error: ${msg}` });
|
|
128
|
+
emit({ type: 'policy-violation', kind: gate.violation.kind, message: gate.violation.message, action: gate.action, tool: call.name });
|
|
129
|
+
emit({ type: 'tool-result', id: call.id, name: call.name, result: msg, isError: true });
|
|
130
|
+
if (gate.action === 'stop') {
|
|
131
|
+
policyStop = true;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
// Feature gate: the host's registered guards (auth/quota/plan/token). A tool
|
|
137
|
+
// that declares requiresFeature only runs when no guard denies it — enforced
|
|
138
|
+
// by the kernel, so it holds in the browser, the node CLI, and the sidecar.
|
|
139
|
+
if (tool.requiresFeature) {
|
|
140
|
+
const verdict = await checkFeature(tool.requiresFeature);
|
|
141
|
+
if (!verdict.allowed) {
|
|
142
|
+
const msg = `Feature unavailable (${tool.requiresFeature}): ${verdict.reason}`;
|
|
143
|
+
messages.push({ role: 'tool', tool_call_id: call.id, content: `Error: ${msg}` });
|
|
144
|
+
emit({ type: 'tool-result', id: call.id, name: tool.name, result: msg, isError: true });
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Permission gate: resolve oversight level, ask the user when required.
|
|
149
|
+
if (permission) {
|
|
150
|
+
const decision = await permission.check({ name: tool.name, address, mutates: tool.mutates, permission: tool.permission }, parsed);
|
|
151
|
+
emit({ type: 'permission', tool: tool.name, decision });
|
|
152
|
+
if (decision === 'deny') {
|
|
153
|
+
messages.push({ role: 'tool', tool_call_id: call.id, content: 'Permission denied by the user — the action was not performed.' });
|
|
154
|
+
emit({ type: 'tool-result', id: call.id, name: tool.name, result: 'permission denied', isError: true });
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const startedAt = Date.now();
|
|
159
|
+
try {
|
|
160
|
+
// Per-call context: callId lets a tool correlate with UI state keyed by
|
|
161
|
+
// tool_call id (propose_edit blocks on its review).
|
|
162
|
+
const result = await tool.run(parsed, { ...toolCtx, callId: call.id });
|
|
163
|
+
const durationMs = Date.now() - startedAt;
|
|
164
|
+
gstate.toolCalls++;
|
|
165
|
+
gstate.calledTools.add(tool.name);
|
|
166
|
+
gstate.calledTools.add(address); // so mustCall globs may use either form
|
|
167
|
+
// Context compression (rung-1): offload a large, offloadable output to the
|
|
168
|
+
// RecallStore and append a compact reference instead. Append-only — never
|
|
169
|
+
// rewrites prior messages, so the OpenAI prefix cache stays valid.
|
|
170
|
+
let out = result;
|
|
171
|
+
if (compression && compression.mode !== 'off' && !tool.noOffload && toolCtx.recall) {
|
|
172
|
+
if (result.length > effectiveThreshold(compression.mode, fill)) {
|
|
173
|
+
const ref = await toolCtx.recall.record(tool.name, result);
|
|
174
|
+
out = formatOffloadRef(ref);
|
|
175
|
+
emit({ type: 'offload', id: ref.id, name: tool.name, bytes: ref.bytes });
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
messages.push({ role: 'tool', tool_call_id: call.id, content: out });
|
|
179
|
+
emit({ type: 'tool-result', id: call.id, name: call.name, result: out, durationMs });
|
|
180
|
+
}
|
|
181
|
+
catch (e) {
|
|
182
|
+
const errMsg = String(e?.message || e);
|
|
183
|
+
messages.push({ role: 'tool', tool_call_id: call.id, content: `Error: ${errMsg}` });
|
|
184
|
+
emit({ type: 'tool-result', id: call.id, name: call.name, result: errMsg, isError: true, durationMs: Date.now() - startedAt });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (policyStop) {
|
|
188
|
+
stopReason = 'policy';
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
if (turn === maxTurns)
|
|
192
|
+
stopReason = 'max_turns';
|
|
193
|
+
}
|
|
194
|
+
// A stop that breaks AFTER committing the assistant tool_calls message but
|
|
195
|
+
// before every call ran (no-progress, policy-stop with parallel calls) leaves a
|
|
196
|
+
// tool_call with no result. The OpenAI message contract requires one result per
|
|
197
|
+
// tool_call_id, so reusing these messages as conversation history would 400 on
|
|
198
|
+
// the next turn ("did not have response messages"). Backfill any gaps.
|
|
199
|
+
reconcileDanglingToolCalls(messages);
|
|
200
|
+
// Completion guardrail: required tools must have been invoked.
|
|
201
|
+
for (const v of evaluateCompletion(policy, gstate)) {
|
|
202
|
+
emit({ type: 'policy-violation', kind: v.kind, message: v.message, action: 'stop', tool: v.tool });
|
|
203
|
+
}
|
|
204
|
+
alog('done', stopReason, 'tokens', usage);
|
|
205
|
+
emit({ type: 'done', reason: stopReason });
|
|
206
|
+
return { messages, text, usage, stopReason };
|
|
207
|
+
}
|
|
208
|
+
/** Ensure every tool_call in the final assistant message has a following tool
|
|
209
|
+
* result — appending a synthetic one for any the run stopped before answering —
|
|
210
|
+
* so the returned messages stay a valid conversation prefix. */
|
|
211
|
+
function reconcileDanglingToolCalls(messages) {
|
|
212
|
+
let idx = -1;
|
|
213
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
214
|
+
const m = messages[i];
|
|
215
|
+
if (m.role === 'assistant' && m.tool_calls && m.tool_calls.length) {
|
|
216
|
+
idx = i;
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (idx < 0)
|
|
221
|
+
return;
|
|
222
|
+
const asst = messages[idx];
|
|
223
|
+
if (asst.role !== 'assistant' || !asst.tool_calls)
|
|
224
|
+
return;
|
|
225
|
+
const answered = new Set();
|
|
226
|
+
for (let i = idx + 1; i < messages.length; i++) {
|
|
227
|
+
const m = messages[i];
|
|
228
|
+
if (m.role === 'tool')
|
|
229
|
+
answered.add(m.tool_call_id);
|
|
230
|
+
}
|
|
231
|
+
for (const c of asst.tool_calls) {
|
|
232
|
+
if (!answered.has(c.id)) {
|
|
233
|
+
messages.push({ role: 'tool', tool_call_id: c.id, content: 'Tool not run — the run stopped before this call.' });
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../core/loop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type OpenAI from 'openai';
|
|
2
|
+
import type { PermissionService } from '../guardrail/permission-service';
|
|
3
|
+
import type { AgentTool, AgentEvent, ToolContext, Policy, CompressionConfig, NodeOutput, NodeEvent, NodeSpec, RunNodeResult } from '@corenel/protocol';
|
|
4
|
+
export type { NodeSpec, RunNodeResult } from '@corenel/protocol';
|
|
5
|
+
export interface NodeRunRequest {
|
|
6
|
+
node: NodeSpec;
|
|
7
|
+
/** Upstream outputs keyed by edge/port name (empty for a root/dynamic spawn). */
|
|
8
|
+
inputs: Record<string, NodeOutput>;
|
|
9
|
+
signal: AbortSignal;
|
|
10
|
+
onEvent: (e: NodeEvent) => void;
|
|
11
|
+
}
|
|
12
|
+
/** Everything runNode needs that isn't on the request (supplied by the worker or
|
|
13
|
+
* the scheduler): the chat client, the full available tool set, the bridge-backed
|
|
14
|
+
* ToolContext, and the run governance. */
|
|
15
|
+
export interface RunNodeDeps {
|
|
16
|
+
client: OpenAI;
|
|
17
|
+
defaultModel: string;
|
|
18
|
+
tools: AgentTool[];
|
|
19
|
+
toolCtx: ToolContext;
|
|
20
|
+
policy?: Policy;
|
|
21
|
+
permission?: PermissionService;
|
|
22
|
+
compression?: CompressionConfig;
|
|
23
|
+
defaultSystem?: string;
|
|
24
|
+
}
|
|
25
|
+
/** Read-biased default tool set for a node with no explicit allowlist (§4). No
|
|
26
|
+
* mutating tools, so a delegated node never writes unless its allowlist opts in. */
|
|
27
|
+
export declare const READ_BIASED_TOOLS: string[];
|
|
28
|
+
export declare const SUBAGENT_SYSTEM: string;
|
|
29
|
+
/** Resolve the node's effective tool list: allowlist (or read-biased default),
|
|
30
|
+
* with spawn_* tools dropped when this context can't spawn (the depth cap). */
|
|
31
|
+
export declare function resolveTools(all: AgentTool[], allow: string[] | undefined, ctx: ToolContext): AgentTool[];
|
|
32
|
+
/** Render a node's task: literal `task` wins; else a Nunjucks `promptTemplate`
|
|
33
|
+
* bound to { inputs } via the real engine; else fan-in concat of upstream text. */
|
|
34
|
+
export declare function composeTask(node: NodeSpec, inputs: Record<string, NodeOutput>): Promise<string>;
|
|
35
|
+
/** Run one node to completion. Emits node-start, the wrapped per-turn AgentEvents,
|
|
36
|
+
* then node-done (or node-error). Safe to call concurrently. */
|
|
37
|
+
export declare function runNode(req: NodeRunRequest, deps: RunNodeDeps): Promise<RunNodeResult>;
|
|
38
|
+
/** Wrap a plain AgentEvent callback into the node-tagged stream (§9.3) — used by
|
|
39
|
+
* the root-session adapter so root + sub-agents tag identically. */
|
|
40
|
+
export declare function wrapAsNodeEvents(nodeId: string, onNode: (e: NodeEvent) => void): (e: AgentEvent) => void;
|
|
41
|
+
//# sourceMappingURL=executeNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executeNode.d.ts","sourceRoot":"","sources":["../../dag/executeNode.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAIjC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,KAAK,EACV,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,EAC7D,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAC/C,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;CACjC;AAED;;0CAE0C;AAC1C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;oFACoF;AACpF,eAAO,MAAM,iBAAiB,UAI7B,CAAC;AAEF,eAAO,MAAM,eAAe,QAI6D,CAAC;AAE1F;+EAC+E;AAC/E,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,GAAG,EAAE,WAAW,GAAG,SAAS,EAAE,CAKzG;AAED;mFACmF;AACnF,wBAAsB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAWrG;AAED;gEACgE;AAChE,wBAAsB,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAiC5F;AAED;oEACoE;AACpE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,GAAG,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAExG"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { runAgent } from '../core/loop';
|
|
2
|
+
import { compilePrompt } from '../promptCompiler';
|
|
3
|
+
/** Read-biased default tool set for a node with no explicit allowlist (§4). No
|
|
4
|
+
* mutating tools, so a delegated node never writes unless its allowlist opts in. */
|
|
5
|
+
export const READ_BIASED_TOOLS = [
|
|
6
|
+
'compile_prompd', 'search_packages', 'web_search',
|
|
7
|
+
'read_file', 'list_files', 'search_files', 'stat_file',
|
|
8
|
+
'recall_result', 'recall_memory', 'kv_get',
|
|
9
|
+
];
|
|
10
|
+
export const SUBAGENT_SYSTEM = 'You are a focused Prompd sub-agent. A parent agent has delegated ONE ' +
|
|
11
|
+
'self-contained task to you. You do not see the parent conversation. Complete ' +
|
|
12
|
+
'only that task and return a concise, complete result the parent can use ' +
|
|
13
|
+
'directly. Prefer calling a tool over guessing. State the result plainly, no preamble.';
|
|
14
|
+
/** Resolve the node's effective tool list: allowlist (or read-biased default),
|
|
15
|
+
* with spawn_* tools dropped when this context can't spawn (the depth cap). */
|
|
16
|
+
export function resolveTools(all, allow, ctx) {
|
|
17
|
+
const wanted = new Set(allow && allow.length ? allow : READ_BIASED_TOOLS);
|
|
18
|
+
let tools = all.filter((t) => wanted.has(t.name));
|
|
19
|
+
if (!ctx.spawn)
|
|
20
|
+
tools = tools.filter((t) => !t.name.startsWith('spawn_'));
|
|
21
|
+
return tools;
|
|
22
|
+
}
|
|
23
|
+
/** Render a node's task: literal `task` wins; else a Nunjucks `promptTemplate`
|
|
24
|
+
* bound to { inputs } via the real engine; else fan-in concat of upstream text. */
|
|
25
|
+
export async function composeTask(node, inputs) {
|
|
26
|
+
if (typeof node.task === 'string')
|
|
27
|
+
return node.task;
|
|
28
|
+
if (node.promptTemplate) {
|
|
29
|
+
// Wrap the template body in a minimal valid .prmd so the host's compiler
|
|
30
|
+
// renders it; parameters become top-level vars, so `inputs` is addressable.
|
|
31
|
+
const doc = `---\nid: dag-node\nname: dag-node\nversion: 1.0.0\n---\n${node.promptTemplate}`;
|
|
32
|
+
const r = await compilePrompt(doc, { inputs });
|
|
33
|
+
return r.output;
|
|
34
|
+
}
|
|
35
|
+
const keys = Object.keys(inputs ?? {});
|
|
36
|
+
return keys.map((k) => inputs[k]?.text ?? '').filter(Boolean).join('\n\n');
|
|
37
|
+
}
|
|
38
|
+
/** Run one node to completion. Emits node-start, the wrapped per-turn AgentEvents,
|
|
39
|
+
* then node-done (or node-error). Safe to call concurrently. */
|
|
40
|
+
export async function runNode(req, deps) {
|
|
41
|
+
const { node, inputs, signal, onEvent } = req;
|
|
42
|
+
onEvent({ type: 'node-start', nodeId: node.id });
|
|
43
|
+
let turns = 0;
|
|
44
|
+
try {
|
|
45
|
+
const task = await composeTask(node, inputs);
|
|
46
|
+
const tools = resolveTools(deps.tools, node.tools, deps.toolCtx);
|
|
47
|
+
const messages = [{ role: 'user', content: task }];
|
|
48
|
+
const result = await runAgent({
|
|
49
|
+
client: deps.client,
|
|
50
|
+
model: node.model || deps.defaultModel,
|
|
51
|
+
system: node.system || deps.defaultSystem || SUBAGENT_SYSTEM,
|
|
52
|
+
messages,
|
|
53
|
+
tools,
|
|
54
|
+
toolCtx: deps.toolCtx,
|
|
55
|
+
maxTurns: node.maxTurns,
|
|
56
|
+
policy: deps.policy,
|
|
57
|
+
permission: deps.permission,
|
|
58
|
+
compression: deps.compression,
|
|
59
|
+
signal,
|
|
60
|
+
onEvent: (e) => {
|
|
61
|
+
if (e.type === 'turn')
|
|
62
|
+
turns = e.turn;
|
|
63
|
+
onEvent({ type: 'node-event', nodeId: node.id, event: e });
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
const output = { text: result.text, usage: result.usage, stopReason: result.stopReason };
|
|
67
|
+
onEvent({ type: 'node-done', nodeId: node.id, output });
|
|
68
|
+
return { ...output, turns };
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
const message = String(e?.message || e);
|
|
72
|
+
onEvent({ type: 'node-error', nodeId: node.id, message });
|
|
73
|
+
throw e;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** Wrap a plain AgentEvent callback into the node-tagged stream (§9.3) — used by
|
|
77
|
+
* the root-session adapter so root + sub-agents tag identically. */
|
|
78
|
+
export function wrapAsNodeEvents(nodeId, onNode) {
|
|
79
|
+
return (event) => onNode({ type: 'node-event', nodeId, event });
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=executeNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executeNode.js","sourceRoot":"","sources":["../../dag/executeNode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config path of the per-filetype system prompt for the active file, or null when
|
|
3
|
+
* there's no recognized file. A `.md`/`.markdown` only counts as a prompt when it
|
|
4
|
+
* actually carries frontmatter (a plain note does not).
|
|
5
|
+
*/
|
|
6
|
+
export declare function systemForFile(fileName: string, src?: string): string | null;
|
|
7
|
+
//# sourceMappingURL=fileSchema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileSchema.d.ts","sourceRoot":"","sources":["../fileSchema.ts"],"names":[],"mappings":"AA2BA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAK,GAAG,MAAM,GAAG,IAAI,CAMvE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/* Per-filetype system prompt selection.
|
|
2
|
+
*
|
|
3
|
+
* When the assistant works over a recognized Prompd file, it should use a system
|
|
4
|
+
* prompt that teaches the file's FORMAT — the .prmd/.md frontmatter+param schema
|
|
5
|
+
* and Nunjucks body, or the .pdflow node taxonomy — so it edits the structure
|
|
6
|
+
* correctly instead of guessing. Those docs are authorable markdown that inherit
|
|
7
|
+
* the base system prompt (prompts/library/systems/system-<ext...>.md), discovered
|
|
8
|
+
* by extension via SYSTEM_BY_EXT.
|
|
9
|
+
*
|
|
10
|
+
* `systemForFile` returns the config-workspace path of the matching system doc, or
|
|
11
|
+
* null when there's no recognized file — in which case the caller falls back to
|
|
12
|
+
* the base system prompt. To add a format, drop a `system-<ext>.md` in the systems
|
|
13
|
+
* folder; no code change here is required for a new single-extension type.
|
|
14
|
+
*/
|
|
15
|
+
import { SYSTEM_BY_EXT } from './prompts/library';
|
|
16
|
+
/** Whether a Markdown document opens with a YAML frontmatter fence — only then is
|
|
17
|
+
* a .md file a Prompd prompt (a plain note isn't). */
|
|
18
|
+
const hasFrontmatter = (src) => /^\s*---\r?\n/.test(src || '');
|
|
19
|
+
/** Lowercased extension after the last dot (no dot), or '' when there is none. */
|
|
20
|
+
function extOf(fileName) {
|
|
21
|
+
const name = (fileName || '').toLowerCase();
|
|
22
|
+
const dot = name.lastIndexOf('.');
|
|
23
|
+
return dot === -1 ? '' : name.slice(dot + 1);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Config path of the per-filetype system prompt for the active file, or null when
|
|
27
|
+
* there's no recognized file. A `.md`/`.markdown` only counts as a prompt when it
|
|
28
|
+
* actually carries frontmatter (a plain note does not).
|
|
29
|
+
*/
|
|
30
|
+
export function systemForFile(fileName, src = '') {
|
|
31
|
+
let ext = extOf(fileName);
|
|
32
|
+
if (ext === 'markdown')
|
|
33
|
+
ext = 'md';
|
|
34
|
+
if (!ext)
|
|
35
|
+
return null;
|
|
36
|
+
if (ext === 'md' && !hasFrontmatter(src))
|
|
37
|
+
return null;
|
|
38
|
+
return SYSTEM_BY_EXT[ext] ?? null;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=fileSchema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileSchema.js","sourceRoot":"","sources":["../fileSchema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD;sDACsD;AACtD,MAAM,cAAc,GAAG,CAAC,GAAW,EAAW,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;AAEhF,kFAAkF;AAClF,SAAS,KAAK,CAAC,QAAgB;IAC7B,MAAM,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,GAAG,GAAG,EAAE;IACtD,IAAI,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC1B,IAAI,GAAG,KAAK,UAAU;QAAE,GAAG,GAAG,IAAI,CAAC;IACnC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Policy } from '@corenel/protocol';
|
|
2
|
+
/** Default: read freely, ask before any side effect (file/memory writes). */
|
|
3
|
+
export declare const STANDARD_POLICY: Policy;
|
|
4
|
+
/** Strict: no side effects at all. Mutating tools are denied outright. */
|
|
5
|
+
export declare const READ_ONLY_POLICY: Policy;
|
|
6
|
+
/** Unattended: everything runs without prompting, except harness self-config. */
|
|
7
|
+
export declare const AUTONOMOUS_POLICY: Policy;
|
|
8
|
+
export declare const BUILTIN_POLICIES: Record<string, Policy>;
|
|
9
|
+
//# sourceMappingURL=builtins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../../guardrail/builtins.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,6EAA6E;AAC7E,eAAO,MAAM,eAAe,EAAE,MAW7B,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,EAAE,MA4B9B,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,EAAE,MAU/B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAInD,CAAC"}
|