@harperfast/harper 5.2.0-alpha.4 → 5.2.0-alpha.6
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/agent/agent.ts +152 -10
- package/agent/bestPractices.ts +58 -0
- package/agent/mcpTools.ts +122 -0
- package/agent/operations.ts +10 -1
- package/agent/registryTools.ts +117 -0
- package/agent/session.ts +16 -7
- package/agent/tools/fsTools.ts +74 -27
- package/agent/tools/inspectorTool.ts +459 -0
- package/agent/toolset.ts +27 -7
- package/agent/types.ts +2 -0
- package/components/Application.ts +566 -85
- package/components/OptionsWatcher.ts +62 -2
- package/components/Scope.ts +31 -8
- package/components/componentLoader.ts +5 -1
- package/components/componentSecrets.ts +514 -55
- package/components/deploymentRecorder.ts +7 -6
- package/components/gitCredentialHelper.js +115 -0
- package/components/gitCredentialServer.ts +251 -0
- package/components/mcp/tools/application.ts +197 -23
- package/components/mcp/tools/operations.ts +1 -1
- package/components/mcp/tools/schemas/derive.ts +6 -2
- package/components/operations.js +21 -19
- package/components/operationsValidation.js +86 -21
- package/components/secretOperations.ts +110 -30
- package/config/harperConfigEnvVars.ts +90 -5
- package/config-root.schema.json +4 -0
- package/dist/agent/agent.d.ts +24 -3
- package/dist/agent/agent.js +172 -10
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/bestPractices.d.ts +24 -0
- package/dist/agent/bestPractices.js +60 -0
- package/dist/agent/bestPractices.js.map +1 -0
- package/dist/agent/mcpTools.d.ts +24 -0
- package/dist/agent/mcpTools.js +115 -0
- package/dist/agent/mcpTools.js.map +1 -0
- package/dist/agent/operations.js +10 -1
- package/dist/agent/operations.js.map +1 -1
- package/dist/agent/registryTools.d.ts +45 -0
- package/dist/agent/registryTools.js +113 -0
- package/dist/agent/registryTools.js.map +1 -0
- package/dist/agent/session.js +16 -7
- package/dist/agent/session.js.map +1 -1
- package/dist/agent/tools/fsTools.js +70 -28
- package/dist/agent/tools/fsTools.js.map +1 -1
- package/dist/agent/tools/inspectorTool.d.ts +40 -0
- package/dist/agent/tools/inspectorTool.js +428 -0
- package/dist/agent/tools/inspectorTool.js.map +1 -0
- package/dist/agent/toolset.d.ts +16 -6
- package/dist/agent/toolset.js +17 -7
- package/dist/agent/toolset.js.map +1 -1
- package/dist/agent/types.d.ts +2 -0
- package/dist/components/Application.d.ts +73 -18
- package/dist/components/Application.js +475 -64
- package/dist/components/Application.js.map +1 -1
- package/dist/components/OptionsWatcher.d.ts +1 -1
- package/dist/components/OptionsWatcher.js +65 -2
- package/dist/components/OptionsWatcher.js.map +1 -1
- package/dist/components/Scope.d.ts +8 -6
- package/dist/components/Scope.js +22 -6
- package/dist/components/Scope.js.map +1 -1
- package/dist/components/componentLoader.js +5 -1
- package/dist/components/componentLoader.js.map +1 -1
- package/dist/components/componentSecrets.d.ts +33 -7
- package/dist/components/componentSecrets.js +473 -59
- package/dist/components/componentSecrets.js.map +1 -1
- package/dist/components/deploymentRecorder.d.ts +2 -2
- package/dist/components/deploymentRecorder.js +1 -1
- package/dist/components/deploymentRecorder.js.map +1 -1
- package/dist/components/gitCredentialHelper.d.ts +1 -0
- package/dist/components/gitCredentialHelper.js +113 -0
- package/dist/components/gitCredentialHelper.js.map +1 -0
- package/dist/components/gitCredentialServer.d.ts +33 -0
- package/dist/components/gitCredentialServer.js +236 -0
- package/dist/components/gitCredentialServer.js.map +1 -0
- package/dist/components/mcp/tools/application.d.ts +19 -0
- package/dist/components/mcp/tools/application.js +180 -22
- package/dist/components/mcp/tools/application.js.map +1 -1
- package/dist/components/mcp/tools/operations.d.ts +13 -0
- package/dist/components/mcp/tools/operations.js +1 -0
- package/dist/components/mcp/tools/operations.js.map +1 -1
- package/dist/components/mcp/tools/schemas/derive.js +6 -2
- package/dist/components/mcp/tools/schemas/derive.js.map +1 -1
- package/dist/components/operations.js +23 -21
- package/dist/components/operations.js.map +1 -1
- package/dist/components/operationsValidation.js +84 -21
- package/dist/components/operationsValidation.js.map +1 -1
- package/dist/components/secretOperations.d.ts +33 -11
- package/dist/components/secretOperations.js +90 -26
- package/dist/components/secretOperations.js.map +1 -1
- package/dist/config/harperConfigEnvVars.d.ts +21 -0
- package/dist/config/harperConfigEnvVars.js +95 -5
- package/dist/config/harperConfigEnvVars.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/resources/Resource.d.ts +19 -0
- package/dist/resources/Resource.js +93 -2
- package/dist/resources/Resource.js.map +1 -1
- package/dist/resources/Table.d.ts +9 -0
- package/dist/resources/Table.js +256 -50
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/analytics/read.js +28 -25
- package/dist/resources/analytics/read.js.map +1 -1
- package/dist/resources/defineResource.d.ts +180 -0
- package/dist/resources/defineResource.js +505 -0
- package/dist/resources/defineResource.js.map +1 -0
- package/dist/resources/defineTable.d.ts +221 -0
- package/dist/resources/defineTable.js +227 -0
- package/dist/resources/defineTable.js.map +1 -0
- package/dist/resources/jsonSchemaTypes.d.ts +2 -0
- package/dist/resources/jsonSchemaTypes.js +12 -4
- package/dist/resources/jsonSchemaTypes.js.map +1 -1
- package/dist/resources/openApi.js +69 -13
- package/dist/resources/openApi.js.map +1 -1
- package/dist/resources/search.js +6 -8
- package/dist/resources/search.js.map +1 -1
- package/dist/server/graphqlQuerying.js +4 -2
- package/dist/server/graphqlQuerying.js.map +1 -1
- package/dist/server/http.d.ts +12 -0
- package/dist/server/http.js +35 -15
- package/dist/server/http.js.map +1 -1
- package/dist/server/serverHelpers/serverUtilities.js +8 -5
- package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
- package/dist/server/serverHelpers/uwsServer.js +23 -0
- package/dist/server/serverHelpers/uwsServer.js.map +1 -1
- package/dist/utility/errors/hdbError.d.ts +21 -0
- package/dist/utility/errors/hdbError.js +23 -1
- package/dist/utility/errors/hdbError.js.map +1 -1
- package/dist/validation/configValidator.js +22 -6
- package/dist/validation/configValidator.js.map +1 -1
- package/index.ts +33 -0
- package/npm-shrinkwrap.json +9197 -15236
- package/package.json +5 -3
- package/resources/DESIGN.md +42 -15
- package/resources/Resource.ts +99 -2
- package/resources/Table.ts +275 -71
- package/resources/analytics/read.ts +30 -25
- package/resources/defineResource.ts +651 -0
- package/resources/defineTable.ts +407 -0
- package/resources/jsonSchemaTypes.ts +12 -4
- package/resources/openApi.ts +68 -16
- package/resources/search.ts +5 -8
- package/server/graphqlQuerying.ts +4 -2
- package/server/http.ts +40 -16
- package/server/serverHelpers/serverUtilities.ts +19 -6
- package/server/serverHelpers/uwsServer.ts +24 -0
- package/studio/web/assets/{Chat-D4FIaBu7.js → Chat-CTjtL8Z4.js} +2 -2
- package/studio/web/assets/{Chat-D4FIaBu7.js.map → Chat-CTjtL8Z4.js.map} +1 -1
- package/studio/web/assets/{FloatingChat-DGUC3L4r.js → FloatingChat-CafHR4Ur.js} +4 -4
- package/studio/web/assets/{FloatingChat-DGUC3L4r.js.map → FloatingChat-CafHR4Ur.js.map} +1 -1
- package/studio/web/assets/{applications-D8Am9ikM.js → applications-Buh_q0Vj.js} +2 -2
- package/studio/web/assets/{applications-D8Am9ikM.js.map → applications-Buh_q0Vj.js.map} +1 -1
- package/studio/web/assets/{index-HGL4WHdb.js → index-0hXeECkS.js} +6 -6
- package/studio/web/assets/{index-HGL4WHdb.js.map → index-0hXeECkS.js.map} +1 -1
- package/studio/web/assets/{index.lazy-Dk5j1AoQ.js → index.lazy-B00B7VBT.js} +4 -4
- package/studio/web/assets/{index.lazy-Dk5j1AoQ.js.map → index.lazy-B00B7VBT.js.map} +1 -1
- package/studio/web/assets/{profile-7bu_CF1f.js → profile-Cg2wwYPn.js} +2 -2
- package/studio/web/assets/{profile-7bu_CF1f.js.map → profile-Cg2wwYPn.js.map} +1 -1
- package/studio/web/assets/{setComponentFile-MfYm9F94.js → setComponentFile-DCaDIvyB.js} +2 -2
- package/studio/web/assets/{setComponentFile-MfYm9F94.js.map → setComponentFile-DCaDIvyB.js.map} +1 -1
- package/studio/web/assets/{setup-SKA4UhdE.js → setup-CAVcAQjK.js} +2 -2
- package/studio/web/assets/{setup-SKA4UhdE.js.map → setup-CAVcAQjK.js.map} +1 -1
- package/studio/web/assets/{status-DetVLUxR.js → status-BRXorNdD.js} +2 -2
- package/studio/web/assets/{status-DetVLUxR.js.map → status-BRXorNdD.js.map} +1 -1
- package/studio/web/assets/{swagger-ui-react-DLeYARY2.js → swagger-ui-react-Dy1D62vO.js} +2 -2
- package/studio/web/assets/{swagger-ui-react-DLeYARY2.js.map → swagger-ui-react-Dy1D62vO.js.map} +1 -1
- package/studio/web/assets/{tsMode-DGO-jIF7.js → tsMode-A8gbL74v.js} +2 -2
- package/studio/web/assets/{tsMode-DGO-jIF7.js.map → tsMode-A8gbL74v.js.map} +1 -1
- package/studio/web/assets/{useEntityRestURL-4M2i6bo4.js → useEntityRestURL-cDodrVcQ.js} +2 -2
- package/studio/web/assets/{useEntityRestURL-4M2i6bo4.js.map → useEntityRestURL-cDodrVcQ.js.map} +1 -1
- package/studio/web/index.html +1 -1
- package/utility/errors/hdbError.ts +32 -0
- package/validation/configValidator.ts +23 -6
package/dist/agent/agent.js
CHANGED
|
@@ -9,22 +9,63 @@
|
|
|
9
9
|
* is realized lazily on first use, and the loop runs in-process.
|
|
10
10
|
*
|
|
11
11
|
* The component intentionally avoids `handleApplication`: it has nothing
|
|
12
|
-
* worker-thread-shaped to do.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* worker-thread-shaped to do. Two tool sources compose: operator-only tools
|
|
13
|
+
* (FS, schedule, fetch, and the V8 inspector) that are inline, and RBAC-filtered
|
|
14
|
+
* registry tools (#615/#617) drained for the agent's configured user via
|
|
15
|
+
* `registryTools.ts`.
|
|
15
16
|
*/
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
34
|
+
var ownKeys = function(o) {
|
|
35
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
36
|
+
var ar = [];
|
|
37
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
38
|
+
return ar;
|
|
39
|
+
};
|
|
40
|
+
return ownKeys(o);
|
|
41
|
+
};
|
|
42
|
+
return function (mod) {
|
|
43
|
+
if (mod && mod.__esModule) return mod;
|
|
44
|
+
var result = {};
|
|
45
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
46
|
+
__setModuleDefault(result, mod);
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
})();
|
|
16
50
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
51
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
52
|
};
|
|
19
53
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
54
|
exports.startOnMainThread = startOnMainThread;
|
|
55
|
+
exports.resolveAgentIdentity = resolveAgentIdentity;
|
|
21
56
|
exports._resetForTests = _resetForTests;
|
|
22
57
|
const node_path_1 = require("node:path");
|
|
23
58
|
const hdbTerms_ts_1 = require("../utility/hdbTerms.js");
|
|
59
|
+
const env = __importStar(require("../utility/environment/environmentManager.js"));
|
|
24
60
|
const harper_logger_ts_1 = __importDefault(require("../utility/logging/harper_logger.js"));
|
|
25
61
|
const Models_ts_1 = require("../resources/models/Models.js");
|
|
62
|
+
const manageThreads_js_1 = require("../server/threads/manageThreads.js");
|
|
26
63
|
const toolset_ts_1 = require("./toolset.js");
|
|
64
|
+
const inspectorTool_ts_1 = require("./tools/inspectorTool.js");
|
|
65
|
+
const bestPractices_ts_1 = require("./bestPractices.js");
|
|
66
|
+
const registryTools_ts_1 = require("./registryTools.js");
|
|
27
67
|
const operations_ts_1 = require("./operations.js");
|
|
68
|
+
const mcpTools_ts_1 = require("./mcpTools.js");
|
|
28
69
|
const loop_ts_1 = require("./loop.js");
|
|
29
70
|
const session_ts_1 = require("./session.js");
|
|
30
71
|
const log = harper_logger_ts_1.default.loggerWithTag('agent');
|
|
@@ -48,10 +89,54 @@ async function startOnMainThread(opts) {
|
|
|
48
89
|
const models = new Models_ts_1.Models();
|
|
49
90
|
const abortControllers = new Map();
|
|
50
91
|
let liveConfig = config;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
92
|
+
// Populate the Operations MCP profile on the main thread. `agentIdentity` resolves the enforcement
|
|
93
|
+
// identity fresh on each call (so a live role change is honored, and an unresolvable non-default
|
|
94
|
+
// user fails closed); the startup snapshot below is only for `visibleTo` listing.
|
|
95
|
+
(0, registryTools_ts_1.ensureOperationsToolsRegistered)();
|
|
96
|
+
const agentIdentity = () => resolveAgentIdentity(opts.server, liveConfig.user);
|
|
97
|
+
let registryTools = await composeRegistryToolsForListing(agentIdentity);
|
|
98
|
+
// Operator-only V8 inspector tools. Debug config is read once here — enabling threads_debug opens the
|
|
99
|
+
// worker inspector ports at thread boot, so it can't be toggled without a restart anyway. Worker
|
|
100
|
+
// count is a live closure over the pool, so attaches range-check against the current worker set.
|
|
101
|
+
const inspectorTools = (0, inspectorTool_ts_1.buildInspectorTools)({
|
|
102
|
+
debugEnabled: env.get(hdbTerms_ts_1.CONFIG_PARAMS.THREADS_DEBUG) !== false,
|
|
103
|
+
startingPort: env.get(hdbTerms_ts_1.CONFIG_PARAMS.THREADS_DEBUG_STARTINGPORT) ?? undefined,
|
|
104
|
+
host: env.get(hdbTerms_ts_1.CONFIG_PARAMS.THREADS_DEBUG_HOST) ?? '127.0.0.1',
|
|
105
|
+
getWorkerCount: () => manageThreads_js_1.workers.length,
|
|
54
106
|
});
|
|
107
|
+
// Harper best-practices skill (@harperfast/skills): the SKILL.md overview goes in the system prompt;
|
|
108
|
+
// the `harper_best_practice` tool serves the detailed rules on demand. Both degrade to nothing if the
|
|
109
|
+
// package isn't resolvable, so the agent still runs without it.
|
|
110
|
+
const bestPracticesOverview = (0, bestPractices_ts_1.loadBestPracticesOverview)();
|
|
111
|
+
const bestPracticeTool = (0, bestPractices_ts_1.buildBestPracticeTool)();
|
|
112
|
+
const extraTools = bestPracticeTool ? [bestPracticeTool] : [];
|
|
113
|
+
// The grounding + best-practices portion of the system prompt is static for the component's
|
|
114
|
+
// lifetime (scopes don't change), so build it once here; only the operator's per-run
|
|
115
|
+
// `systemPromptAppend` is folded on at run time in `startRun`.
|
|
116
|
+
const staticSystemPrompt = buildStaticSystemPrompt(scopes, bestPracticesOverview);
|
|
117
|
+
function compose() {
|
|
118
|
+
return (0, toolset_ts_1.composeToolset)({
|
|
119
|
+
allowDestructive: liveConfig.allowDestructive,
|
|
120
|
+
onFollowup: handleFollowup,
|
|
121
|
+
inspectorTools,
|
|
122
|
+
registryTools,
|
|
123
|
+
extraTools,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
let composed = compose();
|
|
127
|
+
// Build the listing snapshot best-effort: if the configured user can't be resolved (and isn't the
|
|
128
|
+
// default bootstrap user), `agentIdentity` fails closed — the agent then runs with only its
|
|
129
|
+
// operator-only tools until the operator fixes `agent.user`. Never falls back to an escalated list.
|
|
130
|
+
async function composeRegistryToolsForListing(resolveIdentity) {
|
|
131
|
+
try {
|
|
132
|
+
const listingUser = await resolveIdentity();
|
|
133
|
+
return (0, registryTools_ts_1.composeRegistryTools)(listingUser, resolveIdentity);
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
log.error?.(`Registry tools disabled — agent.user='${liveConfig.user}' could not be resolved: ${err instanceof Error ? err.message : String(err)}`);
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
}
|
|
55
140
|
// Only warn when the operator explicitly configured `maxCostUsd`. Logging on the default
|
|
56
141
|
// every boot would flood the log without telling anyone anything actionable.
|
|
57
142
|
if (opts.maxCostUsd !== undefined) {
|
|
@@ -88,6 +173,7 @@ async function startOnMainThread(opts) {
|
|
|
88
173
|
autoApprove: liveConfig.autoApprove,
|
|
89
174
|
signal: controller.signal,
|
|
90
175
|
generateOpts: { model: liveConfig.model },
|
|
176
|
+
systemPrompt: composeSystemPrompt(staticSystemPrompt, liveConfig.systemPromptAppend),
|
|
91
177
|
})
|
|
92
178
|
.catch((err) => log.error?.(`Agent run failed for ${sessionId}: ${err?.message ?? err}`))
|
|
93
179
|
.finally(() => {
|
|
@@ -116,10 +202,7 @@ async function startOnMainThread(opts) {
|
|
|
116
202
|
const previousAllowDestructive = liveConfig.allowDestructive;
|
|
117
203
|
liveConfig = { ...liveConfig, ...patch };
|
|
118
204
|
if (liveConfig.allowDestructive !== previousAllowDestructive) {
|
|
119
|
-
composed = (
|
|
120
|
-
allowDestructive: liveConfig.allowDestructive,
|
|
121
|
-
onFollowup: handleFollowup,
|
|
122
|
-
});
|
|
205
|
+
composed = compose();
|
|
123
206
|
}
|
|
124
207
|
// NOTE: an already in-flight run captured its toolset (and autoApprove) at start, so flipping
|
|
125
208
|
// allowDestructive here only affects subsequent runs — the live loop finishes on its existing
|
|
@@ -136,8 +219,86 @@ async function startOnMainThread(opts) {
|
|
|
136
219
|
});
|
|
137
220
|
for (const op of operations)
|
|
138
221
|
opts.server.registerOperation(op);
|
|
222
|
+
// Expose the agent over MCP: register curated agent tools into the registry AFTER the ops exist.
|
|
223
|
+
// (The generic operations-profile walk ran before this, so allow-listing the agent ops wouldn't
|
|
224
|
+
// surface them — see mcpTools.ts.) They only reach clients when the MCP surface is enabled.
|
|
225
|
+
(0, mcpTools_ts_1.registerAgentMcpTools)(operations);
|
|
139
226
|
log.info?.(`Agent component initialized with ${composed.tools.length} tools`);
|
|
140
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* Grounding prompt so the agent knows what it is, where its files live, and how a Harper app is
|
|
230
|
+
* shaped. The filesystem tools take a `root` scope enum, so we describe the scopes rather than
|
|
231
|
+
* spelling out path-prefixing rules.
|
|
232
|
+
*
|
|
233
|
+
* We deliberately do NOT enumerate individual tool names here — the model already receives the full
|
|
234
|
+
* tool schema from the SDK, and duplicating names in the prompt drifts as tools are added/removed and
|
|
235
|
+
* invites hallucinated calls. This describes the tool *surface* at a category level only.
|
|
236
|
+
*
|
|
237
|
+
* The built-in grounding and best-practices overview are static for the component's lifetime, so the
|
|
238
|
+
* caller precomputes them once (`buildStaticSystemPrompt`) and only the operator
|
|
239
|
+
* `agent.systemPromptAppend` — which can change via `set_agent_config` without a restart — is folded
|
|
240
|
+
* in per run by `composeSystemPrompt`.
|
|
241
|
+
*/
|
|
242
|
+
function buildStaticSystemPrompt(scopes, bestPracticesOverview) {
|
|
243
|
+
const parts = [
|
|
244
|
+
'You are the built-in Harper agent, running on the main thread inside a live Harper server.',
|
|
245
|
+
'You operate this instance for an operator through the tools provided to you: Harper database/cluster operations, scoped filesystem tools, HTTP fetch against this server, followup scheduling, and (when available) V8 inspector tools for debugging worker threads plus a Harper best-practices lookup. Consult the provided tool schemas for the exact set and their parameters.',
|
|
246
|
+
'',
|
|
247
|
+
'Filesystem scopes (the fs tools take a `root` naming one of these; paths are relative to it):',
|
|
248
|
+
`- components — the app source directory, your only WRITE scope: ${scopes.componentsRoot}`,
|
|
249
|
+
`- logs — read-only: ${scopes.logDir}`,
|
|
250
|
+
`- config — read-only: ${scopes.configDir}`,
|
|
251
|
+
'',
|
|
252
|
+
'A Harper app is a component directory under the components dir. Define tables/resources in a schema (GraphQL `.graphql` with `@table`/`@export`, or `config.yaml` + resource files). After writing or changing component files, deploy/restart as needed for them to load, then verify by querying the REST endpoint via an HTTP fetch against this server.',
|
|
253
|
+
'Prefer the operations tools for database/cluster actions; use the filesystem tools for app source. When designing schemas or building app logic, consult the Harper best practices below and read the relevant rule via the best-practice tool. Be concise and verify your work.',
|
|
254
|
+
];
|
|
255
|
+
if (bestPracticesOverview) {
|
|
256
|
+
parts.push('', '=== Harper best practices (overview) ===', bestPracticesOverview);
|
|
257
|
+
}
|
|
258
|
+
return parts.join('\n');
|
|
259
|
+
}
|
|
260
|
+
/** Fold the operator's per-run `systemPromptAppend` onto the precomputed static base. */
|
|
261
|
+
function composeSystemPrompt(staticPrompt, append) {
|
|
262
|
+
if (typeof append === 'string' && append.trim()) {
|
|
263
|
+
return `${staticPrompt}\n\n=== Operator instructions ===\n${append.trim()}`;
|
|
264
|
+
}
|
|
265
|
+
return staticPrompt;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Resolve the identity the agent's tool calls run as. Registry tools are enforced
|
|
269
|
+
* (`hdb_user` at call time) against this user, so an operator who sets `agent.user`
|
|
270
|
+
* to a restricted role gets a narrowed surface — and a later role change is honored,
|
|
271
|
+
* because this runs per call rather than once at startup.
|
|
272
|
+
*
|
|
273
|
+
* Failure policy — fail closed, with one bounded exception:
|
|
274
|
+
* - If `agent.user` resolves to a permissioned user, use it.
|
|
275
|
+
* - If it can't be resolved AND it's the *default* `hdb_agent` bootstrap user,
|
|
276
|
+
* fall back to a super_user identity (the system user isn't provisioned yet —
|
|
277
|
+
* #626 defers creating it). This is the documented default-agent behavior.
|
|
278
|
+
* - If it can't be resolved and the operator configured a *non-default* user,
|
|
279
|
+
* throw. Silently escalating a misconfigured/transient restricted account to
|
|
280
|
+
* super_user is the vulnerability we refuse to introduce.
|
|
281
|
+
*/
|
|
282
|
+
async function resolveAgentIdentity(server, username) {
|
|
283
|
+
let resolved;
|
|
284
|
+
if (typeof server.getUser === 'function') {
|
|
285
|
+
try {
|
|
286
|
+
const user = await server.getUser(username, null, null);
|
|
287
|
+
if (user?.role?.permission)
|
|
288
|
+
resolved = user;
|
|
289
|
+
}
|
|
290
|
+
catch (err) {
|
|
291
|
+
log.warn?.(`Failed to resolve agent.user='${username}': ${err instanceof Error ? err.message : String(err)}`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (resolved)
|
|
295
|
+
return resolved;
|
|
296
|
+
if (username === DEFAULT_CONFIG.user) {
|
|
297
|
+
log.warn?.(`Default agent user '${username}' is not provisioned yet; using super_user bootstrap identity`);
|
|
298
|
+
return { username, role: { permission: { super_user: true } } };
|
|
299
|
+
}
|
|
300
|
+
throw new Error(`agent.user '${username}' could not be resolved to a permissioned user; failing closed`);
|
|
301
|
+
}
|
|
141
302
|
function resolveScopes(config, getConfigPath, getConfigFilePath) {
|
|
142
303
|
const componentsRoot = getConfigPath(hdbTerms_ts_1.CONFIG_PARAMS.COMPONENTSROOT) ?? process.cwd();
|
|
143
304
|
const logDir = getConfigPath(hdbTerms_ts_1.CONFIG_PARAMS.LOGGING_ROOT) ?? process.cwd();
|
|
@@ -166,6 +327,7 @@ function mergeConfig(opts) {
|
|
|
166
327
|
...(opts.allowDestructive !== undefined && { allowDestructive: !!opts.allowDestructive }),
|
|
167
328
|
...(opts.user !== undefined && { user: String(opts.user) }),
|
|
168
329
|
...(opts.componentsScope !== undefined && { componentsScope: String(opts.componentsScope) }),
|
|
330
|
+
...(opts.systemPromptAppend !== undefined && { systemPromptAppend: String(opts.systemPromptAppend) }),
|
|
169
331
|
};
|
|
170
332
|
}
|
|
171
333
|
/** Test-only: reset module state between specs. */
|
package/dist/agent/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../agent/agent.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../agent/agent.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDH,8CAoKC;AA0DD,oDAiBC;AAwCD,wCAEC;AAxUD,yCAAwE;AACxE,wDAAuD;AACvD,kFAAoE;AACpE,2FAA+D;AAC/D,6DAAuD;AAEvD,yEAA6D;AAC7D,6CAA8C;AAC9C,+DAA+D;AAC/D,yDAAsF;AACtF,yDAA2F;AAC3F,mDAAkD;AAClD,+CAAsD;AACtD,uCAA6D;AAC7D,6CAAyD;AAGzD,MAAM,GAAG,GAAG,0BAAY,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AAEhD,MAAM,cAAc,GAAgB;IACnC,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,KAAK;IAClB,gBAAgB,EAAE,KAAK;IACvB,IAAI,EAAE,WAAW;CACjB,CAAC;AAqBK,KAAK,UAAU,iBAAiB,CAAC,IAAe;IACtD,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACrB,GAAG,CAAC,IAAI,EAAE,CAAC,uEAAuE,CAAC,CAAC;QACpF,OAAO;IACR,CAAC;IAED,8EAA8E;IAC9E,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;IACtF,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,iBAAiB,CAAC,CAAC;IAEvE,MAAM,MAAM,GAAG,IAAI,kBAAM,EAAE,CAAC;IAC5B,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC5D,IAAI,UAAU,GAAgB,MAAM,CAAC;IAErC,mGAAmG;IACnG,iGAAiG;IACjG,kFAAkF;IAClF,IAAA,kDAA+B,GAAE,CAAC;IAClC,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/E,IAAI,aAAa,GAAG,MAAM,8BAA8B,CAAC,aAAa,CAAC,CAAC;IAExE,sGAAsG;IACtG,iGAAiG;IACjG,iGAAiG;IACjG,MAAM,cAAc,GAAG,IAAA,sCAAmB,EAAC;QAC1C,YAAY,EAAE,GAAG,CAAC,GAAG,CAAC,2BAAa,CAAC,aAAa,CAAC,KAAK,KAAK;QAC5D,YAAY,EAAG,GAAG,CAAC,GAAG,CAAC,2BAAa,CAAC,0BAA0B,CAAwB,IAAI,SAAS;QACpG,IAAI,EAAG,GAAG,CAAC,GAAG,CAAC,2BAAa,CAAC,kBAAkB,CAAwB,IAAI,WAAW;QACtF,cAAc,EAAE,GAAG,EAAE,CAAC,0BAAO,CAAC,MAAM;KACpC,CAAC,CAAC;IAEH,qGAAqG;IACrG,sGAAsG;IACtG,gEAAgE;IAChE,MAAM,qBAAqB,GAAG,IAAA,4CAAyB,GAAE,CAAC;IAC1D,MAAM,gBAAgB,GAAG,IAAA,wCAAqB,GAAE,CAAC;IACjD,MAAM,UAAU,GAAgB,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE3E,4FAA4F;IAC5F,qFAAqF;IACrF,+DAA+D;IAC/D,MAAM,kBAAkB,GAAG,uBAAuB,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAElF,SAAS,OAAO;QACf,OAAO,IAAA,2BAAc,EAAC;YACrB,gBAAgB,EAAE,UAAU,CAAC,gBAAgB;YAC7C,UAAU,EAAE,cAAc;YAC1B,cAAc;YACd,aAAa;YACb,UAAU;SACV,CAAC,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,GAAG,OAAO,EAAE,CAAC;IAEzB,kGAAkG;IAClG,4FAA4F;IAC5F,oGAAoG;IACpG,KAAK,UAAU,8BAA8B,CAAC,eAA0C;QACvF,IAAI,CAAC;YACJ,MAAM,WAAW,GAAG,MAAM,eAAe,EAAE,CAAC;YAC5C,OAAO,IAAA,uCAAoB,EAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,GAAG,CAAC,KAAK,EAAE,CACV,yCAAyC,UAAU,CAAC,IAAI,4BAA4B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACtI,CAAC;YACF,OAAO,EAAE,CAAC;QACX,CAAC;IACF,CAAC;IAED,yFAAyF;IACzF,6EAA6E;IAC7E,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACnC,GAAG,CAAC,IAAI,EAAE,CACT,oBAAoB,UAAU,CAAC,UAAU,iFAAiF,CAC1H,CAAC;IACH,CAAC;IAED,KAAK,UAAU,cAAc,CAAC,SAAiB,EAAE,MAAc;QAC9D,MAAM,OAAO,GAAG,MAAM,IAAA,uBAAU,EAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,GAAG,CAAC,IAAI,EAAE,CAAC,oCAAoC,SAAS,YAAY,CAAC,CAAC;YACtE,OAAO;QACR,CAAC;QACD,MAAM,IAAA,0BAAa,EAAC,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACzF,QAAQ,CAAC,SAAS,CAAC,CAAC;IACrB,CAAC;IAED,SAAS,YAAY;QACpB,OAAO,QAAQ,CAAC,KAAK,CAAC;IACvB,CAAC;IAED,SAAS,QAAQ,CAAC,SAAiB;QAClC,4FAA4F;QAC5F,sFAAsF;QACtF,yFAAyF;QACzF,0FAA0F;QAC1F,sFAAsF;QACtF,IAAI,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,OAAO;QAC5C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,gBAAgB,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC5C,IAAA,kBAAQ,EAAC;YACR,SAAS;YACT,MAAM;YACN,KAAK,EAAE,YAAY,EAAE;YACrB,MAAM;YACN,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,WAAW,EAAE,UAAU,CAAC,WAAW;YACnC,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,YAAY,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE;YACzC,YAAY,EAAE,mBAAmB,CAAC,kBAAkB,EAAE,UAAU,CAAC,kBAAkB,CAAC;SACpF,CAAC;aACA,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,wBAAwB,SAAS,KAAM,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;aACnG,OAAO,CAAC,GAAG,EAAE;YACb,IAAI,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,UAAU;gBAAE,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACxF,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,SAAS,CAAC,SAAiB;QACnC,yFAAyF;QACzF,2FAA2F;QAC3F,mEAAmE;QACnE,KAAK,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3D,IAAI,QAAQ,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBACtC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAC7B,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC/B,CAAC;QACF,CAAC;QACD,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QAC9B,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;QACrD,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,SAAS,SAAS,CAAC,KAA2B;QAC7C,MAAM,wBAAwB,GAAG,UAAU,CAAC,gBAAgB,CAAC;QAC7D,UAAU,GAAG,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK,EAAE,CAAC;QACzC,IAAI,UAAU,CAAC,gBAAgB,KAAK,wBAAwB,EAAE,CAAC;YAC9D,QAAQ,GAAG,OAAO,EAAE,CAAC;QACtB,CAAC;QACD,8FAA8F;QAC9F,8FAA8F;QAC9F,6FAA6F;QAC7F,gGAAgG;QAChG,wFAAwF;QACxF,OAAO,UAAU,CAAC;IACnB,CAAC;IAED,MAAM,UAAU,GAAG,IAAA,+BAAe,EAAC;QAClC,SAAS,EAAE,GAAG,EAAE,CAAC,UAAU;QAC3B,SAAS;QACT,QAAQ;QACR,SAAS;KACT,CAAC,CAAC;IACH,KAAK,MAAM,EAAE,IAAI,UAAU;QAAE,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAE/D,iGAAiG;IACjG,gGAAgG;IAChG,4FAA4F;IAC5F,IAAA,mCAAqB,EAAC,UAAU,CAAC,CAAC;IAElC,GAAG,CAAC,IAAI,EAAE,CAAC,oCAAoC,QAAQ,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAC;AAC/E,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,uBAAuB,CAAC,MAAmB,EAAE,qBAA8B;IACnF,MAAM,KAAK,GAAG;QACb,4FAA4F;QAC5F,oXAAoX;QACpX,EAAE;QACF,+FAA+F;QAC/F,mEAAmE,MAAM,CAAC,cAAc,EAAE;QAC1F,uBAAuB,MAAM,CAAC,MAAM,EAAE;QACtC,yBAAyB,MAAM,CAAC,SAAS,EAAE;QAC3C,EAAE;QACF,6VAA6V;QAC7V,kRAAkR;KAClR,CAAC;IACF,IAAI,qBAAqB,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,0CAA0C,EAAE,qBAAqB,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,yFAAyF;AACzF,SAAS,mBAAmB,CAAC,YAAoB,EAAE,MAAe;IACjE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACjD,OAAO,GAAG,YAAY,sCAAsC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;IAC7E,CAAC;IACD,OAAO,YAAY,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACI,KAAK,UAAU,oBAAoB,CAAC,MAA2B,EAAE,QAAgB;IACvF,IAAI,QAAgC,CAAC;IACrC,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAC1C,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YACxD,IAAI,IAAI,EAAE,IAAI,EAAE,UAAU;gBAAE,QAAQ,GAAG,IAAI,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,GAAG,CAAC,IAAI,EAAE,CAAC,iCAAiC,QAAQ,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/G,CAAC;IACF,CAAC;IACD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,IAAI,QAAQ,KAAK,cAAc,CAAC,IAAI,EAAE,CAAC;QACtC,GAAG,CAAC,IAAI,EAAE,CAAC,uBAAuB,QAAQ,+DAA+D,CAAC,CAAC;QAC3G,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IACjE,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,eAAe,QAAQ,gEAAgE,CAAC,CAAC;AAC1G,CAAC;AAED,SAAS,aAAa,CACrB,MAAmB,EACnB,aAAoD,EACpD,iBAAgC;IAEhC,MAAM,cAAc,GAAG,aAAa,CAAC,2BAAa,CAAC,cAAc,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACpF,MAAM,MAAM,GAAG,aAAa,CAAC,2BAAa,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1E,MAAM,QAAQ,GAAG,aAAa,CAAC,2BAAa,CAAC,QAAQ,CAAC,IAAI,cAAc,CAAC;IACzE,MAAM,UAAU,GAAG,iBAAiB,EAAE,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,IAAA,mBAAO,EAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IACnE,2FAA2F;IAC3F,oGAAoG;IACpG,oEAAoE;IACpE,MAAM,gBAAgB,GAAG,MAAM,CAAC,eAAe;QAC9C,CAAC,CAAC,IAAA,sBAAU,EAAC,MAAM,CAAC,eAAe,CAAC;YACnC,CAAC,CAAC,MAAM,CAAC,eAAe;YACxB,CAAC,CAAC,IAAA,mBAAW,EAAC,QAAQ,EAAE,MAAM,CAAC,eAAe,CAAC;QAChD,CAAC,CAAC,cAAc,CAAC;IAClB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAChE,CAAC;AAED,SAAS,WAAW,CAAC,IAAe;IACnC,OAAO;QACN,GAAG,cAAc;QACjB,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAC9D,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7E,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAC1E,GAAG,CAAC,IAAI,CAAC,gBAAgB,KAAK,SAAS,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACzF,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,SAAS,IAAI,EAAE,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;QAC5F,GAAG,CAAC,IAAI,CAAC,kBAAkB,KAAK,SAAS,IAAI,EAAE,kBAAkB,EAAE,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;KACrG,CAAC;AACH,CAAC;AAED,mDAAmD;AACnD,SAAgB,cAAc;IAC7B,IAAA,gCAAsB,GAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harper best-practices knowledge for the built-in agent (#626).
|
|
3
|
+
*
|
|
4
|
+
* Sources the `harper-best-practices` skill from the `@harperfast/skills`
|
|
5
|
+
* package (versioned with the release, no drift). The package exposes the skill
|
|
6
|
+
* content directly as module exports — `skillSummary` (the SKILL.md overview),
|
|
7
|
+
* `ruleNames` (the rule index), and `rules` (name → markdown body) — so we read
|
|
8
|
+
* from those rather than groveling around the installed package on disk.
|
|
9
|
+
*
|
|
10
|
+
* Progressive disclosure, mirroring how the skill is meant to be used:
|
|
11
|
+
* - the SKILL.md overview (rule index + when-to-use) is injected into the
|
|
12
|
+
* agent's system prompt so it always knows *which* practices exist;
|
|
13
|
+
* - the detailed rule bodies are pulled on demand via the
|
|
14
|
+
* `harper_best_practice` tool, so the agent only spends context on the
|
|
15
|
+
* guidance relevant to the task instead of carrying all ~20 rules.
|
|
16
|
+
*/
|
|
17
|
+
import type { AgentTool } from './types.ts';
|
|
18
|
+
/** The SKILL.md overview (rule index + guidance), for injection into the system prompt. Undefined if unavailable. */
|
|
19
|
+
export declare function loadBestPracticesOverview(): string | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* A tool that lists the best-practice rules (no arg) or returns one rule's full body (`rule` arg).
|
|
22
|
+
* Returns undefined when the skill package ships no rules, so the caller simply omits it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildBestPracticeTool(): AgentTool | undefined;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Harper best-practices knowledge for the built-in agent (#626).
|
|
4
|
+
*
|
|
5
|
+
* Sources the `harper-best-practices` skill from the `@harperfast/skills`
|
|
6
|
+
* package (versioned with the release, no drift). The package exposes the skill
|
|
7
|
+
* content directly as module exports — `skillSummary` (the SKILL.md overview),
|
|
8
|
+
* `ruleNames` (the rule index), and `rules` (name → markdown body) — so we read
|
|
9
|
+
* from those rather than groveling around the installed package on disk.
|
|
10
|
+
*
|
|
11
|
+
* Progressive disclosure, mirroring how the skill is meant to be used:
|
|
12
|
+
* - the SKILL.md overview (rule index + when-to-use) is injected into the
|
|
13
|
+
* agent's system prompt so it always knows *which* practices exist;
|
|
14
|
+
* - the detailed rule bodies are pulled on demand via the
|
|
15
|
+
* `harper_best_practice` tool, so the agent only spends context on the
|
|
16
|
+
* guidance relevant to the task instead of carrying all ~20 rules.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.loadBestPracticesOverview = loadBestPracticesOverview;
|
|
20
|
+
exports.buildBestPracticeTool = buildBestPracticeTool;
|
|
21
|
+
const skills_1 = require("@harperfast/skills");
|
|
22
|
+
/** The SKILL.md overview (rule index + guidance), for injection into the system prompt. Undefined if unavailable. */
|
|
23
|
+
function loadBestPracticesOverview() {
|
|
24
|
+
return skills_1.skillSummary || undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A tool that lists the best-practice rules (no arg) or returns one rule's full body (`rule` arg).
|
|
28
|
+
* Returns undefined when the skill package ships no rules, so the caller simply omits it.
|
|
29
|
+
*/
|
|
30
|
+
function buildBestPracticeTool() {
|
|
31
|
+
if (!skills_1.ruleNames?.length)
|
|
32
|
+
return undefined;
|
|
33
|
+
return {
|
|
34
|
+
def: {
|
|
35
|
+
name: 'harper_best_practice',
|
|
36
|
+
description: 'Read a Harper best-practices rule for detailed guidance and code examples — schema design, relationships, automatic/REST APIs, authentication, custom resources, caching, vector indexing, TypeScript type-stripping, deployment, logging, and more. Call with no `rule` to list the available rule names; then call again with a `rule` to read it. Consult these before designing schemas or building app logic.',
|
|
37
|
+
parameters: {
|
|
38
|
+
type: 'object',
|
|
39
|
+
properties: {
|
|
40
|
+
rule: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
description: 'Rule name without extension, e.g. "adding-tables-with-schemas". Omit to list all rules.',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
handler: async (args) => {
|
|
48
|
+
const rule = args?.rule ? String(args.rule).trim() : '';
|
|
49
|
+
if (!rule)
|
|
50
|
+
return { rules: [...skills_1.ruleNames] };
|
|
51
|
+
// A plain map lookup — an unknown or malformed name simply misses, so there's no
|
|
52
|
+
// path-traversal surface to guard against.
|
|
53
|
+
const content = skills_1.rules[rule];
|
|
54
|
+
if (content == null)
|
|
55
|
+
throw new Error(`No such best-practice rule: '${rule}'. Call with no rule to list available rules.`);
|
|
56
|
+
return { rule, content };
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=bestPractices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bestPractices.js","sourceRoot":"","sources":["../../agent/bestPractices.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;AAMH,8DAEC;AAMD,sDA4BC;AAxCD,+CAAoE;AAGpE,qHAAqH;AACrH,SAAgB,yBAAyB;IACxC,OAAO,qBAAY,IAAI,SAAS,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,SAAgB,qBAAqB;IACpC,IAAI,CAAC,kBAAS,EAAE,MAAM;QAAE,OAAO,SAAS,CAAC;IACzC,OAAO;QACN,GAAG,EAAE;YACJ,IAAI,EAAE,sBAAsB;YAC5B,WAAW,EACV,oZAAoZ;YACrZ,UAAU,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACX,IAAI,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE,yFAAyF;qBACtG;iBACD;aACD;SACD;QACD,OAAO,EAAE,KAAK,EAAE,IAAS,EAAE,EAAE;YAC5B,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC,IAAI;gBAAE,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,kBAAS,CAAC,EAAE,CAAC;YAC5C,iFAAiF;YACjF,2CAA2C;YAC3C,MAAM,OAAO,GAAI,cAAgC,CAAC,IAAI,CAAC,CAAC;YACxD,IAAI,OAAO,IAAI,IAAI;gBAClB,MAAM,IAAI,KAAK,CAAC,gCAAgC,IAAI,+CAA+C,CAAC,CAAC;YACtG,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC1B,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expose the built-in agent over MCP (#626).
|
|
3
|
+
*
|
|
4
|
+
* The generic MCP operations profile (#617) can surface these ops too, but only
|
|
5
|
+
* when an operator opts them into `mcp.operations.allow` and with generic,
|
|
6
|
+
* schema-inferred descriptions. We register a *curated* agent tool set directly
|
|
7
|
+
* into the registry instead: exposed by default (no allow-list entry needed),
|
|
8
|
+
* with hand-written descriptions and annotations tuned for driving the agent.
|
|
9
|
+
*
|
|
10
|
+
* Each tool dispatches through the SAME path the generic operations profile uses
|
|
11
|
+
* (`makeOperationToolHandler` → `chooseOperation` + `processLocalTransaction`), so
|
|
12
|
+
* Harper's `verifyPerms` runs at call time and enforces the `requiresSuperUser: true`
|
|
13
|
+
* declared on each agent op — plus any scoped `operations: ['agent_*']` delegation
|
|
14
|
+
* role. Listing mirrors that boundary via `canRoleInvokeOperation`. A direct
|
|
15
|
+
* `op.execute(body)` call is NOT used: it would bypass `verifyPerms` entirely and
|
|
16
|
+
* let any authenticated MCP user drive the super_user agent.
|
|
17
|
+
*/
|
|
18
|
+
import type { OperationDefinition } from '../server/serverHelpers/serverUtilities.ts';
|
|
19
|
+
/**
|
|
20
|
+
* Register the curated agent tools into the MCP registry (operations profile). Call after the agent
|
|
21
|
+
* operations are registered. Safe to call whether or not the MCP HTTP surface is enabled — the tools
|
|
22
|
+
* simply sit in the registry until an MCP client lists them.
|
|
23
|
+
*/
|
|
24
|
+
export declare function registerAgentMcpTools(operations: OperationDefinition[]): void;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Expose the built-in agent over MCP (#626).
|
|
4
|
+
*
|
|
5
|
+
* The generic MCP operations profile (#617) can surface these ops too, but only
|
|
6
|
+
* when an operator opts them into `mcp.operations.allow` and with generic,
|
|
7
|
+
* schema-inferred descriptions. We register a *curated* agent tool set directly
|
|
8
|
+
* into the registry instead: exposed by default (no allow-list entry needed),
|
|
9
|
+
* with hand-written descriptions and annotations tuned for driving the agent.
|
|
10
|
+
*
|
|
11
|
+
* Each tool dispatches through the SAME path the generic operations profile uses
|
|
12
|
+
* (`makeOperationToolHandler` → `chooseOperation` + `processLocalTransaction`), so
|
|
13
|
+
* Harper's `verifyPerms` runs at call time and enforces the `requiresSuperUser: true`
|
|
14
|
+
* declared on each agent op — plus any scoped `operations: ['agent_*']` delegation
|
|
15
|
+
* role. Listing mirrors that boundary via `canRoleInvokeOperation`. A direct
|
|
16
|
+
* `op.execute(body)` call is NOT used: it would bypass `verifyPerms` entirely and
|
|
17
|
+
* let any authenticated MCP user drive the super_user agent.
|
|
18
|
+
*/
|
|
19
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
20
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.registerAgentMcpTools = registerAgentMcpTools;
|
|
24
|
+
const toolRegistry_ts_1 = require("../components/mcp/toolRegistry.js");
|
|
25
|
+
const operations_ts_1 = require("../components/mcp/tools/operations.js");
|
|
26
|
+
const harper_logger_ts_1 = __importDefault(require("../utility/logging/harper_logger.js"));
|
|
27
|
+
const log = harper_logger_ts_1.default.loggerWithTag('agent');
|
|
28
|
+
// Curated client-facing surface for driving the agent. `set_agent_config` is intentionally excluded
|
|
29
|
+
// — it's an operator/config action, not something an MCP client should reach.
|
|
30
|
+
const AGENT_MCP_TOOLS = {
|
|
31
|
+
agent_prompt: {
|
|
32
|
+
description: 'Send a prompt to the built-in Harper agent. Starts a new session, or continues one when session_id is given. Returns { session_id, status }; poll get_agent_session for the transcript and result.',
|
|
33
|
+
inputSchema: {
|
|
34
|
+
type: 'object',
|
|
35
|
+
properties: {
|
|
36
|
+
message: { type: 'string', description: 'The instruction/prompt for the agent.' },
|
|
37
|
+
session_id: { type: 'string', description: 'Optional existing session id to continue the conversation.' },
|
|
38
|
+
},
|
|
39
|
+
required: ['message'],
|
|
40
|
+
},
|
|
41
|
+
destructive: true, // the agent may take actions in response
|
|
42
|
+
},
|
|
43
|
+
get_agent_session: {
|
|
44
|
+
description: 'Read a built-in-agent session: its status, full transcript (messages, tool calls and results), and any pending approvals.',
|
|
45
|
+
inputSchema: {
|
|
46
|
+
type: 'object',
|
|
47
|
+
properties: { session_id: { type: 'string' } },
|
|
48
|
+
required: ['session_id'],
|
|
49
|
+
},
|
|
50
|
+
readOnly: true,
|
|
51
|
+
},
|
|
52
|
+
list_agent_sessions: {
|
|
53
|
+
description: 'List built-in-agent sessions, most recent first.',
|
|
54
|
+
inputSchema: {
|
|
55
|
+
type: 'object',
|
|
56
|
+
properties: { limit: { type: 'integer', minimum: 1, description: 'Max sessions to return (default 100).' } },
|
|
57
|
+
},
|
|
58
|
+
readOnly: true,
|
|
59
|
+
},
|
|
60
|
+
approve_agent_action: {
|
|
61
|
+
description: 'Approve or deny a pending agent tool call (when autoApprove is off), then resume the run. Get the approval_id from get_agent_session.pendingApprovals.',
|
|
62
|
+
inputSchema: {
|
|
63
|
+
type: 'object',
|
|
64
|
+
properties: {
|
|
65
|
+
session_id: { type: 'string' },
|
|
66
|
+
approval_id: { type: 'string' },
|
|
67
|
+
approved: { type: 'boolean', description: 'true to approve (default), false to deny.' },
|
|
68
|
+
},
|
|
69
|
+
required: ['session_id', 'approval_id'],
|
|
70
|
+
},
|
|
71
|
+
destructive: true,
|
|
72
|
+
},
|
|
73
|
+
cancel_agent_run: {
|
|
74
|
+
description: 'Cancel an in-progress agent run for a session.',
|
|
75
|
+
inputSchema: {
|
|
76
|
+
type: 'object',
|
|
77
|
+
properties: { session_id: { type: 'string' } },
|
|
78
|
+
required: ['session_id'],
|
|
79
|
+
},
|
|
80
|
+
destructive: true,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Register the curated agent tools into the MCP registry (operations profile). Call after the agent
|
|
85
|
+
* operations are registered. Safe to call whether or not the MCP HTTP surface is enabled — the tools
|
|
86
|
+
* simply sit in the registry until an MCP client lists them.
|
|
87
|
+
*/
|
|
88
|
+
function registerAgentMcpTools(operations) {
|
|
89
|
+
const registered = new Set(operations.map((op) => op.name));
|
|
90
|
+
let count = 0;
|
|
91
|
+
for (const [name, meta] of Object.entries(AGENT_MCP_TOOLS)) {
|
|
92
|
+
if (!registered.has(name))
|
|
93
|
+
continue; // op not registered (shouldn't happen) — skip rather than expose a dead tool
|
|
94
|
+
const annotations = meta.destructive ? { destructiveHint: true } : meta.readOnly ? { readOnlyHint: true } : {};
|
|
95
|
+
(0, toolRegistry_ts_1.addTool)({
|
|
96
|
+
name,
|
|
97
|
+
description: meta.description,
|
|
98
|
+
inputSchema: meta.inputSchema,
|
|
99
|
+
profile: 'operations',
|
|
100
|
+
...(Object.keys(annotations).length > 0 ? { annotations } : {}),
|
|
101
|
+
// List only for users the op's role-level policy would let call it (super_user, or a
|
|
102
|
+
// scoped `operations: ['agent_*']` delegation role). verifyPerms enforces the same at
|
|
103
|
+
// call time inside makeOperationToolHandler — this predicate keeps hidden tools out of
|
|
104
|
+
// the listing, not out of reach.
|
|
105
|
+
visibleTo: (user) => (0, toolRegistry_ts_1.canRoleInvokeOperation)(user, name),
|
|
106
|
+
// Route through the standard operation dispatch (chooseOperation + processLocalTransaction),
|
|
107
|
+
// so verifyPerms runs and the op's requiresSuperUser gate is actually enforced — a direct
|
|
108
|
+
// op.execute() would skip it. Same handler the generic operations profile uses.
|
|
109
|
+
handler: (0, operations_ts_1.makeOperationToolHandler)(name),
|
|
110
|
+
});
|
|
111
|
+
count++;
|
|
112
|
+
}
|
|
113
|
+
log.info?.(`Agent MCP tools registered: ${count}`);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=mcpTools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpTools.js","sourceRoot":"","sources":["../../agent/mcpTools.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/operations.js
CHANGED
|
@@ -123,7 +123,16 @@ async function approveAgentAction(op, deps) {
|
|
|
123
123
|
}
|
|
124
124
|
async function setAgentConfig(op, deps) {
|
|
125
125
|
const patch = {};
|
|
126
|
-
for (const key of [
|
|
126
|
+
for (const key of [
|
|
127
|
+
'enabled',
|
|
128
|
+
'provider',
|
|
129
|
+
'model',
|
|
130
|
+
'maxTurns',
|
|
131
|
+
'maxCostUsd',
|
|
132
|
+
'autoApprove',
|
|
133
|
+
'allowDestructive',
|
|
134
|
+
'systemPromptAppend',
|
|
135
|
+
]) {
|
|
127
136
|
if (op?.[key] !== undefined)
|
|
128
137
|
patch[key] = op[key];
|
|
129
138
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../../agent/operations.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../../agent/operations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry tool composition for the built-in agent (#626).
|
|
3
|
+
*
|
|
4
|
+
* Folds the unified MCP tool registry (#615) — specifically the Operations
|
|
5
|
+
* profile (#617) — into the agent's toolset. The agent consumes the *same*
|
|
6
|
+
* registry the MCP HTTP server exposes, RBAC-filtered for its configured user,
|
|
7
|
+
* so operators get one tool surface with one permission model.
|
|
8
|
+
*
|
|
9
|
+
* Two-step, mirroring the registry's own security model:
|
|
10
|
+
* 1. `visibleTo(agentUser)` narrows *listing* — the LLM only sees tools it is
|
|
11
|
+
* likely allowed to call. This is NOT a security boundary.
|
|
12
|
+
* 2. Real enforcement runs in the operation handler at call time: each call
|
|
13
|
+
* dispatches through Harper's operations runtime with `hdb_user` set to the
|
|
14
|
+
* agent's configured identity, so `verifyPerms` gates it regardless of what
|
|
15
|
+
* the LLM was shown.
|
|
16
|
+
*
|
|
17
|
+
* The Application profile (#618) is intentionally out of scope here; it can fold
|
|
18
|
+
* in the same way once per-Resource tool generation is wired for the agent.
|
|
19
|
+
*/
|
|
20
|
+
import { type AuthedUser } from '../components/mcp/toolRegistry.ts';
|
|
21
|
+
import type { AgentTool } from './types.ts';
|
|
22
|
+
/**
|
|
23
|
+
* Populate the Operations profile on the main thread. Idempotent: guarded so a
|
|
24
|
+
* second call (e.g. an `agent.enabled` flip via `set_agent_config`) is a no-op
|
|
25
|
+
* rather than re-walking `OPERATION_FUNCTION_MAP` and re-logging. The registry's
|
|
26
|
+
* `addTool` is `Map.set`-backed, so this stays correct whether or not the
|
|
27
|
+
* operator also enabled the `mcp:` HTTP surface.
|
|
28
|
+
*/
|
|
29
|
+
export declare function ensureOperationsToolsRegistered(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Adapt every Operations-profile registry tool into the agent's {@link AgentTool}
|
|
32
|
+
* shape. Call {@link ensureOperationsToolsRegistered} first so the profile is
|
|
33
|
+
* populated.
|
|
34
|
+
*
|
|
35
|
+
* Two identities, deliberately split:
|
|
36
|
+
* - `listingUser` filters `visibleTo` at compose time — which tools the LLM is
|
|
37
|
+
* *shown*. Listing is not a security boundary, so a startup snapshot is fine.
|
|
38
|
+
* - `resolveIdentity()` is called *per tool call* to set `hdb_user`, so the
|
|
39
|
+
* operation is enforced against the agent user's *current* role. This is what
|
|
40
|
+
* honors a role revocation/change without a restart — the enforcement identity
|
|
41
|
+
* is never cached in the handler closure.
|
|
42
|
+
*/
|
|
43
|
+
export declare function composeRegistryTools(listingUser: AuthedUser, resolveIdentity: () => Promise<AuthedUser>): AgentTool[];
|
|
44
|
+
/** Test-only: reset the one-time registration guard between specs. */
|
|
45
|
+
export declare function _resetRegistryToolsForTests(): void;
|