@schlenkr/ragents 0.1.7 → 0.1.9
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/apps/server/src/config-definition.ts +24 -2
- package/apps/server/src/config.ts +0 -6
- package/apps/server/src/host-api.json +3 -10
- package/apps/server/src/host-api.ts +6 -7
- package/apps/server/src/plugin-build/build.ts +28 -5
- package/apps/server/src/plugin-build/plugin-description.ts +1 -1
- package/apps/server/src/plugin-build/typecheck.ts +2 -2
- package/apps/server/src/plugin-support/language-server/plugin.ts +8 -7
- package/apps/server/src/plugin-support/language-server/tools.ts +7 -6
- package/apps/server/src/plugin-support/model-aliases.ts +55 -25
- package/apps/server/src/plugin-support/plugin-folder.ts +2 -1
- package/apps/server/src/plugin-support/product-relay.ts +10 -2
- package/apps/server/src/plugin-support/workspace-sandbox-host.ts +18 -9
- package/apps/server/src/profile/bundle-manifest.ts +7 -3
- package/apps/server/src/profile/compose.ts +6 -0
- package/apps/server/src/profile/plugin-discovery.ts +6 -1
- package/apps/server/src/profile/provisioning.ts +6 -5
- package/apps/server/src/ragents/engine.ts +18 -12
- package/apps/server/src/ragents/host-services.ts +4 -0
- package/apps/server/src/ragents/session.ts +1 -1
- package/apps/server/src/server.ts +1 -0
- package/apps/server/tsconfig.json +2 -0
- package/apps/web/dist/assets/{highlighted-body-KPVGNVTW-CFhTJEmH.js → highlighted-body-KPVGNVTW-xXXhTDbh.js} +1 -1
- package/apps/web/dist/assets/{main-DlzW4t4c.js → main-C7JeZFjs.js} +1 -1
- package/apps/web/dist/assets/{mermaid-HWGCJPDP-kxkB991i.js → mermaid-HWGCJPDP-DfsU5ofC.js} +2 -2
- package/apps/web/dist/assets/{runPanel-BJEFQ__w.js → runPanel-ZT6TPDLM.js} +1 -1
- package/apps/web/dist/help/guide-clients.html +14 -6
- package/apps/web/dist/help/guide-clients.md +14 -6
- package/apps/web/dist/help/guide-distributed.html +12 -4
- package/apps/web/dist/help/guide-distributed.md +12 -4
- package/apps/web/dist/help/guide-getting-started.html +12 -8
- package/apps/web/dist/help/guide-getting-started.md +12 -8
- package/apps/web/dist/help/guide-plugins.html +6 -2
- package/apps/web/dist/help/guide-plugins.md +6 -2
- package/apps/web/dist/help/guide-runtime.html +2 -1
- package/apps/web/dist/help/guide-runtime.md +2 -1
- package/apps/web/dist/help/index.html +3328 -1135
- package/apps/web/dist/host-web.json +4 -4
- package/apps/web/dist/index.html +2 -2
- package/apps/web/dist/run-panel.html +2 -2
- package/apps/web/src/StartTiles.tsx +1 -1
- package/bundles/ragents.activity/ragents-bundle.json +3 -3
- package/bundles/ragents.actor-programs/ragents-bundle.json +3 -3
- package/bundles/ragents.ask/ragents-bundle.json +4 -4
- package/bundles/ragents.ask/server/index.js +42 -11
- package/bundles/ragents.ask/server/index.js.map +3 -3
- package/bundles/ragents.ask/web/chunks/chunk-WFN4374U.js +2 -0
- package/bundles/ragents.ask/web/chunks/chunk-WFN4374U.js.map +7 -0
- package/bundles/ragents.ask/web/classes.json +1 -1
- package/bundles/ragents.ask/web/exports/ask-payload.js +1 -1
- package/bundles/ragents.ask/web/index.js +1 -1
- package/bundles/ragents.ask/web/index.js.map +3 -3
- package/bundles/ragents.browser/executor/index.mjs +357 -0
- package/bundles/ragents.browser/executor/index.mjs.map +7 -0
- package/bundles/ragents.browser/ragents-bundle.json +5 -8
- package/bundles/ragents.browser/server/chunks/{chunk-2GKLLCBE.js → chunk-CWLX4VA5.js} +1 -1
- package/bundles/ragents.browser/server/chunks/chunk-CWLX4VA5.js.map +7 -0
- package/bundles/ragents.browser/server/exports/server/contract.js +1 -1
- package/bundles/ragents.browser/server/index.js +20 -9
- package/bundles/ragents.browser/server/index.js.map +4 -4
- package/bundles/ragents.documents/ragents-bundle.json +3 -3
- package/bundles/ragents.lsp-fsharp/executor/index.mjs +68 -0
- package/bundles/ragents.lsp-fsharp/executor/index.mjs.map +7 -0
- package/bundles/ragents.lsp-fsharp/ragents-bundle.json +5 -9
- package/bundles/ragents.lsp-fsharp/server/index.js +21 -6
- package/bundles/ragents.lsp-fsharp/server/index.js.map +4 -4
- package/bundles/ragents.lsp-roslyn/executor/index.mjs +68 -0
- package/bundles/ragents.lsp-roslyn/executor/index.mjs.map +7 -0
- package/bundles/ragents.lsp-roslyn/ragents-bundle.json +6 -8
- package/bundles/ragents.lsp-roslyn/server/index.js +54 -15
- package/bundles/ragents.lsp-roslyn/server/index.js.map +4 -4
- package/bundles/ragents.lsp-typescript/executor/index.mjs +49 -0
- package/bundles/ragents.lsp-typescript/executor/index.mjs.map +7 -0
- package/bundles/ragents.lsp-typescript/ragents-bundle.json +5 -7
- package/bundles/ragents.lsp-typescript/server/index.js +22 -2
- package/bundles/ragents.lsp-typescript/server/index.js.map +3 -3
- package/bundles/ragents.model-relay/ragents-bundle.json +4 -4
- package/bundles/ragents.model-relay/server/index.js +3 -2
- package/bundles/ragents.model-relay/server/index.js.map +2 -2
- package/bundles/ragents.orchestration/ragents-bundle.json +3 -3
- package/bundles/ragents.overseer/ragents-bundle.json +3 -3
- package/bundles/ragents.processes/ragents-bundle.json +3 -3
- package/bundles/ragents.product/ragents-bundle.json +3 -3
- package/bundles/ragents.profile-distribution/ragents-bundle.json +4 -4
- package/bundles/ragents.profile-distribution/server/index.js +1 -1
- package/bundles/ragents.profile-distribution/server/index.js.map +2 -2
- package/bundles/ragents.reference/ragents-bundle.json +3 -3
- package/bundles/ragents.todo/ragents-bundle.json +3 -3
- package/bundles/ragents.transcript/ragents-bundle.json +3 -3
- package/bundles/ragents.watch/ragents-bundle.json +3 -3
- package/bundles/ragents.workspace/ragents-bundle.json +11 -5
- package/bundles/ragents.workspace/server/index.js +101 -28
- package/bundles/ragents.workspace/server/index.js.map +3 -3
- package/bundles/ragents.workspace/web/classes.json +1 -1
- package/bundles/ragents.workspace/web/index.js +1 -1
- package/bundles/ragents.workspace/web/index.js.map +3 -3
- package/package.json +2 -2
- package/packages/agent/dist/core/agent-settings.d.ts +1 -7
- package/packages/agent/dist/core/compaction/compaction.d.ts +17 -13
- package/packages/agent/dist/core/model-runtime.d.ts +5 -4
- package/packages/agent/dist/core/provider-composer.d.ts +2 -1
- package/packages/agent/dist/core/tools/bash.d.ts +9 -3
- package/packages/agent/dist/index.d.ts +1 -1
- package/packages/agent/src/core/agent-settings.ts +1 -4
- package/packages/agent/src/core/compaction/compaction.ts +68 -30
- package/packages/agent/src/core/model-runtime.ts +12 -5
- package/packages/agent/src/core/provider-composer.ts +5 -0
- package/packages/agent/src/core/tools/bash.ts +36 -30
- package/packages/agent/src/index.ts +3 -0
- package/packages/ai/dist/types.d.ts +11 -0
- package/packages/ai/src/types.ts +12 -0
- package/packages/ragents/src/agents/plugins.ts +5 -0
- package/packages/ragents/src/domain/event-semantics.ts +3 -0
- package/packages/ragents/src/domain/event-validation.ts +15 -2
- package/packages/ragents/src/domain/events.ts +3 -0
- package/packages/ragents/src/domain/model.ts +2 -0
- package/packages/ragents/src/domain/projection.ts +1 -0
- package/packages/ragents/src/drivers/agent-runtime.ts +1 -1
- package/packages/ragents/src/drivers/agent-turn.ts +8 -6
- package/packages/ragents/src/index.ts +1 -0
- package/packages/ragents/src/plugin-host.ts +58 -10
- package/packages/ragents/src/plugin-types.ts +7 -2
- package/packages/ragents/src/runtime/decisions/inputs.ts +6 -2
- package/packages/ragents/src/runtime/journal-storage.ts +5 -4
- package/packages/workspace-executor/package.json +0 -1
- package/packages/workspace-executor/src/bash-launch.ts +56 -10
- package/packages/workspace-executor/src/context.ts +4 -0
- package/packages/workspace-executor/src/contributions.ts +150 -0
- package/packages/workspace-executor/src/executor.ts +1 -1
- package/packages/workspace-executor/src/index.ts +16 -19
- package/packages/workspace-executor/src/language-server/host.ts +3 -0
- package/packages/workspace-executor/src/language-server/module.ts +12 -2
- package/packages/workspace-executor/src/language-server/roots.ts +0 -5
- package/packages/workspace-executor/src/modules.ts +7 -6
- package/packages/workspace-executor/src/sandbox-tools.ts +3 -9
- package/packages/workspace-executor/src/shell-platform.ts +14 -3
- package/packages/workspace-executor/src/tools.ts +0 -3
- package/plugins/ragents.ask/ask-payload.ts +9 -0
- package/plugins/ragents.ask/server/ask-service.ts +53 -13
- package/plugins/ragents.ask/web/AskActionView.tsx +3 -2
- package/plugins/ragents.browser/executor/index.ts +5 -0
- package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/module.ts +25 -31
- package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/playwright.ts +9 -23
- package/plugins/ragents.browser/provision.ts +1 -1
- package/plugins/ragents.browser/server/browser.ts +3 -3
- package/plugins/ragents.browser/server/contract.ts +2 -2
- package/plugins/ragents.browser/server/index.ts +1 -1
- package/plugins/ragents.lsp-fsharp/executor.ts +80 -0
- package/plugins/ragents.lsp-fsharp/provision.ts +1 -1
- package/plugins/ragents.lsp-fsharp/server/index.ts +2 -2
- package/plugins/ragents.lsp-roslyn/executor.ts +64 -0
- package/plugins/ragents.lsp-roslyn/provision.ts +1 -1
- package/plugins/ragents.lsp-roslyn/server/index.ts +28 -5
- package/plugins/ragents.lsp-roslyn/server/solution-on-start.ts +18 -6
- package/plugins/ragents.lsp-typescript/executor.ts +50 -0
- package/plugins/ragents.lsp-typescript/server/index.ts +2 -2
- package/plugins/ragents.model-relay/server/config.ts +1 -1
- package/plugins/ragents.model-relay/server/relay.ts +4 -2
- package/plugins/ragents.profile-distribution/server/archive.ts +2 -1
- package/plugins/ragents.workspace/client/workspace-client.ts +111 -28
- package/plugins/ragents.workspace/contract.ts +33 -2
- package/plugins/ragents.workspace/server/binding.ts +10 -4
- package/plugins/ragents.workspace/server/clients.ts +56 -9
- package/plugins/ragents.workspace/server/config.ts +9 -0
- package/plugins/ragents.workspace/server/index.ts +13 -4
- package/plugins/ragents.workspace/server/runtime.ts +10 -0
- package/plugins/ragents.workspace/server/shell-platform.ts +6 -5
- package/plugins/ragents.workspace/web/WorkspaceBinding.tsx +1 -1
- package/ragents.config.core.ts +4 -1
- package/ragents.config.showcase.ts +4 -1
- package/scripts/agent/journal.ts +3 -1
- package/scripts/package/build-package.ts +3 -1
- package/scripts/package/publish-package.ts +4 -3
- package/scripts/provision/run-provision.ts +2 -2
- package/scripts/workspace-client/run-workspace-client.ts +7 -4
- package/apps/web/dist/help/screenshots/release-checklist-vscode.png +0 -0
- package/apps/web/dist/help/screenshots/release-checklist-web.png +0 -0
- package/bundles/ragents.ask/web/chunks/chunk-HGFDGTNC.js +0 -2
- package/bundles/ragents.ask/web/chunks/chunk-HGFDGTNC.js.map +0 -7
- package/bundles/ragents.browser/server/chunks/chunk-2GKLLCBE.js.map +0 -7
- package/packages/workspace-executor/src/language-server/adapters/fsharp.ts +0 -60
- package/packages/workspace-executor/src/language-server/adapters/index.ts +0 -7
- package/packages/workspace-executor/src/language-server/adapters/roslyn.ts +0 -56
- package/packages/workspace-executor/src/language-server/adapters/typescript.ts +0 -74
- package/packages/workspace-executor/src/language-server/solution.ts +0 -13
- /package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/contract.ts +0 -0
- /package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/pages.ts +0 -0
|
@@ -520,6 +520,15 @@ export interface ModelCost extends ModelCostRates {
|
|
|
520
520
|
/** Request-wide pricing tiers. The highest matching input threshold applies to the full request. */
|
|
521
521
|
tiers?: ModelCostTier[];
|
|
522
522
|
}
|
|
523
|
+
/** When an agent compacts its context on a model and how much it keeps, in absolute tokens of that model. */
|
|
524
|
+
export interface ModelCompaction {
|
|
525
|
+
/** Context tokens above which the agent compacts. */
|
|
526
|
+
threshold: number;
|
|
527
|
+
/** Tokens of the newest context the compaction keeps verbatim. */
|
|
528
|
+
keepRecentTokens: number;
|
|
529
|
+
/** Output budget of the summary. */
|
|
530
|
+
summaryTokens: number;
|
|
531
|
+
}
|
|
523
532
|
export interface Model<TApi extends Api> {
|
|
524
533
|
id: string;
|
|
525
534
|
name: string;
|
|
@@ -536,6 +545,8 @@ export interface Model<TApi extends Api> {
|
|
|
536
545
|
cost: ModelCost;
|
|
537
546
|
contextWindow: number;
|
|
538
547
|
maxTokens: number;
|
|
548
|
+
/** The model's own compaction values; without them the agent applies the catalog standard of its context window. */
|
|
549
|
+
compaction?: ModelCompaction;
|
|
539
550
|
headers?: Record<string, string>;
|
|
540
551
|
/** Compatibility overrides for OpenAI-compatible APIs. If not set, auto-detected from baseUrl. */
|
|
541
552
|
compat?: TApi extends "openai-completions" ? OpenAICompletionsCompat : TApi extends "openai-responses" | "openai-codex-responses" ? OpenAIResponsesCompat : TApi extends "anthropic-messages" ? AnthropicMessagesCompat : never;
|
package/packages/ai/src/types.ts
CHANGED
|
@@ -561,6 +561,16 @@ export interface ModelCost extends ModelCostRates {
|
|
|
561
561
|
tiers?: ModelCostTier[];
|
|
562
562
|
}
|
|
563
563
|
|
|
564
|
+
/** When an agent compacts its context on a model and how much it keeps, in absolute tokens of that model. */
|
|
565
|
+
export interface ModelCompaction {
|
|
566
|
+
/** Context tokens above which the agent compacts. */
|
|
567
|
+
threshold: number;
|
|
568
|
+
/** Tokens of the newest context the compaction keeps verbatim. */
|
|
569
|
+
keepRecentTokens: number;
|
|
570
|
+
/** Output budget of the summary. */
|
|
571
|
+
summaryTokens: number;
|
|
572
|
+
}
|
|
573
|
+
|
|
564
574
|
// Model interface for the unified model system
|
|
565
575
|
export interface Model<TApi extends Api> {
|
|
566
576
|
id: string;
|
|
@@ -578,6 +588,8 @@ export interface Model<TApi extends Api> {
|
|
|
578
588
|
cost: ModelCost;
|
|
579
589
|
contextWindow: number;
|
|
580
590
|
maxTokens: number;
|
|
591
|
+
/** The model's own compaction values; without them the agent applies the catalog standard of its context window. */
|
|
592
|
+
compaction?: ModelCompaction;
|
|
581
593
|
headers?: Record<string, string>;
|
|
582
594
|
/** Compatibility overrides for OpenAI-compatible APIs. If not set, auto-detected from baseUrl. */
|
|
583
595
|
compat?: TApi extends "openai-completions"
|
|
@@ -19,6 +19,8 @@ export type ToolContributor = {
|
|
|
19
19
|
name: string;
|
|
20
20
|
descriptors: readonly ToolDescriptor[];
|
|
21
21
|
dynamic?: boolean;
|
|
22
|
+
/** Ob die Werkzeuge in einem Run gelten; ohne Angabe in jedem, sonst fehlen sie dort ganz. */
|
|
23
|
+
runCondition?: (runId: string) => boolean;
|
|
22
24
|
tools: (context: PluginContext) => readonly RunFunction[] | Promise<readonly RunFunction[]>;
|
|
23
25
|
};
|
|
24
26
|
|
|
@@ -74,6 +76,9 @@ export class ToolRegistry implements ToolProvider {
|
|
|
74
76
|
const taken = new Set(agentTools.map((entry) => entry.name));
|
|
75
77
|
|
|
76
78
|
for (const plugin of this.#plugins) {
|
|
79
|
+
if (plugin.runCondition && !plugin.runCondition(context.runId))
|
|
80
|
+
continue;
|
|
81
|
+
|
|
77
82
|
const tools = await plugin.tools(context);
|
|
78
83
|
this.#assertDescriptors(plugin, tools);
|
|
79
84
|
|
|
@@ -358,6 +358,9 @@ export const assertEventSemantics = (
|
|
|
358
358
|
for (const artifactId of event.payload.artifactIds)
|
|
359
359
|
assertArtifactRead(state, event.actorId, artifactId);
|
|
360
360
|
|
|
361
|
+
if (event.payload.origin === "human" && existingActorOf(state, event.actorId).kind !== "human")
|
|
362
|
+
throw new Error(`Input ${event.payload.inputId} of human origin was not enqueued by a human actor.`);
|
|
363
|
+
|
|
361
364
|
if (event.payload.subscriptionId) {
|
|
362
365
|
const subscription = state.subscriptions.get(event.payload.subscriptionId);
|
|
363
366
|
|
|
@@ -431,9 +431,13 @@ const payloadOf = (type: EventType, value: unknown, path: string) => {
|
|
|
431
431
|
"artifactIds",
|
|
432
432
|
"sourceEventIds",
|
|
433
433
|
"subscriptionId",
|
|
434
|
-
], ["presentation"]);
|
|
434
|
+
], ["presentation", "origin"]);
|
|
435
435
|
if (payload.presentation !== undefined && payload.presentation !== "background")
|
|
436
436
|
fail(`${path}.presentation`, "must be background");
|
|
437
|
+
if (payload.origin !== undefined && payload.origin !== "human")
|
|
438
|
+
fail(`${path}.origin`, "must be human");
|
|
439
|
+
if (subscriptionInput && Object.hasOwn(payload, "origin"))
|
|
440
|
+
fail(`${path}.origin`, "is not supported for a subscription input");
|
|
437
441
|
stringOf(payload.inputId, `${path}.inputId`);
|
|
438
442
|
actorIdOf(payload.actorId, `${path}.actorId`);
|
|
439
443
|
stringArrayOf(payload.artifactIds, `${path}.artifactIds`);
|
|
@@ -545,7 +549,7 @@ const payloadOf = (type: EventType, value: unknown, path: string) => {
|
|
|
545
549
|
"model",
|
|
546
550
|
"readFiles",
|
|
547
551
|
"modifiedFiles",
|
|
548
|
-
]);
|
|
552
|
+
], ["threshold"]);
|
|
549
553
|
stringOf(payload.turnId, `${path}.turnId`);
|
|
550
554
|
nonEmptyStringOf(payload.summary, `${path}.summary`);
|
|
551
555
|
nonEmptyStringOf(payload.firstKeptEventId, `${path}.firstKeptEventId`);
|
|
@@ -554,6 +558,15 @@ const payloadOf = (type: EventType, value: unknown, path: string) => {
|
|
|
554
558
|
nonEmptyStringOf(payload.model, `${path}.model`);
|
|
555
559
|
stringArrayOf(payload.readFiles, `${path}.readFiles`);
|
|
556
560
|
stringArrayOf(payload.modifiedFiles, `${path}.modifiedFiles`);
|
|
561
|
+
|
|
562
|
+
if (Object.hasOwn(payload, "threshold")) {
|
|
563
|
+
const threshold = exactObject(payload.threshold, `${path}.threshold`, ["tokens", "source"]);
|
|
564
|
+
if (!Number.isSafeInteger(threshold.tokens))
|
|
565
|
+
fail(`${path}.threshold.tokens`, "must be a safe integer");
|
|
566
|
+
if (threshold.source !== "model" && threshold.source !== "catalog")
|
|
567
|
+
fail(`${path}.threshold.source`, "must be model or catalog");
|
|
568
|
+
}
|
|
569
|
+
|
|
557
570
|
return;
|
|
558
571
|
}
|
|
559
572
|
|
|
@@ -93,6 +93,7 @@ export type EventPayloads = {
|
|
|
93
93
|
actorId: ActorId;
|
|
94
94
|
artifactIds: string[];
|
|
95
95
|
presentation?: "background";
|
|
96
|
+
origin?: "human";
|
|
96
97
|
} & (
|
|
97
98
|
| { subscriptionId: null; sourceEventIds: string[]; content: string }
|
|
98
99
|
| { subscriptionId: SubscriptionId; sourceEventIds: [string]; content?: never }
|
|
@@ -151,6 +152,8 @@ export type EventPayloads = {
|
|
|
151
152
|
model: string;
|
|
152
153
|
readFiles: string[];
|
|
153
154
|
modifiedFiles: string[];
|
|
155
|
+
/** The compaction threshold of the model and whether it is the model's own or the catalog standard; absent before file format 9. */
|
|
156
|
+
threshold?: { tokens: number; source: "model" | "catalog" };
|
|
154
157
|
};
|
|
155
158
|
"model.output.completed": {
|
|
156
159
|
turnId: TurnId;
|
|
@@ -89,6 +89,8 @@ export type ActorInput = {
|
|
|
89
89
|
actorId: ActorId;
|
|
90
90
|
content: string;
|
|
91
91
|
presentation?: "background";
|
|
92
|
+
/** Set only on a person's own message, because system inputs are enqueued under the owner too. */
|
|
93
|
+
origin?: "human";
|
|
92
94
|
artifactIds: readonly ArtifactId[];
|
|
93
95
|
enqueuedBy: ActorId;
|
|
94
96
|
enqueuedAt: string;
|
|
@@ -222,6 +222,7 @@ export function applyEvent(
|
|
|
222
222
|
actorId: event.payload.actorId,
|
|
223
223
|
content: event.payload.subscriptionId === null ? event.payload.content : JSON.stringify(source),
|
|
224
224
|
...(event.payload.presentation ? { presentation: event.payload.presentation } : {}),
|
|
225
|
+
...(event.payload.origin ? { origin: event.payload.origin } : {}),
|
|
225
226
|
artifactIds: event.payload.artifactIds,
|
|
226
227
|
enqueuedBy: event.actorId,
|
|
227
228
|
enqueuedAt: event.occurredAt,
|
|
@@ -36,7 +36,7 @@ export type AgentRuntimeManagerOptions = {
|
|
|
36
36
|
context: AgentRuntimeContext,
|
|
37
37
|
signal: AbortSignal,
|
|
38
38
|
) => readonly AgentHook[] | Promise<readonly AgentHook[]>;
|
|
39
|
-
/**
|
|
39
|
+
/** Retry and provider request limits; unset values keep the defaults. Compaction comes from the model. */
|
|
40
40
|
settings?: AgentSettingsInput;
|
|
41
41
|
turnAbortTimeoutMs?: number;
|
|
42
42
|
onDiagnostic?: (diagnostic: AgentRuntimeDiagnostic) => void;
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
type AgentTool,
|
|
11
11
|
calculateContextTokens,
|
|
12
12
|
compact,
|
|
13
|
+
compactionOf,
|
|
13
14
|
contextMessages,
|
|
14
15
|
convertToLlm,
|
|
15
16
|
EMPTY_RESPONSE_NUDGE,
|
|
@@ -626,12 +627,11 @@ export class AgentTurn {
|
|
|
626
627
|
return true;
|
|
627
628
|
}
|
|
628
629
|
|
|
629
|
-
/** After a context overflow compacts and retries once; over the threshold compacts without a retry. */
|
|
630
|
+
/** After a context overflow compacts and retries once; over the threshold of the turn's model compacts without a retry. */
|
|
630
631
|
async #checkCompaction(assistant: AssistantMessage | undefined, skipAborted = true): Promise<boolean> {
|
|
631
|
-
const settings = this.#options.settings.compaction;
|
|
632
632
|
const { model } = this.#options;
|
|
633
633
|
|
|
634
|
-
if (!assistant ||
|
|
634
|
+
if (!assistant || (skipAborted && assistant.stopReason === "aborted"))
|
|
635
635
|
return false;
|
|
636
636
|
|
|
637
637
|
const contextWindow = model.contextWindow ?? 0;
|
|
@@ -672,12 +672,13 @@ export class AgentTurn {
|
|
|
672
672
|
contextTokens = estimate.tokens;
|
|
673
673
|
}
|
|
674
674
|
|
|
675
|
-
return shouldCompact(contextTokens,
|
|
675
|
+
return shouldCompact(contextTokens, compactionOf(model).values) ? this.#compact(false) : false;
|
|
676
676
|
}
|
|
677
677
|
|
|
678
678
|
async #compact(retry: boolean): Promise<boolean> {
|
|
679
|
-
const { model, modelRuntime, thinkingLevel
|
|
680
|
-
const
|
|
679
|
+
const { model, modelRuntime, thinkingLevel } = this.#options;
|
|
680
|
+
const compaction = compactionOf(model);
|
|
681
|
+
const preparation = prepareCompaction([...this.#request.modelContext().entries], compaction.values);
|
|
681
682
|
|
|
682
683
|
if (!preparation)
|
|
683
684
|
return false;
|
|
@@ -715,6 +716,7 @@ export class AgentTurn {
|
|
|
715
716
|
model: model.id,
|
|
716
717
|
readFiles: result.readFiles,
|
|
717
718
|
modifiedFiles: result.modifiedFiles,
|
|
719
|
+
threshold: { tokens: compaction.values.threshold, source: compaction.source },
|
|
718
720
|
},
|
|
719
721
|
});
|
|
720
722
|
const messages = this.#request.modelContext().messages;
|
|
@@ -41,6 +41,7 @@ import type {
|
|
|
41
41
|
RAgentsPlugin,
|
|
42
42
|
ServiceToken,
|
|
43
43
|
RegisteredStartOption,
|
|
44
|
+
RunCondition,
|
|
44
45
|
SessionLifecycleContribution,
|
|
45
46
|
SessionMetadata,
|
|
46
47
|
SessionStartedContext,
|
|
@@ -86,6 +87,24 @@ class ContributionRegistry<T extends { id: string }> {
|
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
89
|
|
|
90
|
+
/** Die Laufbedingung je Plugin; ein Plugin ohne gilt in jedem Run. */
|
|
91
|
+
export class RunConditionRegistry {
|
|
92
|
+
readonly #conditions = new Map<string, RunCondition>();
|
|
93
|
+
|
|
94
|
+
register(owner: string, condition: RunCondition): void {
|
|
95
|
+
if (this.#conditions.has(owner)) throw new Error(`Plugin ${owner} hat bereits eine Laufbedingung`);
|
|
96
|
+
this.#conditions.set(owner, condition);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
has(owner: string): boolean {
|
|
100
|
+
return this.#conditions.has(owner);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
applies(owner: string, runId: string): boolean {
|
|
104
|
+
return this.#conditions.get(owner)?.(runId) ?? true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
89
108
|
export class MethodContributionRegistry {
|
|
90
109
|
readonly #methods = new ContributionRegistry<{ id: string; contribution: MethodContribution }>("Methode");
|
|
91
110
|
|
|
@@ -219,6 +238,11 @@ export class OperationContributionRegistry {
|
|
|
219
238
|
|
|
220
239
|
export class AgentContributionRegistry {
|
|
221
240
|
readonly #contributions = new ContributionRegistry<AgentContribution>("Agent-Beitrag");
|
|
241
|
+
readonly #conditions: RunConditionRegistry;
|
|
242
|
+
|
|
243
|
+
constructor(conditions = new RunConditionRegistry()) {
|
|
244
|
+
this.#conditions = conditions;
|
|
245
|
+
}
|
|
222
246
|
|
|
223
247
|
register(owner: string, contributions: readonly AgentContribution[]): void {
|
|
224
248
|
for (const contribution of contributions) {
|
|
@@ -230,7 +254,9 @@ export class AgentContributionRegistry {
|
|
|
230
254
|
}
|
|
231
255
|
|
|
232
256
|
resolve(context: AgentContributionContext): readonly AgentHook[] {
|
|
233
|
-
return this.#contributions.entries()
|
|
257
|
+
return this.#contributions.entries()
|
|
258
|
+
.filter(({ owner }) => this.#conditions.applies(owner, context.runId))
|
|
259
|
+
.map(({ value }) => agentHookOf(value, context));
|
|
234
260
|
}
|
|
235
261
|
|
|
236
262
|
describe(): readonly PublicAgentHookContribution[] {
|
|
@@ -246,6 +272,11 @@ export class AgentContributionRegistry {
|
|
|
246
272
|
|
|
247
273
|
export class ToolContributionRegistry {
|
|
248
274
|
readonly #contributors: Owned<ToolContributor>[] = [];
|
|
275
|
+
readonly #conditions: RunConditionRegistry;
|
|
276
|
+
|
|
277
|
+
constructor(conditions = new RunConditionRegistry()) {
|
|
278
|
+
this.#conditions = conditions;
|
|
279
|
+
}
|
|
249
280
|
|
|
250
281
|
register(owner: string, contributors: readonly ToolContributor[]): void {
|
|
251
282
|
for (const contributor of contributors) {
|
|
@@ -278,7 +309,9 @@ export class ToolContributionRegistry {
|
|
|
278
309
|
}
|
|
279
310
|
|
|
280
311
|
entries(): readonly ToolContributor[] {
|
|
281
|
-
return this.#contributors.map(({ value }) =>
|
|
312
|
+
return this.#contributors.map(({ owner, value }) => this.#conditions.has(owner)
|
|
313
|
+
? { ...value, runCondition: (runId: string) => this.#conditions.applies(owner, runId) }
|
|
314
|
+
: value);
|
|
282
315
|
}
|
|
283
316
|
|
|
284
317
|
describe(): readonly PublicToolDescriptor[] {
|
|
@@ -295,6 +328,11 @@ export class ToolContributionRegistry {
|
|
|
295
328
|
|
|
296
329
|
export class PromptContributionRegistry {
|
|
297
330
|
readonly #prompts = new ContributionRegistry<PromptContribution>("Prompt-Beitrag");
|
|
331
|
+
readonly #conditions: RunConditionRegistry;
|
|
332
|
+
|
|
333
|
+
constructor(conditions = new RunConditionRegistry()) {
|
|
334
|
+
this.#conditions = conditions;
|
|
335
|
+
}
|
|
298
336
|
|
|
299
337
|
register(owner: string, prompts: readonly PromptContribution[]): void {
|
|
300
338
|
this.#prompts.register(owner, prompts);
|
|
@@ -330,10 +368,13 @@ export class PromptContributionRegistry {
|
|
|
330
368
|
})));
|
|
331
369
|
}
|
|
332
370
|
|
|
333
|
-
/** Die Beiträge, die für diesen Run anders lauten als im Schnappschuss; alles andere bleibt der gerenderte Text. */
|
|
371
|
+
/** Die Beiträge, die für diesen Run anders lauten als im Schnappschuss; ein leerer Text fehlt dort, alles andere bleibt der gerenderte Text. */
|
|
334
372
|
runOverrides(runId: string): ReadonlyMap<string, string> {
|
|
335
|
-
return new Map([...this.#prompts.entries()].flatMap(({ value }) =>
|
|
336
|
-
|
|
373
|
+
return new Map([...this.#prompts.entries()].flatMap(({ owner, value }) => {
|
|
374
|
+
if (!this.#conditions.applies(owner, runId)) return [[value.id, ""] as const];
|
|
375
|
+
const text = value.renderForRun?.(runId);
|
|
376
|
+
return text === undefined ? [] : [[value.id, text.trim()] as const];
|
|
377
|
+
}));
|
|
337
378
|
}
|
|
338
379
|
|
|
339
380
|
static handlebarsContext(context: PromptRenderContext): Record<string, unknown> {
|
|
@@ -343,6 +384,11 @@ export class PromptContributionRegistry {
|
|
|
343
384
|
|
|
344
385
|
export class SkillContributionRegistry {
|
|
345
386
|
readonly #skills = new ContributionRegistry<SkillContribution>("Skill-Beitrag");
|
|
387
|
+
readonly #conditions: RunConditionRegistry;
|
|
388
|
+
|
|
389
|
+
constructor(conditions = new RunConditionRegistry()) {
|
|
390
|
+
this.#conditions = conditions;
|
|
391
|
+
}
|
|
346
392
|
|
|
347
393
|
register(owner: string, skills: readonly SkillContribution[]): void {
|
|
348
394
|
for (const skill of skills) {
|
|
@@ -385,7 +431,7 @@ export class SkillContributionRegistry {
|
|
|
385
431
|
id: value.id,
|
|
386
432
|
owner,
|
|
387
433
|
audiences: value.audiences ?? allAudiences,
|
|
388
|
-
paths: await value.paths(context),
|
|
434
|
+
paths: context && !this.#conditions.applies(owner, context.runId) ? [] : await value.paths(context),
|
|
389
435
|
})));
|
|
390
436
|
}
|
|
391
437
|
}
|
|
@@ -1068,10 +1114,11 @@ export class PluginHost {
|
|
|
1068
1114
|
readonly channels = new ChannelContributionRegistry();
|
|
1069
1115
|
readonly http = new HttpContributionRegistry();
|
|
1070
1116
|
readonly operations = new OperationContributionRegistry();
|
|
1071
|
-
readonly
|
|
1072
|
-
readonly
|
|
1073
|
-
readonly
|
|
1074
|
-
readonly
|
|
1117
|
+
readonly runConditions = new RunConditionRegistry();
|
|
1118
|
+
readonly agentRuntime = new AgentContributionRegistry(this.runConditions);
|
|
1119
|
+
readonly tools = new ToolContributionRegistry(this.runConditions);
|
|
1120
|
+
readonly prompts = new PromptContributionRegistry(this.runConditions);
|
|
1121
|
+
readonly skills = new SkillContributionRegistry(this.runConditions);
|
|
1075
1122
|
readonly startEntries = new StartEntryContributionRegistry();
|
|
1076
1123
|
readonly profiles = new ProfileContributionRegistry();
|
|
1077
1124
|
readonly script = new ScriptContributionRegistry();
|
|
@@ -1121,6 +1168,7 @@ export class PluginHost {
|
|
|
1121
1168
|
agentRuntime: (...entries) => this.agentRuntime.register(manifest.id, entries),
|
|
1122
1169
|
profiles: (...entries) => this.profiles.register(manifest.id, entries),
|
|
1123
1170
|
prompts: (...entries) => this.prompts.register(manifest.id, entries),
|
|
1171
|
+
runCondition: (condition) => this.runConditions.register(manifest.id, condition),
|
|
1124
1172
|
provide: (token, service) => this.#services.provide(manifest.id, token, service),
|
|
1125
1173
|
service: (token) => this.#services.require(token),
|
|
1126
1174
|
optionalService: (token) => this.#services.optional(token),
|
|
@@ -277,10 +277,13 @@ export interface PromptContribution {
|
|
|
277
277
|
delivery?: "initial" | "on-demand";
|
|
278
278
|
requiresTools?: readonly string[];
|
|
279
279
|
render: (context: PromptRenderContext) => string | Promise<string>;
|
|
280
|
-
/** Hängt der Beitrag am einzelnen Run, ersetzt dieser Text den von `render
|
|
281
|
-
renderForRun?: (runId: string) => string;
|
|
280
|
+
/** Hängt der Beitrag am einzelnen Run, ersetzt dieser Text den von `render`, undefined behält ihn - synchron, damit der Turn ihn ohne Warten hat. */
|
|
281
|
+
renderForRun?: (runId: string) => string | undefined;
|
|
282
282
|
}
|
|
283
283
|
|
|
284
|
+
/** Ob die laufbezogenen Beiträge eines Plugins in einem Run gelten; der Host fragt je Run, ein Wurf lässt dessen Turn mit dieser Ursache scheitern. */
|
|
285
|
+
export type RunCondition = (runId: string) => boolean;
|
|
286
|
+
|
|
284
287
|
export type ModelProviderConfig = Parameters<ModelRuntime["registerProvider"]>[1];
|
|
285
288
|
|
|
286
289
|
export interface ModelProviderRegistration {
|
|
@@ -420,6 +423,8 @@ export interface PluginRegistration {
|
|
|
420
423
|
agentRuntime: (...contributions: readonly AgentContribution[]) => void;
|
|
421
424
|
profiles: (...contributions: readonly ProfileContribution[]) => void;
|
|
422
425
|
prompts: (...contributions: readonly PromptContribution[]) => void;
|
|
426
|
+
/** Prompts, Funktionen, Skills und Agent-Hooks dieses Plugins gelten nur in Runs, für die die Bedingung zutrifft; höchstens eine je Plugin. */
|
|
427
|
+
runCondition: (condition: RunCondition) => void;
|
|
423
428
|
provide: <T>(token: ServiceToken<T>, service: T) => void;
|
|
424
429
|
service: <T>(token: ServiceToken<T>) => T;
|
|
425
430
|
optionalService: <T>(token: ServiceToken<T>) => T | undefined;
|
|
@@ -17,8 +17,8 @@ export type EnqueueInput = {
|
|
|
17
17
|
artifactIds?: readonly string[];
|
|
18
18
|
presentation?: "background";
|
|
19
19
|
} & (
|
|
20
|
-
| { content: string; sourceEventIds?: readonly string[]; subscriptionId?: null }
|
|
21
|
-
| { content?: never; sourceEventIds: readonly [string]; subscriptionId: string }
|
|
20
|
+
| { content: string; sourceEventIds?: readonly string[]; subscriptionId?: null; origin?: "human" }
|
|
21
|
+
| { content?: never; sourceEventIds: readonly [string]; subscriptionId: string; origin?: never }
|
|
22
22
|
);
|
|
23
23
|
|
|
24
24
|
export const enqueueInput =
|
|
@@ -43,6 +43,9 @@ export const enqueueInput =
|
|
|
43
43
|
assertCapability(caller, "actor.input", { kind: "run" });
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
if (input.origin === "human" && caller.kind !== "human")
|
|
47
|
+
throw new DomainError("input-origin-invalid", "Only a human can enqueue an input of human origin.", 403);
|
|
48
|
+
|
|
46
49
|
const artifactIds = [...new Set(input.artifactIds ?? [])];
|
|
47
50
|
|
|
48
51
|
for (const artifactId of artifactIds)
|
|
@@ -55,6 +58,7 @@ export const enqueueInput =
|
|
|
55
58
|
actorId: target.id,
|
|
56
59
|
artifactIds,
|
|
57
60
|
...(input.presentation !== undefined ? { presentation: input.presentation } : {}),
|
|
61
|
+
...(input.origin !== undefined ? { origin: input.origin } : {}),
|
|
58
62
|
};
|
|
59
63
|
|
|
60
64
|
if (subscriptionId && firstSourceEventId === undefined)
|
|
@@ -8,9 +8,10 @@ import { isRunId } from "../domain/portable-id.ts";
|
|
|
8
8
|
import { syncDirectory } from "./durable-fs.ts";
|
|
9
9
|
import type { CommandRecord, JournalCommand } from "./journal.ts";
|
|
10
10
|
|
|
11
|
-
/** Rises whenever an older stand would reject newly written lines;
|
|
12
|
-
export const journalStorageVersion =
|
|
13
|
-
const
|
|
11
|
+
/** Rises whenever an older stand would reject newly written lines; formats 7 and 8 stay readable because they only lack the input origin and the compaction threshold. */
|
|
12
|
+
export const journalStorageVersion = 9;
|
|
13
|
+
const oldestReadableJournalStorageVersion = 7;
|
|
14
|
+
const readableJournalStorageVersions: readonly unknown[] = [oldestReadableJournalStorageVersion, 8, journalStorageVersion];
|
|
14
15
|
export const journalPayloadThresholdBytes = 4096;
|
|
15
16
|
|
|
16
17
|
type PayloadReference = { sha256: string; bytes: number };
|
|
@@ -162,7 +163,7 @@ export const parseJournalRecord = (line: string, runDirectory: string, location:
|
|
|
162
163
|
|
|
163
164
|
if (!readableJournalStorageVersions.includes(record.formatVersion))
|
|
164
165
|
throw new Error(`${location} has unsupported journal format version ${String(record.formatVersion)}.${
|
|
165
|
-
typeof record.formatVersion === "number" && record.formatVersion <
|
|
166
|
+
typeof record.formatVersion === "number" && record.formatVersion < oldestReadableJournalStorageVersion
|
|
166
167
|
? " Journals before format 7 hold no model context and are not migrated."
|
|
167
168
|
: ""}`);
|
|
168
169
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
1
|
+
import { accessSync, constants, existsSync, statSync } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { getShellConfig } from "@ragents/agent";
|
|
4
4
|
|
|
@@ -9,6 +9,12 @@ export interface BashLaunch {
|
|
|
9
9
|
readonly env: NodeJS.ProcessEnv;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
/** Was der Executor dem Werkzeug bash mitgibt: die Bash selbst und rg; ohne Angabe gilt jeweils das des Systems. */
|
|
13
|
+
export interface BashPrograms {
|
|
14
|
+
readonly bash: string | undefined;
|
|
15
|
+
readonly rg: string | undefined;
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
/** Unter Windows sucht RAgents keine Bash; der Executor nennt die mitgebrachte. */
|
|
13
19
|
const missingWindowsBash = (): Error => new Error(
|
|
14
20
|
"Unter Windows arbeitet das Werkzeug bash nur mit der Bash, die RAgents mitbringt, und für diesen Executor ist keine genannt. "
|
|
@@ -16,17 +22,51 @@ const missingWindowsBash = (): Error => new Error(
|
|
|
16
22
|
+ "und reicht sie an Arbeitsplatz und lokalen Host weiter; ein Host oder Arbeitsplatz ohne Erweiterung braucht RAGENTS_BASH mit dem Pfad dieser bash.exe.",
|
|
17
23
|
);
|
|
18
24
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
const missingRipgrep = (rg: string): Error =>
|
|
26
|
+
new Error(`Das rg dieses Executors fehlt: ${rg}. Es gehört zur Erweiterung (dist/rg/<plattform>) oder steht in RAGENTS_RG.`);
|
|
27
|
+
|
|
28
|
+
const pathModule = (platform: NodeJS.Platform): path.PlatformPath => platform === "win32" ? path.win32 : path.posix;
|
|
29
|
+
|
|
30
|
+
/** Die Namen der PATH-Variablen; unter Windows zählt jede Schreibweise (`Path`). */
|
|
31
|
+
const pathNames = (env: NodeJS.ProcessEnv, platform: NodeJS.Platform): readonly string[] =>
|
|
32
|
+
platform === "win32" ? Object.keys(env).filter((name) => name.toUpperCase() === "PATH") : ["PATH"];
|
|
33
|
+
|
|
34
|
+
const currentPath = (env: NodeJS.ProcessEnv, platform: NodeJS.Platform): string | undefined =>
|
|
35
|
+
pathNames(env, platform).map((name) => env[name]).find((value) => value !== undefined && value !== "");
|
|
36
|
+
|
|
37
|
+
/** Die Ordner vorn im PATH, als eine Variable PATH; MSYSTEM gehört unter Windows einer Git-Bash-Anmeldung und fällt weg. */
|
|
38
|
+
const withPathFront = (env: NodeJS.ProcessEnv, directories: readonly string[], platform: NodeJS.Platform): NodeJS.ProcessEnv => {
|
|
39
|
+
if (directories.length === 0) return env;
|
|
40
|
+
const names = pathNames(env, platform);
|
|
41
|
+
const current = currentPath(env, platform);
|
|
42
|
+
const kept = Object.entries(env).filter(([name]) => !names.includes(name) && (platform !== "win32" || name !== "MSYSTEM"));
|
|
43
|
+
const delimiter = pathModule(platform).delimiter;
|
|
44
|
+
return { ...Object.fromEntries(kept), PATH: [...directories, ...(current ? [current] : [])].join(delimiter) };
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const isExecutableFile = (file: string, platform: NodeJS.Platform): boolean => {
|
|
48
|
+
try {
|
|
49
|
+
if (platform !== "win32") accessSync(file, constants.X_OK);
|
|
50
|
+
return statSync(file).isFile();
|
|
51
|
+
} catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** Ob die Bash dieses Executors rg findet: das genannte, sonst eines im PATH; ein genanntes, das fehlt, ist ein Fehler. */
|
|
57
|
+
export const ripgrepAvailable = (rg: string | undefined, env: NodeJS.ProcessEnv, platform: NodeJS.Platform = process.platform): boolean => {
|
|
58
|
+
if (rg !== undefined) {
|
|
59
|
+
if (!existsSync(rg)) throw missingRipgrep(rg);
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
const file = platform === "win32" ? "rg.exe" : "rg";
|
|
63
|
+
return (currentPath(env, platform) ?? "").split(pathModule(platform).delimiter).filter(Boolean)
|
|
64
|
+
.some((directory) => isExecutableFile(path.join(directory, file), platform));
|
|
25
65
|
};
|
|
26
66
|
|
|
27
|
-
/** Wie ein Befehl in der Bash dieses Executors startet
|
|
67
|
+
/** Wie ein Befehl in der Bash dieses Executors startet: das Verzeichnis von rg vorn im PATH, unter Windows dahinter das usr/bin der Bash, damit find.exe und sort.exe aus System32 nicht gewinnen. */
|
|
28
68
|
export const bashLaunch = (
|
|
29
|
-
bash
|
|
69
|
+
{ bash, rg }: BashPrograms,
|
|
30
70
|
command: string,
|
|
31
71
|
env: NodeJS.ProcessEnv,
|
|
32
72
|
platform: NodeJS.Platform = process.platform,
|
|
@@ -35,11 +75,17 @@ export const bashLaunch = (
|
|
|
35
75
|
if (bash !== undefined && !existsSync(bash)) {
|
|
36
76
|
throw new Error(`Die Bash dieses Executors fehlt: ${bash}. Unter Windows gehört sie zur Erweiterung (dist/bash/<plattform>) oder steht in RAGENTS_BASH.`);
|
|
37
77
|
}
|
|
78
|
+
if (rg !== undefined && !existsSync(rg)) throw missingRipgrep(rg);
|
|
38
79
|
const shell = getShellConfig(bash, platform);
|
|
39
80
|
if (!/bash(\.exe)?$/i.test(shell.shell)) throw new Error(`${shell.shell} ist keine Bash; das Werkzeug heißt bash und der Prompt beschreibt bash`);
|
|
81
|
+
const paths = pathModule(platform);
|
|
82
|
+
const front = [
|
|
83
|
+
...(rg === undefined ? [] : [paths.dirname(rg)]),
|
|
84
|
+
...(platform === "win32" ? [paths.dirname(shell.shell)] : []),
|
|
85
|
+
];
|
|
40
86
|
return {
|
|
41
87
|
command: shell.shell,
|
|
42
88
|
args: [...shell.args, command],
|
|
43
|
-
env:
|
|
89
|
+
env: withPathFront(env, front, platform),
|
|
44
90
|
};
|
|
45
91
|
};
|
|
@@ -27,6 +27,8 @@ export interface WorkspaceProcessContext {
|
|
|
27
27
|
sandbox?: ProcessSandbox;
|
|
28
28
|
/** Die Bash, mit der das Werkzeug bash startet; unter Windows Pflicht, sonst gilt ohne Angabe die des Systems. */
|
|
29
29
|
bash?: string;
|
|
30
|
+
/** Das rg, dessen Ordner das Werkzeug bash vorn im PATH hat; ohne Angabe gilt eines im PATH, falls es eines gibt. */
|
|
31
|
+
rg?: string;
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
export interface SandboxHomeEnvironment {
|
|
@@ -103,6 +105,7 @@ export interface WorkspaceContextOptions {
|
|
|
103
105
|
source?: NodeJS.ProcessEnv;
|
|
104
106
|
baseEnvironment?: BaseEnvironment;
|
|
105
107
|
bash?: string;
|
|
108
|
+
rg?: string;
|
|
106
109
|
}
|
|
107
110
|
|
|
108
111
|
const namedEntries = (
|
|
@@ -151,5 +154,6 @@ export const workspaceProcessContext = (options: WorkspaceContextOptions): Works
|
|
|
151
154
|
...(options.runOperation === undefined ? {} : { runOperation: options.runOperation }),
|
|
152
155
|
...(options.sandbox === undefined ? {} : { sandbox: options.sandbox }),
|
|
153
156
|
...(options.bash === undefined ? {} : { bash: options.bash }),
|
|
157
|
+
...(options.rg === undefined ? {} : { rg: options.rg }),
|
|
154
158
|
};
|
|
155
159
|
};
|