@lotagate/cli 0.1.25 → 0.1.26
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/README.md +5 -4
- package/bin/lotagate.mjs +50 -8
- package/dist/application/agent/agent-constants.d.ts +6 -0
- package/dist/application/agent/agent-constants.js +1 -0
- package/dist/application/agent/agent-session-store-registry.d.ts +16 -0
- package/dist/application/agent/agent-session-store-registry.js +1 -0
- package/dist/application/agent/agent-session-store.d.ts +4 -0
- package/dist/application/agent/agent-session-store.js +5 -5
- package/dist/application/agent/capability-profile.d.ts +0 -38
- package/dist/application/agent/capability-profile.js +0 -1
- package/dist/application/agent/cli-agent-execution-service.d.ts +22 -12
- package/dist/application/agent/cli-agent-execution-service.js +1 -1
- package/dist/application/agent/cli-agent-preparation-cache.d.ts +39 -0
- package/dist/application/agent/cli-agent-preparation-cache.js +1 -0
- package/dist/application/agent/context-compaction.d.ts +1 -0
- package/dist/application/agent/context-compaction.js +7 -6
- package/dist/application/agent/context-token-cache.d.ts +21 -0
- package/dist/application/agent/context-token-cache.js +4 -0
- package/dist/application/agent/context-usage-service.d.ts +52 -0
- package/dist/application/agent/context-usage-service.js +1 -0
- package/dist/application/agent/continuation-checkpoint.d.ts +15 -0
- package/dist/application/agent/continuation-checkpoint.js +2 -0
- package/dist/application/agent/interactive-agent-guidance.d.ts +3 -3
- package/dist/application/agent/interactive-agent-guidance.js +2 -2
- package/dist/application/chat/pending-attachment-store.d.ts +5 -2
- package/dist/application/chat/pending-attachment-store.js +1 -1
- package/dist/application/commands/application-command-executor.js +1 -1
- package/dist/application/commands/command-catalog.js +1 -1
- package/dist/application/commands/goal-command-handlers.js +6 -6
- package/dist/application/commands/media-command-handlers.js +7 -6
- package/dist/application/commands/runtime-command-handlers.js +9 -9
- package/dist/application/intent/completion-gate.d.ts +2 -5
- package/dist/application/intent/completion-gate.js +1 -1
- package/dist/application/intent/evidence-ledger.d.ts +2 -1
- package/dist/application/intent/evidence-recording-tool-executor.js +1 -1
- package/dist/application/intent/intent-compiler.js +2 -2
- package/dist/application/memory/memory-extractor.js +2 -2
- package/dist/application/model/cached-model-catalog.d.ts +7 -1
- package/dist/application/model/cached-model-catalog.js +1 -1
- package/dist/application/model/model-catalog-service.js +1 -1
- package/dist/application/model/model-context-window.js +1 -1
- package/dist/application/model/model-response-retry.d.ts +7 -1
- package/dist/application/model/model-response-retry.js +1 -1
- package/dist/application/orchestration/cli-subagent-service.d.ts +4 -0
- package/dist/application/orchestration/cli-subagent-service.js +3 -3
- package/dist/application/orchestration/cli-turn-event-projector.js +1 -1
- package/dist/application/orchestration/cli-turn-events.d.ts +0 -7
- package/dist/application/orchestration/goal-input.d.ts +1 -1
- package/dist/application/orchestration/goal-input.js +1 -1
- package/dist/application/orchestration/headless-agent-turn.d.ts +1 -0
- package/dist/application/orchestration/headless-agent-turn.js +3 -3
- package/dist/application/orchestration/orchestration-constants.d.ts +3 -0
- package/dist/application/orchestration/orchestration-constants.js +1 -0
- package/dist/application/orchestration/subagent-handoff.js +3 -3
- package/dist/application/project-intelligence/project-intelligence-constants.d.ts +56 -0
- package/dist/application/project-intelligence/project-intelligence-constants.js +1 -0
- package/dist/application/project-intelligence/project-intelligence-service.js +1 -1
- package/dist/application/protocol/browser-host-tool-executor.d.ts +13 -3
- package/dist/application/protocol/browser-host-tool-executor.js +2 -2
- package/dist/application/protocol/computer-host-tool-executor.d.ts +3 -0
- package/dist/application/protocol/computer-host-tool-executor.js +2 -2
- package/dist/application/protocol/desktop-agent-command.d.ts +2 -2
- package/dist/application/protocol/desktop-agent-command.js +2 -2
- package/dist/application/protocol/desktop-agent-contracts.d.ts +34 -0
- package/dist/application/protocol/desktop-agent-contracts.js +1 -0
- package/dist/application/protocol/desktop-agent-helpers.d.ts +5 -0
- package/dist/application/protocol/desktop-agent-helpers.js +1 -0
- package/dist/application/protocol/desktop-agent-request-parser.d.ts +31 -6
- package/dist/application/protocol/desktop-agent-request-parser.js +1 -1
- package/dist/application/protocol/desktop-approval-broker.d.ts +14 -4
- package/dist/application/protocol/desktop-approval-broker.js +1 -1
- package/dist/application/protocol/desktop-attachment-store.d.ts +19 -2
- package/dist/application/protocol/desktop-attachment-store.js +1 -1
- package/dist/application/protocol/desktop-execution-policy.d.ts +2 -0
- package/dist/application/protocol/desktop-execution-policy.js +1 -1
- package/dist/application/protocol/desktop-host-bridge.d.ts +33 -0
- package/dist/application/protocol/desktop-host-bridge.js +1 -0
- package/dist/application/protocol/desktop-host-capabilities.d.ts +12 -0
- package/dist/application/protocol/desktop-host-capabilities.js +1 -0
- package/dist/application/protocol/desktop-host-tool-executor.d.ts +15 -2
- package/dist/application/protocol/desktop-host-tool-executor.js +2 -2
- package/dist/application/protocol/desktop-intent-event-writer.js +1 -1
- package/dist/application/protocol/desktop-protocol-helpers.js +1 -1
- package/dist/application/protocol/json-line-writer.d.ts +24 -2
- package/dist/application/protocol/json-line-writer.js +2 -2
- package/dist/application/protocol/jsonl-agent-command.d.ts +1 -1
- package/dist/application/protocol/jsonl-agent-command.js +2 -2
- package/dist/application/protocol/jsonl-protocol.d.ts +1 -1
- package/dist/application/protocol/jsonl-protocol.js +2 -2
- package/dist/application/security/desktop-tool-scope-policy.js +1 -1
- package/dist/application/security/tool-action-risk-analyzer.js +1 -1
- package/dist/application/security/tool-approval-service.d.ts +9 -3
- package/dist/application/security/tool-approval-service.js +1 -1
- package/dist/application/security/tool-policy-registry.d.ts +20 -0
- package/dist/application/security/tool-policy-registry.js +1 -0
- package/dist/application/security/tool-risk-classifier.d.ts +2 -1
- package/dist/application/security/tool-risk-classifier.js +1 -1
- package/dist/application/security/workspace-permission-policy.js +1 -1
- package/dist/application/workspace/session-execution-workspace.d.ts +2 -2
- package/dist/application/workspace/session-execution-workspace.js +3 -3
- package/dist/application/workspace/workspace-constants.d.ts +17 -0
- package/dist/application/workspace/workspace-constants.js +1 -0
- package/dist/application/workspace/workspace-file-index.d.ts +0 -1
- package/dist/application/workspace/workspace-file-index.js +1 -1
- package/dist/application/workspace/workspace-instruction-loader.js +1 -1
- package/dist/bootstrap/composition-root.d.ts +1 -0
- package/dist/bootstrap/runtime-factory.d.ts +5 -0
- package/dist/bootstrap/runtime-factory.js +1 -1
- package/dist/domain/errors/cli-error.js +1 -1
- package/dist/domain/extensions/extension-constants.d.ts +1 -0
- package/dist/domain/extensions/extension-constants.js +1 -0
- package/dist/domain/extensions/host-tool-plugin-ids.d.ts +0 -4
- package/dist/domain/extensions/host-tool-plugin-ids.js +1 -1
- package/dist/domain/extensions/plugin-manifest.js +1 -1
- package/dist/domain/intent/intent-contract.d.ts +0 -8
- package/dist/domain/intent/intent-contract.js +1 -1
- package/dist/domain/media/gateway-media-contract.js +1 -1
- package/dist/domain/media/media-constants.d.ts +3 -0
- package/dist/domain/media/media-constants.js +1 -0
- package/dist/domain/media/media-execution-policy.js +1 -1
- package/dist/domain/memory/memory-constants.d.ts +3 -0
- package/dist/domain/memory/memory-constants.js +1 -0
- package/dist/domain/memory/memory-search.js +2 -2
- package/dist/domain/orchestration/goal.d.ts +0 -1
- package/dist/domain/orchestration/goal.js +1 -1
- package/dist/domain/orchestration/work-plan.d.ts +0 -62
- package/dist/domain/orchestration/work-plan.js +0 -1
- package/dist/domain/runtime/assistant-stream-text.d.ts +11 -0
- package/dist/domain/runtime/assistant-stream-text.js +1 -0
- package/dist/domain/runtime/gateway-request-budget.d.ts +19 -0
- package/dist/domain/runtime/gateway-request-budget.js +1 -0
- package/dist/domain/runtime/resource-limits.d.ts +17 -0
- package/dist/domain/runtime/resource-limits.js +1 -1
- package/dist/domain/session/attachment.d.ts +2 -0
- package/dist/domain/workspace/workspace-settings.d.ts +2 -0
- package/dist/domain/workspace/workspace-settings.js +1 -1
- package/dist/infrastructure/agent-sdk/model-response-metrics.d.ts +7 -0
- package/dist/infrastructure/agent-sdk/model-response-metrics.js +1 -0
- package/dist/infrastructure/agent-sdk/model-tool-name-mapper.js +1 -1
- package/dist/infrastructure/agent-sdk/sdk-constants.d.ts +2 -0
- package/dist/infrastructure/agent-sdk/sdk-constants.js +1 -0
- package/dist/infrastructure/agent-sdk/tool-calling-model-client.js +1 -1
- package/dist/infrastructure/cache/cache-policy.d.ts +2 -0
- package/dist/infrastructure/cache/cache-policy.js +1 -1
- package/dist/infrastructure/cache/file-cache-store.d.ts +8 -0
- package/dist/infrastructure/cache/file-cache-store.js +2 -2
- package/dist/infrastructure/clipboard/clipboard-constants.d.ts +1 -0
- package/dist/infrastructure/clipboard/clipboard-constants.js +1 -0
- package/dist/infrastructure/clipboard/image-normalizer.js +1 -1
- package/dist/infrastructure/extensions/extensions-constants.d.ts +6 -0
- package/dist/infrastructure/extensions/extensions-constants.js +1 -0
- package/dist/infrastructure/extensions/mcp-runtime.d.ts +7 -0
- package/dist/infrastructure/extensions/mcp-runtime.js +1 -1
- package/dist/infrastructure/extensions/plugin-manager.js +2 -2
- package/dist/infrastructure/extensions/skill-tool-executor.d.ts +3 -1
- package/dist/infrastructure/extensions/skill-tool-executor.js +2 -2
- package/dist/infrastructure/filesystem/atomic-file-store.d.ts +11 -0
- package/dist/infrastructure/filesystem/atomic-file-store.js +1 -1
- package/dist/infrastructure/filesystem/filesystem-constants.d.ts +8 -0
- package/dist/infrastructure/filesystem/filesystem-constants.js +1 -0
- package/dist/infrastructure/filesystem/local-filesystem-tool-executor.d.ts +3 -0
- package/dist/infrastructure/filesystem/local-filesystem-tool-executor.js +3 -3
- package/dist/infrastructure/logging/daily-rotating-file-writer.d.ts +1 -1
- package/dist/infrastructure/logging/daily-rotating-file-writer.js +2 -2
- package/dist/infrastructure/logging/log-redactor.js +1 -1
- package/dist/infrastructure/logging/logging-constants.d.ts +3 -0
- package/dist/infrastructure/logging/logging-constants.js +1 -0
- package/dist/infrastructure/logging/structured-logger.d.ts +1 -1
- package/dist/infrastructure/logging/structured-logger.js +2 -2
- package/dist/infrastructure/observability/tool-execution-logger.d.ts +11 -0
- package/dist/infrastructure/observability/tool-execution-logger.js +1 -0
- package/dist/infrastructure/platform/host-platform.d.ts +2 -0
- package/dist/infrastructure/platform/host-platform.js +1 -1
- package/dist/infrastructure/platform/host-process.d.ts +3 -1
- package/dist/infrastructure/platform/host-process.js +1 -1
- package/dist/infrastructure/platform/platform-constants.d.ts +4 -0
- package/dist/infrastructure/platform/platform-constants.js +1 -0
- package/dist/infrastructure/platform/process-identity.d.ts +8 -0
- package/dist/infrastructure/platform/process-identity.js +1 -0
- package/dist/infrastructure/platform/read-only-executable.d.ts +2 -1
- package/dist/infrastructure/platform/read-only-executable.js +1 -1
- package/dist/infrastructure/sdk/lotagate-client-factory.js +1 -1
- package/dist/infrastructure/sdk/sdk-media-gateway-client.d.ts +4 -0
- package/dist/infrastructure/sdk/sdk-media-gateway-client.js +1 -1
- package/dist/infrastructure/sessions/file-session-store.d.ts +3 -0
- package/dist/infrastructure/sessions/file-session-store.js +4 -4
- package/dist/infrastructure/sessions/session-constants.d.ts +3 -0
- package/dist/infrastructure/sessions/session-constants.js +1 -0
- package/dist/infrastructure/sessions/session-index.js +3 -3
- package/dist/infrastructure/sessions/session-journal-health.d.ts +7 -0
- package/dist/infrastructure/sessions/session-journal-health.js +1 -0
- package/dist/infrastructure/shell/shell-tool-executor.d.ts +5 -1
- package/dist/infrastructure/shell/shell-tool-executor.js +2 -2
- package/dist/infrastructure/tokens/tiktoken-token-estimator.js +1 -1
- package/dist/infrastructure/tokens/token-constants.d.ts +1 -0
- package/dist/infrastructure/tokens/token-constants.js +1 -0
- package/dist/infrastructure/workspace/workspace-settings-store.d.ts +1 -0
- package/dist/infrastructure/workspace/workspace-settings-store.js +4 -4
- package/dist/main.js +3 -3
- package/dist/ports/media-gateway-client.d.ts +6 -0
- package/dist/ports/session-store.d.ts +1 -0
- package/dist/presentation/tui/ink/components/composer.js +4 -4
- package/dist/presentation/tui/ink/components/transcript.d.ts +1 -0
- package/dist/presentation/tui/ink/components/transcript.js +5 -5
- package/dist/presentation/tui/ink/tui-bridge.d.ts +2 -2
- package/dist/presentation/tui/ink/tui-bridge.js +1 -1
- package/dist/presentation/tui/tui-agent-turn-controller.d.ts +45 -0
- package/dist/presentation/tui/tui-agent-turn-controller.js +1 -0
- package/dist/presentation/tui/tui-application-contract.d.ts +1 -0
- package/dist/presentation/tui/tui-application.d.ts +1 -4
- package/dist/presentation/tui/tui-application.js +3 -3
- package/dist/presentation/tui/tui-clipboard-paste-handlers.d.ts +2 -2
- package/dist/presentation/tui/tui-clipboard-paste-handlers.js +1 -1
- package/dist/presentation/tui/tui-command-executor.js +3 -3
- package/dist/presentation/tui/tui-context-compaction.d.ts +4 -1
- package/dist/presentation/tui/tui-context-compaction.js +1 -1
- package/dist/presentation/tui/tui-context-service.d.ts +2 -34
- package/dist/presentation/tui/tui-context-service.js +1 -2
- package/dist/presentation/tui/tui-initial-model.js +1 -1
- package/dist/presentation/tui/tui-tool-approval.d.ts +1 -1
- package/dist/presentation/tui/tui-tool-approval.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/native-targets.mjs +1 -1
- package/package.json +9 -10
- package/scripts/install-native.mjs +5 -13
- package/bin/lotagate.exe +0 -1
- package/dist/application/protocol/document-host-tool-definitions.d.ts +0 -4
- package/dist/application/protocol/document-host-tool-definitions.js +0 -1
- package/dist/application/protocol/document-host-tool-executor.d.ts +0 -49
- package/dist/application/protocol/document-host-tool-executor.js +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthenticationService as i}from"../auth/authentication-service.js";import{createLotaGateClient as r}from"../../infrastructure/sdk/lotagate-client-factory.js";import{ModelCatalogAdapter as c}from"../../infrastructure/sdk/model-catalog-adapter.js";import{loadExecutionConfig as d}from"../config/execution-config.js";import{CachedModelCatalog as f,modelCatalogCacheKey as n}from"./cached-model-catalog.js";async function
|
|
1
|
+
import{AuthenticationService as i}from"../auth/authentication-service.js";import{createLotaGateClient as r}from"../../infrastructure/sdk/lotagate-client-factory.js";import{ModelCatalogAdapter as c}from"../../infrastructure/sdk/model-catalog-adapter.js";import{loadExecutionConfig as d}from"../config/execution-config.js";import{CachedModelCatalog as f,modelCatalogCacheKey as n}from"./cached-model-catalog.js";async function w(o,e,l=!1){const t=(await d(o,e)).config.profile??i.defaultProfileName(),a=await o.auth.requireCredential(t);return new f(new c(r(a.profile,a.apiKey)),o.cache,n(a.profile.name,a.profile.baseUrl),o.cachePolicy.modelCatalogTtlMs,o.modelCatalogInFlight).listModels(l)}export{w as loadModelCatalog};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthenticationService as d}from"../auth/authentication-service.js";import{CachedModelCatalog as c,modelCatalogCacheKey as f}from"./cached-model-catalog.js";import{createLotaGateClient as s}from"../../infrastructure/sdk/lotagate-client-factory.js";import{getModelContextWindow as g,ModelCatalogAdapter as p}from"../../infrastructure/sdk/model-catalog-adapter.js";async function M(
|
|
1
|
+
import{AuthenticationService as d}from"../auth/authentication-service.js";import{CachedModelCatalog as c,modelCatalogCacheKey as f}from"./cached-model-catalog.js";import{createLotaGateClient as s}from"../../infrastructure/sdk/lotagate-client-factory.js";import{getModelContextWindow as g,ModelCatalogAdapter as p}from"../../infrastructure/sdk/model-catalog-adapter.js";async function M(e,t,r){if(t===null||t.trim().length===0)return;const l=r??d.defaultProfileName(),o=await e.credentialStore.get(l);if(o!==void 0)try{const a=(await new c(new p(s(o.profile,o.apiKey)),e.cache,f(o.profile.name,o.profile.baseUrl),e.cachePolicy.modelCatalogTtlMs,e.modelCatalogInFlight).listModels()).data.find(i=>i.id===t);return a===void 0?void 0:g(a)}catch(n){e.logger.debug("Unable to load model context window.",{model:t,reason:n instanceof Error?n.message:String(n)});return}}export{M as resolveModelContextWindow};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** Shared bounded retry budget for transient model-response failures. */
|
|
2
2
|
export declare const MODEL_RESPONSE_MAX_RETRIES = 3;
|
|
3
3
|
export interface ModelStreamRetryOptions<T> {
|
|
4
4
|
readonly create: () => Promise<AsyncIterable<T>> | AsyncIterable<T>;
|
|
@@ -7,3 +7,9 @@ export interface ModelStreamRetryOptions<T> {
|
|
|
7
7
|
}
|
|
8
8
|
export declare function retryModelStream<T>(options: ModelStreamRetryOptions<T>): AsyncIterable<T>;
|
|
9
9
|
export declare function isRetryableModelResponseError(error: unknown): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Tool-result follow-ups may be rejected transiently by an upstream model
|
|
12
|
+
* provider. This predicate is intentionally separate from stream retries so
|
|
13
|
+
* ordinary initial requests do not retry provider validation failures.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isRetryableToolResultFollowUpError(error: unknown): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{SdkErrorCode as
|
|
1
|
+
import{SdkErrorCode as i}from"@lotagate/sdk";const s=3;async function*R(e){let t=0;for(;;){let o=!1;try{const r=await e.create();for await(const n of r)e.isObservable(n)&&(o=!0),yield n;return}catch(r){if(!a(r)||o||e.signal?.aborted===!0||t>=s)throw r;t+=1}}}function a(e){return l(e)===i.ResponseParseError}function c(e){return a(e)||l(e)==="UPSTREAM_PROVIDER_ERROR"}function l(e){if(!(typeof e!="object"||e===null||!("errorCode"in e)))return e.errorCode}export{s as MODEL_RESPONSE_MAX_RETRIES,a as isRetryableModelResponseError,c as isRetryableToolResultFollowUpError,R as retryModelStream};
|
|
@@ -19,6 +19,7 @@ export interface CliSubagentServiceOptions {
|
|
|
19
19
|
displayName: string;
|
|
20
20
|
model: string;
|
|
21
21
|
mode: SubagentMode;
|
|
22
|
+
signal: AbortSignal;
|
|
22
23
|
writeScope?: readonly string[];
|
|
23
24
|
onAction?: (action: SubagentLastAction) => void;
|
|
24
25
|
onUsage?: (summary: ModelCallSummary) => void;
|
|
@@ -36,6 +37,7 @@ interface SubagentJob {
|
|
|
36
37
|
readonly displayName: string;
|
|
37
38
|
readonly parentSessionId: string;
|
|
38
39
|
readonly controller: AbortController;
|
|
40
|
+
readonly lifecycle?: SubagentLifecycleObserver;
|
|
39
41
|
promise: Promise<SubagentResult>;
|
|
40
42
|
result?: SubagentResult;
|
|
41
43
|
}
|
|
@@ -52,6 +54,8 @@ export declare class SubagentJobRegistry {
|
|
|
52
54
|
ensureCapacity(): void;
|
|
53
55
|
/** Cancels and observes session-owned background work before the TUI exits. */
|
|
54
56
|
close(): Promise<void>;
|
|
57
|
+
/** Cancels and removes jobs belonging to a deleted durable session. */
|
|
58
|
+
closeSession(sessionId: string): Promise<void>;
|
|
55
59
|
}
|
|
56
60
|
/** Executes least-privileged, bounded child agents and supports resumable background jobs. */
|
|
57
61
|
export declare class DefaultCliSubagentService implements CliSubagentService {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import R from"node:crypto";import{waitWithSignal as
|
|
1
|
+
import R from"node:crypto";import{waitWithSignal as A}from"./abortable-wait.js";import{AgentSdkError as L,AgentSdkErrorCode as M}from"@lotagate/agent-sdk";import{SubagentCoordinator as x}from"./subagent-coordinator.js";import{SubagentJournalStore as B}from"../../infrastructure/sessions/subagent-journal-store.js";import{RESOURCE_LIMITS as u}from"../../domain/runtime/resource-limits.js";import{parseSubagentHandoff as $,SUBAGENT_HANDOFF_GUIDANCE as U}from"./subagent-handoff.js";import{subagentDisplayName as J}from"../../domain/orchestration/subagent-identity.js";import{CliError as j}from"../../domain/errors/cli-error.js";import{formatMcpActivityName as _}from"../agent/tool-display.js";class W{jobs=new Map;activeJobs=0;nextDisplayName=0;closed=!1;lifecycle;setLifecycleObserver(e){this.lifecycle=e}notifyLifecycle(e){const n=this.jobs.get(e.id)?.lifecycle??this.lifecycle;Promise.resolve(n?.onSubagentLifecycle(e)).catch(()=>{})}allocateDisplayName(){return J(this.nextDisplayName++)}ensureCapacity(){if(this.closed)throw new Error("The subagent job registry is closed.");for(;this.jobs.size>=u.subagentMaxRetainedJobs;){const e=[...this.jobs.entries()].find(([,n])=>n.result!==void 0);if(e===void 0)throw new Error("The subagent job registry is full; wait for an existing job before starting another.");this.jobs.delete(e[0])}}async close(){if(this.closed)return;this.closed=!0;const e=[...this.jobs.values()].filter(n=>n.result===void 0);for(const n of e)n.controller.abort(new Error("Interactive session is closing."));await Promise.allSettled(e.map(n=>n.promise))}async closeSession(e){const n=[...this.jobs.values()].filter(o=>o.parentSessionId===e&&o.result===void 0);for(const o of n)o.controller.abort(new Error("The owning session was deleted."));await Promise.allSettled(n.map(o=>o.promise));for(const[o,s]of this.jobs)s.parentSessionId===e&&this.jobs.delete(o)}}class ce{options;coordinator=new x;journal;jobs;constructor(e){this.options=e,this.journal=new B(e.runtime.paths),this.jobs=e.jobs??new W,e.lifecycle!==void 0&&this.jobs.setLifecycleObserver(e.lifecycle)}async spawn(e,n){const o=O(e),s=this.resolveModel(o.model),i=R.randomUUID();this.jobs.ensureCapacity();const c=this.jobs.allocateDisplayName();if(this.jobs.activeJobs>=u.subagentMaxConcurrent)throw new Error("The maximum number of concurrent subagents is already running.");this.jobs.activeJobs+=1;const g=o.background?new AbortController:F(n.signal);o.background&&n.signal?.aborted&&g.abort(n.signal.reason);const d={id:i,displayName:c,parentSessionId:n.sessionId,controller:g,...this.options.lifecycle===void 0?{}:{lifecycle:this.options.lifecycle},promise:Promise.resolve(E(i,c,o,s))};this.jobs.jobs.set(i,d),this.notifyLifecycle({type:"created",sessionId:n.sessionId,id:i,displayName:d.displayName,task:o.task,mode:o.mode,model:s,status:"queued",background:o.background,timestamp:Date.now()}),this.options.runtime.logger.info?.("Subagent created.",{subagentId:i,displayName:c,mode:o.mode,model:s,background:o.background});const f=this.execute(i,c,o,s,n,g.signal).then(r=>(d.result=r,this.notifyLifecycle({type:V(r.status),sessionId:n.sessionId,id:i,displayName:d.displayName,task:o.task,mode:o.mode,model:s,status:r.status,background:o.background,timestamp:Date.now(),durationMs:r.durationMs,summary:r.summary,handoff:r.handoff}),this.options.runtime.logger.info?.("Subagent finished.",{subagentId:i,displayName:c,status:r.status,toolCount:r.toolsUsed.length,...r.limitReason===void 0?{}:{limitReason:r.limitReason}}),r)).finally(()=>{this.jobs.activeJobs-=1,G(g)});return d.promise=f,o.background?E(i,c,o,s):f}async wait(e,n){return A((await this.ownedJob(e,n)).promise,n.signal)}async cancel(e,n){const o=await this.ownedJob(e,n);return o.controller.abort(),o.promise}async execute(e,n,o,s,i,c){const g=Date.now(),d=o.mode??"research";await this.writeJournal(i.sessionId,{recordType:"created",id:e,displayName:n,task:o.task,mode:d,model:s,timestamp:new Date().toISOString()}),await this.writeJournal(i.sessionId,{recordType:"started",id:e,displayName:n,mode:d,model:s,timestamp:new Date().toISOString()}),this.notifyLifecycle({type:"started",sessionId:i.sessionId,id:e,displayName:n,task:o.task,mode:d,model:s,status:"running",background:o.background??!1,timestamp:Date.now()});try{const f={id:e,title:d==="research"?"Research task":"Worker task",description:z(o),dependencies:[],status:"queued"},a=(await this.coordinator.run({tasks:[f],requiresApproval:!1,maxConcurrency:1},{create:async y=>this.createInstance(y,n,s,d,o,i,c)},Z(),c))[0]?.output;if(a===void 0)throw new Error("The subagent completed without a result.");const m=a.limitReason,p=X($(a.content),m),h=m===void 0?"completed":"completed_with_warning",w={id:e,displayName:n,task:o.task,status:h,mode:d,model:s,summary:p.summary,handoff:p,toolsUsed:a.toolsUsed??[],...a.tokensEstimated===!0&&a.tokens!==void 0?{estimatedTokens:a.tokens}:{},...m===void 0?{}:{limitReason:m},durationMs:Date.now()-g};return await this.writeJournal(i.sessionId,{recordType:h,result:w,timestamp:new Date().toISOString()}),w}catch(f){const r=c.aborted,a=r?void 0:D(f),m={summary:r?"Subagent cancelled.":a===void 0?f instanceof Error?f.message:String(f):`Subagent stopped after reaching its ${S(a)} limit.`,filesInspected:[],filesChanged:[],commandsRun:[],verification:[],warnings:[r?"The child was cancelled before completing.":a===void 0?"The child failed before producing a verified handoff.":`The child reached its ${S(a)} limit before producing a verified handoff.`]},p=r?"cancelled":a===void 0?"failed":"completed_with_warning",h={id:e,displayName:n,task:o.task,status:p,mode:d,model:s,summary:m.summary,handoff:m,toolsUsed:[],...a===void 0?{}:{limitReason:a},durationMs:Date.now()-g};return await this.writeJournal(i.sessionId,{recordType:p,result:h,timestamp:new Date().toISOString()}),h}}async createInstance(e,n,o,s,i,c,g){const d=p=>{this.notifyLifecycle({type:"activity",sessionId:c.sessionId,id:e.id,displayName:n,task:i.task,mode:s,model:o,status:"running",background:i.background??!1,timestamp:Date.now(),lastAction:p})};let f=0,r=!1,a,m=!1;return{run:async(p,h)=>{a=await this.options.createAgent({task:e,displayName:n,model:o,mode:s,signal:h,...i.writeScope===void 0?{}:{writeScope:i.writeScope},onAction:d,onUsage:l=>{const b=l.usage;b!==void 0&&(r=!0,f+=Math.max(b.totalTokens??0,(b.promptTokens??0)+(b.completionTokens??0)))}}),await a.initialize();const w=[];let y;const I=new Set,v={input:e.description,model:o,sessionId:e.id,cwd:c.cwd??this.options.cwd,workspaceRoot:c.workspaceRoot??this.options.cwd,stream:!0,signal:h,limits:{maxIterations:u.subagentMaxIterations,maxToolCallsPerTurn:u.subagentMaxToolCallsPerTurn,maxToolArgumentBytes:u.subagentToolArgumentBytes,maxToolResultBytes:u.subagentToolResultBytes},metadata:{parentSessionId:c.sessionId,parentRunId:c.runId,subagentMode:s}};let k;try{for await(const l of a.run(v)){if(l.type==="model.delta"&&w.push(l.content),l.type==="session.completed"&&(y=l.content),l.type==="tool.called"){I.add(l.toolName);const b=K(l.toolName);b!==void 0&&d(b)}if(l.type==="session.failed")throw l.error}}catch(l){if(g.aborted||(k=h.aborted?"timeout":D(l),k===void 0))throw l}const T=H(y??w.join("")),C=r?f:Math.ceil(Buffer.byteLength(T,"utf8")/4);return{content:T,tokens:C,...r?{}:{tokensEstimated:!0},toolsUsed:[...I].sort(),...k===void 0?{}:{limitReason:k}}},close:async()=>{m||(m=!0,await a?.close())}}}resolveModel(e){const n=e??this.options.model;if(!new Set(this.options.allowedModels??[this.options.model]).has(n))throw new Error(`Subagent model is not allowed: ${n}`);return n}async ownedJob(e,n){const o=e.trim(),s=this.jobs.jobs.get(o);if(s===void 0||s.parentSessionId!==n.sessionId)throw new Error(`Subagent job not found: ${o}`);return s}async writeJournal(e,n){try{await this.journal.append(e,this.options.cwd,n)}catch(o){this.options.runtime.logger.warn("Unable to persist subagent lifecycle record.",{reason:o instanceof Error?o.message:String(o)})}}notifyLifecycle(e){this.jobs.notifyLifecycle(e)}}function O(t){const e=t.task.trim();if(e.length===0)throw new Error("agent.spawn requires a non-empty task.");if(Buffer.byteLength(e,"utf8")>u.subagentTaskBytes)throw new Error("agent.spawn task is too large.");const n=t.context?.trim();if(n!==void 0&&Buffer.byteLength(n,"utf8")>u.subagentContextBytes)throw new Error("agent.spawn context is too large.");const o=t.mode??"research",s=N(t.writeScope);if(o==="worker"&&s.length===0)throw new Error("Worker subagents require a non-empty writeScope.");if(o==="research"&&s.length>0)throw new Error("Research subagents cannot receive a writeScope.");return{...t,task:e,mode:o,background:t.background??!1,...n===void 0?{}:{context:n},...s.length===0?{}:{writeScope:s}}}function z(t){const e=t.writeScope===void 0?"":`
|
|
2
2
|
|
|
3
3
|
### Write scope
|
|
4
4
|
${t.writeScope.map(o=>`- ${o}`).join(`
|
|
@@ -9,5 +9,5 @@ ${t.context}
|
|
|
9
9
|
## Delegated task
|
|
10
10
|
${t.task}${e}`}
|
|
11
11
|
|
|
12
|
-
${
|
|
13
|
-
[truncated]`}function
|
|
12
|
+
${U}`}function N(t){if(t===void 0)return[];if(t.length>u.subagentMaxWriteScopeItems)throw new Error("agent.spawn writeScope has too many entries.");const e=t.map(n=>n.trim()).filter(Boolean);if(e.some(n=>Buffer.byteLength(n,"utf8")>u.subagentWriteScopeItemBytes))throw new Error("agent.spawn writeScope entry is too large.");if(e.some(n=>P(n)||n.split(/[\\/]/u).includes("..")))throw new Error("agent.spawn writeScope must contain workspace-relative paths without traversal.");return[...new Set(e)].sort()}function P(t){return t.startsWith("/")||/^[A-Za-z]:[\\/]/u.test(t)||t.startsWith("\\\\")}function E(t,e,n,o){const s=n.mode??"research",i={summary:"Subagent is running in the background. Call agent.wait with this id when its result is needed.",filesInspected:[],filesChanged:[],commandsRun:[],verification:[],warnings:[]};return{id:t,displayName:e,task:n.task,status:"running",mode:s,model:o,summary:i.summary,handoff:i,toolsUsed:[],durationMs:0}}function F(t){const e=new AbortController,n=()=>e.abort(t?.reason);return t?.aborted?n():t?.addEventListener("abort",n,{once:!0}),Object.assign(e,{dispose:()=>t?.removeEventListener("abort",n)})}function G(t){"dispose"in t&&t.dispose()}function H(t){const e=t.trim()||"The subagent completed without a text summary.",n=Buffer.from(e,"utf8");return n.byteLength<=u.subagentSummaryBytes?e:`${n.subarray(0,u.subagentSummaryBytes).toString("utf8")}
|
|
13
|
+
[truncated]`}function Z(){return{maxConcurrency:1,maxTasks:1,maxDurationMs:u.subagentMaxDurationMs,maxTokens:u.subagentMaxTokens}}function K(t){if(!(t.startsWith("filesystem.")||t==="shell.exec"||t.startsWith("skill.")))return{kind:"mcp",label:`Using ${Q(_(t))}`}}function Q(t){const e=t.replace(/Bearer\s+[^\s]+/giu,"Bearer [REDACTED]").replace(/sk-[A-Za-z0-9_-]{8,}/gu,"[REDACTED]");return e.length<=180?e:`${e.slice(0,177)}...`}function V(t){if(t==="completed"||t==="completed_with_warning"||t==="failed"||t==="cancelled")return t;throw new Error(`Subagent execution returned a non-terminal status: ${t}`)}function X(t,e){return e===void 0?t:{...t,warnings:[...t.warnings,`The child reached its ${S(e)} limit before full completion.`]}}function D(t){if(t instanceof L&&t.code===M.AgentLimitExceeded)return t.details?.maxToolCallsPerTurn!==void 0||/tool calls/iu.test(t.message)?"tool_calls":"iteration";if(t instanceof j&&/duration/iu.test(t.message))return"timeout";if(t instanceof j&&/token budget/iu.test(t.message))return"tokens"}function S(t){return t==="tool_calls"?"tool-call":t==="iteration"?"iteration":t==="tokens"?"token":"time"}export{ce as DefaultCliSubagentService,W as SubagentJobRegistry};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{actionDisplayName as
|
|
1
|
+
import{actionDisplayName as o,actionId as a,actionKind as i}from"./cli-turn-events.js";import{normalizeAssistantDelta as d}from"../../domain/runtime/assistant-stream-text.js";class c{openSegments=new Map;lastAssistantContents=new Map;observe(t){switch(t.type){case"session.started":return this.openSegments.delete(t.runId),this.lastAssistantContents.delete(t.runId),[{type:"turn.started",runId:t.runId,timestamp:t.timestamp}];case"model.delta":{const s=t.content.length===0?void 0:this.delta(t);return s===void 0?[]:[s]}case"tool.approval.requested":return[...this.closeOpenSegment(t.request.context.runId,"progress",t.timestamp),this.approval(t)];case"tool.called":return[...this.closeOpenSegment(t.runId,"progress",t.timestamp),this.started(t)];case"tool.completed":return[this.completed(t)];case"context.compacted":return[{type:"context.compacted",runId:t.runId,timestamp:t.timestamp}];case"session.completed":{const s=this.openSegments.get(t.runId),n=this.closeOpenSegment(t.runId,s!==void 0&&s.content===t.content?"final":"progress",t.timestamp),e=this.replacement(t);if(this.lastAssistantContents.delete(t.runId),e!==void 0)return[...n,e,this.completedSegment(e,t.timestamp),{type:"turn.completed",runId:t.runId,timestamp:t.timestamp}];if(n.length>0)return[...n,{type:"turn.completed",runId:t.runId,timestamp:t.timestamp}];if(t.content.length===0)return[{type:"turn.completed",runId:t.runId,timestamp:t.timestamp}];const r=`${t.runId}:final`;return[{type:"assistant.delta",runId:t.runId,segmentId:r,iteration:0,content:t.content,timestamp:t.timestamp},{type:"assistant.segment.completed",runId:t.runId,segmentId:r,iteration:0,phase:"final",timestamp:t.timestamp},{type:"turn.completed",runId:t.runId,timestamp:t.timestamp}]}case"session.failed":return this.lastAssistantContents.delete(t.runId),[...this.closeOpenSegment(t.runId,"progress",t.timestamp),{type:"turn.failed",runId:t.runId,error:t.error,timestamp:t.timestamp}];default:return[]}}delta(t){const s=`${t.runId}:${t.iteration}`,n=this.openSegments.get(t.runId),e=n?.segmentId===s?n.content:"",r=d(e,t.content);if(r.length===0)return;const m=`${e}${r}`;return this.openSegments.set(t.runId,{segmentId:s,iteration:t.iteration,content:m}),this.lastAssistantContents.set(t.runId,m),{type:"assistant.delta",runId:t.runId,segmentId:s,iteration:t.iteration,content:r,timestamp:t.timestamp}}replacement(t){const s=this.lastAssistantContents.get(t.runId);if(!(s===void 0||t.content.length===0||s===t.content))return{type:"assistant.replaced",runId:t.runId,segmentId:`${t.runId}:final`,iteration:0,content:t.content,timestamp:t.timestamp}}completedSegment(t,s){return{type:"assistant.segment.completed",runId:t.runId,segmentId:t.segmentId,iteration:t.iteration,phase:"final",timestamp:s}}closeOpenSegment(t,s,n){const e=this.openSegments.get(t);return e===void 0?[]:(this.openSegments.delete(t),[{type:"assistant.segment.completed",runId:t,segmentId:e.segmentId,iteration:e.iteration,phase:s,timestamp:n}])}approval(t){const s=t.request;return{type:"action.approval_requested",actionId:a(s.context.runId,s.toolName),runId:s.context.runId,toolName:s.toolName,displayName:o(s.toolName),kind:i(s.toolName,s.toolInfo?.source),timestamp:t.timestamp}}started(t){return{type:"action.started",actionId:a(t.runId,t.toolName),runId:t.runId,toolName:t.toolName,displayName:o(t.toolName),kind:i(t.toolName,t.source),...t.source===void 0?{}:{source:t.source},timestamp:t.timestamp}}completed(t){return{type:"action.completed",actionId:a(t.runId,t.toolName),runId:t.runId,toolName:t.toolName,displayName:o(t.toolName),kind:i(t.toolName,t.source),status:t.isError?"failed":"completed",isError:t.isError,timestamp:t.timestamp}}}export{c as CliTurnEventProjector};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { AgentEvent } from '@lotagate/agent-sdk';
|
|
2
1
|
export type CliActionKind = 'filesystem' | 'shell' | 'mcp' | 'skill' | 'subagent' | 'other';
|
|
3
2
|
export type CliActionStatus = 'waiting_approval' | 'running' | 'completed' | 'failed';
|
|
4
3
|
export type AssistantSegmentPhase = 'progress' | 'final';
|
|
@@ -75,9 +74,3 @@ export declare function isDurableTurnEvent(event: CliTurnEvent): boolean;
|
|
|
75
74
|
export declare function toSafeTurnEventData(event: CliTurnEvent): Record<string, unknown>;
|
|
76
75
|
/** Produces the only error text permitted in durable turn state or model-facing history. */
|
|
77
76
|
export declare function safeTurnFailureMessage(error: unknown): string;
|
|
78
|
-
export type ActionEvent = Extract<CliTurnEvent, {
|
|
79
|
-
type: 'action.started' | 'action.completed' | 'action.approval_requested';
|
|
80
|
-
}>;
|
|
81
|
-
export type ProjectableAgentEvent = Extract<AgentEvent, {
|
|
82
|
-
type: 'session.started' | 'model.delta' | 'tool.approval.requested' | 'tool.called' | 'tool.completed' | 'context.compacted' | 'session.completed' | 'session.failed';
|
|
83
|
-
}>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type CreateGoalInput } from '../../domain/orchestration/goal.js';
|
|
2
2
|
export declare function parseGoalInput(objective: string, flags: ReadonlyMap<string, string | boolean>): CreateGoalInput;
|
|
3
3
|
export declare function parseGoalLimits(flags: ReadonlyMap<string, string | boolean>): Omit<CreateGoalInput, 'objective'>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getPositiveIntegerFlag as e}from"../commands/cli-args.js";import{RESOURCE_LIMITS as a}from"../../domain/runtime/resource-limits.js";function
|
|
1
|
+
import{getPositiveIntegerFlag as e}from"../commands/cli-args.js";import{RESOURCE_LIMITS as a}from"../../domain/runtime/resource-limits.js";import{validateGoalInput as i}from"../../domain/orchestration/goal.js";function M(n,t){return i({objective:n,maxTurns:a.goalDefaultMaxTurns,maxDurationMs:a.goalDefaultMaxDurationMs,...m(t)})}function m(n){const t=u(n,"token-budget"),o=u(n,"max-turns"),r=u(n,"max-duration-ms");return{...t===void 0?{}:{tokenBudget:t},...o===void 0?{}:{maxTurns:o},...r===void 0?{}:{maxDurationMs:r}}}function u(n,t){const o=t==="max-duration-ms"?a.goalMaximumMaxDurationMs:t==="max-turns"?a.goalMaximumMaxTurns:a.goalMaximumTokenBudget;return e(n,t,o)}export{M as parseGoalInput,m as parseGoalLimits};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{prepareCliAgent as
|
|
2
|
-
`):t.type==="session.completed"&&r.length===0&&r.push(t.content),t.type==="session.failed"){if(
|
|
1
|
+
import{prepareCliAgent as h}from"../agent/cli-agent-execution-service.js";import{AgentRunTracker as w}from"../agent/agent-run-tracker.js";import{CliError as C}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as c}from"../../domain/errors/error-codes.js";import{writeStreamChunk as m}from"../commands/stream-output.js";import{CliTurnEventProjector as S}from"./cli-turn-event-projector.js";import{persistCliTurnEvent as p}from"./cli-turn-persistence.js";import{agentLimitNotice as I,classifyAgentLimit as y}from"../agent/agent-limit.js";import{buildUserMessage as E}from"../../infrastructure/clipboard/image-normalizer.js";import{createContextManagement as x}from"../agent/context-compaction.js";import{persistContextCompaction as M}from"../agent/context-compaction-persistence.js";import{resolveModelContextWindow as b}from"../model/model-context-window.js";import{formatContinuationCheckpoint as v}from"../agent/continuation-checkpoint.js";async function H(e){const s=new w,u=await b(e.runtime,e.model,e.profileName),i=await h({runtime:e.runtime,projectRoot:e.cwd,executionCwd:e.cwd,model:e.model,...e.reasoningEffort===void 0?{}:{reasoningEffort:e.reasoningEffort},client:e.client,profile:"headless-safe",approvalMode:"auto",...e.goal===void 0?{}:{goal:e.goal},...e.agentSessionStore===void 0?{}:{agentSessionStore:e.agentSessionStore},onModelComplete:n=>{s.observeModel(n),n.usage!==void 0&&e.onUsage?.({usage:n.usage,modelCalls:1})},...e.onSubagentUsage===void 0?{}:{onSubagentModelComplete:n=>{n.usage!==void 0&&e.onSubagentUsage?.({usage:n.usage,modelCalls:1})}},contextManagement:x({client:e.client,model:e.model,...u===void 0?{}:{contextWindow:u},onSummaryFailure:n=>e.runtime.logger.warn("Context summarization failed; using fallback summary.",{reason:n instanceof Error?n.message:String(n)}),continuationContext:()=>v({snapshot:s.snapshot(),...e.goal===void 0?{}:{goal:e.goal}})})}),r=[];let d;const g=new S;try{const n=await i.buildInput(e.prompt);if(e.agentSessionStore!==void 0&&e.sessionId!==void 0){const t=await e.runtime.sessionStore.readHistory(e.sessionId);e.agentSessionStore.hydrate(e.sessionId,t.transcript,t.events,n.input)}const l=e.attachments===void 0||e.attachments.length===0?void 0:E(n.input,e.attachments),f=l?.content===null?void 0:l?.content;for await(const t of i.run({input:n.input,userInput:n.userInput,...n.workspaceContext===void 0?{}:{workspaceContext:n.workspaceContext},...f===void 0?{}:{inputContent:f},model:e.model,...e.signal===void 0?{}:{signal:e.signal},...e.sessionId===void 0?{}:{sessionId:e.sessionId}})){s.observe(t);for(const a of g.observe(t)){if(e.sessionId!==void 0)try{await p(e.runtime.sessionStore,e.sessionId,a,{...e.turnId===void 0?{}:{turnId:e.turnId}})}catch(o){e.runtime.logger.warn("Unable to persist agent lifecycle event.",{eventType:a.type,reason:o instanceof Error?o.message:String(o)})}a.type==="assistant.delta"&&r.push(a.content),a.type==="assistant.replaced"&&r.splice(0,r.length,a.content)}if(e.output!==void 0&&e.json?await m(e.output,`${JSON.stringify(t)}
|
|
2
|
+
`):t.type==="session.completed"&&r.length===0&&r.push(t.content),t.type==="session.failed"){if(d=y(t.error),d===void 0)throw t.error;break}t.type==="context.compacted"&&e.sessionId!==void 0&&await M(e.runtime,i,e.sessionId,t.metrics,e.turnId)}if(d!==void 0){const t=I(d);r.push(r.length===0?t:`
|
|
3
3
|
|
|
4
|
-
${t}`),e.sessionId!==void 0&&e.agentSessionStore?.delete(e.sessionId)}if(r.join("").trim().length===0){const a=
|
|
4
|
+
${t}`),e.sessionId!==void 0&&e.agentSessionStore?.delete(e.sessionId)}if(r.join("").trim().length===0){const a=s.snapshot().toolCalls>0?c.MODEL_EMPTY_FINAL:c.MODEL_PROTOCOL_EMPTY_RESPONSE;throw new C(a,"Agent completed without a final text response.",{category:"model",userMessage:"The model completed without a final text response.",retryable:!0})}return e.output!==void 0&&!e.json&&await m(e.output,r.join("")),r.join("")}finally{e.onSnapshot?.(s.snapshot());try{await i.close()}catch(n){e.runtime.logger.warn("Agent cleanup failed after a completed turn.",{reason:n instanceof Error?n.message:String(n)})}}}export{H as runHeadlessAgentTurn};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const n=32,e=1024,s=["summary","filesInspected","filesChanged","commandsRun","verification","warnings"];export{s as HANDOFF_FIELDS,n as MAX_HANDOFF_ITEMS,e as MAX_ITEM_BYTES};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{RESOURCE_LIMITS as m}from"../../domain/runtime/resource-limits.js";import{findUnexpectedRecordKey as l}from"../../domain/validation/record-schema.js";
|
|
2
|
-
`);function
|
|
3
|
-
[truncated]`}export{
|
|
1
|
+
import{RESOURCE_LIMITS as m}from"../../domain/runtime/resource-limits.js";import{findUnexpectedRecordKey as l}from"../../domain/validation/record-schema.js";import{HANDOFF_FIELDS as c,MAX_HANDOFF_ITEMS as y,MAX_ITEM_BYTES as u}from"./orchestration-constants.js";const w=["## Handoff contract","When complete, return exactly one JSON object with only these fields: summary (string), filesInspected (string[]), filesChanged (string[]), commandsRun (string[]), verification (string[]), and warnings (string[]).","Return no markdown, code fences, or explanatory text outside the JSON object."].join(`
|
|
2
|
+
`);function E(e){const n=x(e,m.subagentSummaryBytes),t=b(n);return t===void 0||!p(t)?h(n):g(t)}function p(e){return l(e,c)!==void 0||!c.every(n=>Object.prototype.hasOwnProperty.call(e,n))||o(e.summary)===void 0?!1:c.slice(1).every(n=>{const t=e[n];return Array.isArray(t)&&t.every(r=>typeof r=="string"&&o(r)!==void 0)})}function g(e){return{summary:o(e.summary)??"The subagent completed without a text summary.",filesInspected:f(e.filesInspected),filesChanged:f(e.filesChanged),commandsRun:f(e.commandsRun),verification:f(e.verification),warnings:f(e.warnings)}}function h(e){return{summary:e||"The subagent completed without a text summary.",filesInspected:[],filesChanged:[],commandsRun:[],verification:[],warnings:["The child returned an unstructured or invalid handoff; verify the result directly."]}}function b(e){const n=[e.trim(),...S(e)];for(const t of n)if(!(t===void 0||t.length===0))try{const r=JSON.parse(t);if(r!==null&&typeof r=="object"&&!Array.isArray(r))return r}catch{}}function S(e){const n=[];for(let t=e.indexOf("{");t>=0;t=e.indexOf("{",t+1)){let r=0,d=!1,a=!1;for(let s=t;s<e.length;s+=1){const i=e[s];if(d){a?a=!1:i==="\\"?a=!0:i==='"'&&(d=!1);continue}if(i==='"')d=!0;else if(i==="{")r+=1;else if(i==="}"&&--r===0){n.push(e.slice(t,s+1));break}}}return n}function f(e){return Array.isArray(e)?e.filter(n=>typeof n=="string").map(n=>o(n)).filter(n=>n!==void 0).slice(0,y):[]}function o(e){if(typeof e!="string")return;const n=e.trim();if(n.length!==0)return Buffer.byteLength(n,"utf8")<=u?n:`${Buffer.from(n,"utf8").subarray(0,u-3).toString("utf8")}...`}function x(e,n){const t=e.trim(),r=Buffer.from(t,"utf8");return r.byteLength<=n?t:`${r.subarray(0,n-16).toString("utf8")}
|
|
3
|
+
[truncated]`}export{w as SUBAGENT_HANDOFF_GUIDANCE,E as parseSubagentHandoff};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export type ProjectMarker = {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly markers: readonly string[];
|
|
4
|
+
readonly extensions: readonly string[];
|
|
5
|
+
};
|
|
6
|
+
export type FrameworkMarker = {
|
|
7
|
+
readonly label: string;
|
|
8
|
+
readonly packages?: readonly string[];
|
|
9
|
+
readonly files?: readonly string[];
|
|
10
|
+
};
|
|
11
|
+
export declare const CONFIG_FILE_NAMES: readonly ["package.json", "tsconfig.json", "jsconfig.json", "pyproject.toml", "setup.cfg", "setup.py", "requirements.txt", "Pipfile", "Cargo.toml", "go.mod", "pom.xml", "build.gradle", "build.gradle.kts", "Gemfile", "composer.json", "Makefile", "CMakeLists.txt", "Dockerfile", "vitest.config.ts", "vitest.config.js", "jest.config.ts", "jest.config.js", "playwright.config.ts", "playwright.config.js", "pytest.ini", "tox.ini", "eslint.config.mjs", "vite.config.ts", "electron.vite.config.ts", "pnpm-workspace.yaml", "turbo.json"];
|
|
12
|
+
export declare const PROJECT_MARKERS: readonly ProjectMarker[];
|
|
13
|
+
export declare const FRAMEWORK_MARKERS: readonly FrameworkMarker[];
|
|
14
|
+
export declare const PACKAGE_MANAGERS: readonly [readonly ["package-lock.json", "npm"], readonly ["pnpm-lock.yaml", "pnpm"], readonly ["yarn.lock", "Yarn"], readonly ["bun.lockb", "Bun"], readonly ["bun.lock", "Bun"], readonly ["uv.lock", "uv"], readonly ["poetry.lock", "Poetry"], readonly ["Pipfile.lock", "Pipenv"], readonly ["Cargo.lock", "Cargo"], readonly ["go.sum", "Go modules"], readonly ["Gemfile.lock", "Bundler"], readonly ["composer.lock", "Composer"]];
|
|
15
|
+
export declare const SOURCE_ROOT_NAMES: readonly ["src", "app", "lib", "test", "tests", "packages", "apps", "cmd", "internal", "pkg", "crates", "components"];
|
|
16
|
+
export declare const TEST_RUNNER_MARKERS: readonly [{
|
|
17
|
+
readonly label: "Vitest";
|
|
18
|
+
readonly packages: readonly ["vitest"];
|
|
19
|
+
readonly scriptTokens: readonly ["vitest"];
|
|
20
|
+
readonly files: readonly ["vitest.config.ts", "vitest.config.js"];
|
|
21
|
+
}, {
|
|
22
|
+
readonly label: "Jest";
|
|
23
|
+
readonly packages: readonly ["jest"];
|
|
24
|
+
readonly scriptTokens: readonly ["jest"];
|
|
25
|
+
readonly files: readonly ["jest.config.ts", "jest.config.js"];
|
|
26
|
+
}, {
|
|
27
|
+
readonly label: "Playwright";
|
|
28
|
+
readonly packages: readonly ["@playwright/test"];
|
|
29
|
+
readonly scriptTokens: readonly ["playwright"];
|
|
30
|
+
readonly files: readonly ["playwright.config.ts", "playwright.config.js"];
|
|
31
|
+
}, {
|
|
32
|
+
readonly label: "pytest";
|
|
33
|
+
readonly packages: readonly [];
|
|
34
|
+
readonly scriptTokens: readonly ["pytest"];
|
|
35
|
+
readonly files: readonly ["pytest.ini", "tox.ini"];
|
|
36
|
+
}, {
|
|
37
|
+
readonly label: "Cargo test";
|
|
38
|
+
readonly packages: readonly [];
|
|
39
|
+
readonly scriptTokens: readonly [];
|
|
40
|
+
readonly files: readonly ["Cargo.toml"];
|
|
41
|
+
}, {
|
|
42
|
+
readonly label: "Go test";
|
|
43
|
+
readonly packages: readonly [];
|
|
44
|
+
readonly scriptTokens: readonly [];
|
|
45
|
+
readonly files: readonly ["go.mod"];
|
|
46
|
+
}, {
|
|
47
|
+
readonly label: "Maven test";
|
|
48
|
+
readonly packages: readonly [];
|
|
49
|
+
readonly scriptTokens: readonly ["mvn", "maven"];
|
|
50
|
+
readonly files: readonly ["pom.xml"];
|
|
51
|
+
}, {
|
|
52
|
+
readonly label: "Gradle test";
|
|
53
|
+
readonly packages: readonly [];
|
|
54
|
+
readonly scriptTokens: readonly ["gradle"];
|
|
55
|
+
readonly files: readonly ["build.gradle", "build.gradle.kts"];
|
|
56
|
+
}];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=["package.json","tsconfig.json","jsconfig.json","pyproject.toml","setup.cfg","setup.py","requirements.txt","Pipfile","Cargo.toml","go.mod","pom.xml","build.gradle","build.gradle.kts","Gemfile","composer.json","Makefile","CMakeLists.txt","Dockerfile","vitest.config.ts","vitest.config.js","jest.config.ts","jest.config.js","playwright.config.ts","playwright.config.js","pytest.ini","tox.ini","eslint.config.mjs","vite.config.ts","electron.vite.config.ts","pnpm-workspace.yaml","turbo.json"],s=[{name:"TypeScript",markers:["tsconfig.json"],extensions:[".ts",".tsx"]},{name:"JavaScript/JSX",markers:["package.json"],extensions:[".js",".jsx",".mjs",".cjs"]},{name:"Python",markers:["pyproject.toml","setup.py","requirements.txt","Pipfile"],extensions:[".py"]},{name:"Rust",markers:["Cargo.toml"],extensions:[".rs"]},{name:"Go",markers:["go.mod"],extensions:[".go"]},{name:"Java/Kotlin",markers:["pom.xml","build.gradle","build.gradle.kts"],extensions:[".java",".kt",".kts"]},{name:"Ruby",markers:["Gemfile"],extensions:[".rb"]},{name:"PHP",markers:["composer.json"],extensions:[".php"]},{name:"C/C++",markers:["CMakeLists.txt"],extensions:[".c",".h",".cc",".cpp",".cxx",".hpp"]},{name:"C#",markers:[],extensions:[".cs",".csproj",".sln"]}],t=[{label:"React",packages:["react","react-dom"]},{label:"Electron",packages:["electron"]},{label:"Vite",packages:["vite"]},{label:"Next.js",packages:["next"]},{label:"Express",packages:["express"]},{label:"Angular",packages:["@angular/core"]},{label:"Vue",packages:["vue"]},{label:"Svelte",packages:["svelte"]},{label:"Django",files:["manage.py"]},{label:"FastAPI",packages:["fastapi"]},{label:"Flask",packages:["flask"]},{label:"Rails",files:["bin/rails"]}],a=[["package-lock.json","npm"],["pnpm-lock.yaml","pnpm"],["yarn.lock","Yarn"],["bun.lockb","Bun"],["bun.lock","Bun"],["uv.lock","uv"],["poetry.lock","Poetry"],["Pipfile.lock","Pipenv"],["Cargo.lock","Cargo"],["go.sum","Go modules"],["Gemfile.lock","Bundler"],["composer.lock","Composer"]],o=["src","app","lib","test","tests","packages","apps","cmd","internal","pkg","crates","components"],l=[{label:"Vitest",packages:["vitest"],scriptTokens:["vitest"],files:["vitest.config.ts","vitest.config.js"]},{label:"Jest",packages:["jest"],scriptTokens:["jest"],files:["jest.config.ts","jest.config.js"]},{label:"Playwright",packages:["@playwright/test"],scriptTokens:["playwright"],files:["playwright.config.ts","playwright.config.js"]},{label:"pytest",packages:[],scriptTokens:["pytest"],files:["pytest.ini","tox.ini"]},{label:"Cargo test",packages:[],scriptTokens:[],files:["Cargo.toml"]},{label:"Go test",packages:[],scriptTokens:[],files:["go.mod"]},{label:"Maven test",packages:[],scriptTokens:["mvn","maven"],files:["pom.xml"]},{label:"Gradle test",packages:[],scriptTokens:["gradle"],files:["build.gradle","build.gradle.kts"]}];export{e as CONFIG_FILE_NAMES,t as FRAMEWORK_MARKERS,a as PACKAGE_MANAGERS,s as PROJECT_MARKERS,o as SOURCE_ROOT_NAMES,l as TEST_RUNNER_MARKERS};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import f from"node:fs/promises";import
|
|
1
|
+
import f from"node:fs/promises";import c from"node:path";import{CONFIG_FILE_NAMES as h,FRAMEWORK_MARKERS as g,PACKAGE_MANAGERS as R,PROJECT_MARKERS as j,SOURCE_ROOT_NAMES as k,TEST_RUNNER_MARKERS as E}from"./project-intelligence-constants.js";class J{async discover(e){const t=await P(c.join(e,"package.json")),s={...o(t?.dependencies),...o(t?.devDependencies)},a=o(t?.scripts),i=await O(e),r=await A(e),u=_(t);return{...r===void 0?{}:{packageManager:r},...u===void 0?{}:{runtime:u},languages:await b(e,t,i),frameworks:await S(e,s),scripts:a,testRunners:await F(e,s,a),sourceRoots:i,configFiles:await M(e,h)}}}async function S(n,e){const t=[];for(const s of g)(s.packages?.some(a=>e[a]!==void 0)===!0||await l(n,s.files??[]))&&t.push(s.label);return t}async function F(n,e,t){const s=Object.values(t).join(" ").toLowerCase(),a=[];for(const i of E)(i.packages.some(r=>e[r]!==void 0)||i.scriptTokens.some(r=>s.includes(r))||await l(n,i.files))&&a.push(i.label);return a}async function M(n,e){return(await Promise.all(e.map(async t=>await d(c.join(n,t))?t:void 0))).filter(t=>t!==void 0)}async function A(n){for(const[e,t]of R)if(await d(c.join(n,e)))return t}async function O(n){const e=[];for(const t of k)await d(c.join(n,t))&&e.push(t);return e}async function b(n,e,t){const s={...o(e?.dependencies),...o(e?.devDependencies)},a=[],i=await T(n,t);for(const r of j){const u=await l(n,r.markers),p=r.name==="TypeScript"?s.typescript!==void 0:r.name==="JavaScript/JSX"?Object.keys(s).length>0:!1,m=i.some(y=>r.extensions.some(w=>y.toLowerCase().endsWith(w)));(u||p||m)&&a.push(r.name)}return a.length===0?["Unknown"]:a}async function T(n,e){const t=[];for(const s of[".",...e.slice(0,8)])try{const a=await f.readdir(c.join(n,s),{withFileTypes:!0});for(const i of a.slice(0,256))i.isFile()?t.push(i.name):i.isDirectory()&&s!=="."&&t.push(...await N(c.join(n,s,i.name)))}catch{}return t}async function N(n){try{return(await f.readdir(n,{withFileTypes:!0})).slice(0,256).filter(e=>e.isFile()).map(e=>e.name)}catch{return[]}}async function l(n,e){return(await Promise.all(e.map(s=>d(c.join(n,s))))).some(Boolean)}function _(n){const e=n?.engines;return typeof e=="object"&&e!==null&&typeof e.node=="string"?`Node ${e.node}`:void 0}async function P(n){try{const e=JSON.parse(await f.readFile(n,"utf8"));return typeof e=="object"&&e!==null?e:void 0}catch{return}}async function d(n){try{return await f.access(n),!0}catch{return!1}}function o(n){return typeof n!="object"||n===null?{}:Object.fromEntries(Object.entries(n).filter(e=>typeof e[1]=="string"))}export{J as ProjectIntelligenceService};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ToolDefinition } from '@lotagate/sdk';
|
|
2
|
-
import type { ToolExecutionContext, ToolExecutor, ToolInfo, ToolResult } from '@lotagate/agent-sdk';
|
|
2
|
+
import type { ToolAuthorizationDecision, ToolApprovalRequest, ToolExecutionContext, ToolExecutor, ToolInfo, ToolResult } from '@lotagate/agent-sdk';
|
|
3
3
|
import type { ToolActivityObserver } from '../../ports/tool-activity.js';
|
|
4
4
|
export interface BrowserHostRequest {
|
|
5
5
|
version: 1;
|
|
@@ -10,8 +10,11 @@ export interface BrowserHostRequest {
|
|
|
10
10
|
runId: string;
|
|
11
11
|
action: string;
|
|
12
12
|
params: Record<string, unknown>;
|
|
13
|
-
executionBoundary: 'host';
|
|
14
|
-
hostFallback: 'deny';
|
|
13
|
+
executionBoundary: 'sandbox' | 'host';
|
|
14
|
+
hostFallback: 'ask' | 'deny' | 'allow';
|
|
15
|
+
projectRoot?: string;
|
|
16
|
+
executionCwd?: string;
|
|
17
|
+
executionWorkspaceId?: string;
|
|
15
18
|
}
|
|
16
19
|
export interface BrowserHostResponse {
|
|
17
20
|
version: 1;
|
|
@@ -19,6 +22,7 @@ export interface BrowserHostResponse {
|
|
|
19
22
|
requestId: string;
|
|
20
23
|
tool: 'browser';
|
|
21
24
|
ok: boolean;
|
|
25
|
+
environmentId?: string;
|
|
22
26
|
result?: unknown;
|
|
23
27
|
error?: {
|
|
24
28
|
code: string;
|
|
@@ -26,6 +30,8 @@ export interface BrowserHostResponse {
|
|
|
26
30
|
message: string;
|
|
27
31
|
retryable: boolean;
|
|
28
32
|
};
|
|
33
|
+
executionBoundary?: 'sandbox' | 'host';
|
|
34
|
+
fallbackReason?: string;
|
|
29
35
|
}
|
|
30
36
|
export type BrowserHostInvoker = (request: BrowserHostRequest, signal?: AbortSignal) => Promise<BrowserHostResponse>;
|
|
31
37
|
export declare function browserToolDefinitions(): readonly ToolDefinition[];
|
|
@@ -33,9 +39,13 @@ export declare class BrowserHostToolExecutor implements ToolExecutor {
|
|
|
33
39
|
private readonly options;
|
|
34
40
|
constructor(options: {
|
|
35
41
|
request: BrowserHostInvoker;
|
|
42
|
+
executionBoundary: 'sandbox' | 'host';
|
|
43
|
+
hostFallback: 'ask' | 'deny' | 'allow';
|
|
44
|
+
onFallbackApproval?: (request: ToolApprovalRequest, reason: string) => boolean | ToolAuthorizationDecision | Promise<boolean | ToolAuthorizationDecision>;
|
|
36
45
|
onActivity?: ToolActivityObserver;
|
|
37
46
|
});
|
|
38
47
|
listTools(): readonly ToolDefinition[];
|
|
39
48
|
getToolInfo(toolName: string): ToolInfo | undefined;
|
|
40
49
|
execute(toolName: string, input: Record<string, unknown>, context: ToolExecutionContext): Promise<ToolResult>;
|
|
50
|
+
private request;
|
|
41
51
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{randomUUID as
|
|
2
|
-
[truncated]`}function
|
|
1
|
+
import{randomUUID as k}from"node:crypto";import{imageContentBlockFromDataUrl as v,omitImageData as I}from"./tool-image-content.js";import{READ_ONLY_BROWSER_TOOLS as O}from"../security/tool-policy-registry.js";const f=[e("browser.navigate","Open an HTTP(S) URL in the agent browser.",{url:o("Destination URL."),tabId:o("Optional browser tab id.")},["url"]),e("browser.newTab","Open a new blank tab in the agent browser.",{},[]),e("browser.closeTab","Close the active browser tab.",{tabId:o("Optional browser tab id.")},[]),e("browser.selectTab","Make a browser tab active.",{tabId:o("Browser tab id.")},["tabId"]),e("browser.inspect","Inspect the current page DOM summary, text, headings, links, and visible interactive elements.",{tabId:o("Optional browser tab id.")},[]),e("browser.inspectElement","Inspect a page element including its DOM, attributes, bounds, and computed CSS.",{target:i(),tabId:o("Optional browser tab id.")},["target"]),e("browser.extractTable","Extract a bounded HTML table from the current page.",{target:i(),maxRows:l("Maximum number of data rows to return.")},["target"]),e("browser.drag","Drag one visible page target onto another.",{from:i(),to:i()},["from","to"]),e("browser.listFrames","List frames embedded in the current browser page.",{tabId:o("Optional browser tab id.")},[]),e("browser.console","Read recent browser console messages and page errors.",{tabId:o("Optional browser tab id."),limit:l("Maximum number of entries to return.")},[]),e("browser.network","Read recent browser network requests, HTTP failures, and request errors.",{tabId:o("Optional browser tab id."),limit:l("Maximum number of entries to return.")},[]),e("browser.accessibility","Inspect the page accessibility tree without exposing control values.",{tabId:o("Optional browser tab id.")},[]),e("browser.setViewport","Emulate a responsive browser viewport for the current tab.",{width:l("Viewport width in CSS pixels."),height:l("Viewport height in CSS pixels."),mobile:d("Whether to emulate a mobile layout."),deviceScaleFactor:l("Optional device scale factor.")},["width","height"]),e("browser.resetViewport","Reset the browser tab to its normal viewport.",{tabId:o("Optional browser tab id.")},[]),e("browser.screenshot","Capture the current browser tab as evidence.",{tabId:o("Optional browser tab id.")},[]),e("browser.click","Click a visible page element using an accessibility target, text, CSS selector, or coordinates.",{target:i()},["target"]),e("browser.focus","Focus a visible page field or control.",{target:i()},["target"]),e("browser.clear","Clear a visible editable page field.",{target:i()},["target"]),e("browser.hover","Move the browser pointer over a visible page element.",{target:i()},["target"]),e("browser.check","Check or uncheck a checkbox or radio input.",{target:i(),checked:d("Whether the control should be checked.")},["target","checked"]),e("browser.select","Select an option in a native HTML select control.",{target:i(),value:o("Option value or visible label.")},["target","value"]),e("browser.readField","Read a visible non-password form field value.",{target:i()},["target"]),e("browser.type","Enter text into a visible page field.",{target:i(),value:o("Text to enter.")},["target","value"]),e("browser.upload","Upload a workspace file through a visible file input.",{target:i(),path:o("Workspace-relative or absolute file path.")},["target","path"]),e("browser.download","Download an HTTP(S) resource to the Desktop downloads folder.",{url:o("HTTP(S) resource URL."),tabId:o("Optional browser tab id.")},["url"]),e("browser.exportPdf","Export the current browser page to a workspace PDF file.",{outputPath:o("Workspace-relative or absolute output path."),overwrite:d("Whether an existing output file may be replaced."),printBackground:d("Whether CSS backgrounds should be printed."),landscape:d("Whether to use landscape orientation."),pageSize:h(["A4","Letter"],"PDF paper size.")},["outputPath"]),e("browser.dialog","Read or respond to the active alert, confirm, or prompt dialog.",{action:h(["read","accept","dismiss"],"Dialog operation."),promptText:o("Optional text for a prompt dialog."),tabId:o("Optional browser tab id.")},["action"]),e("browser.press","Press a keyboard key in the current browser tab.",{key:o("Key name, for example Enter or Tab."),modifiers:S("Optional modifiers: Alt, Control, Shift, or Meta."),tabId:o("Optional browser tab id.")},["key"]),e("browser.scroll","Scroll the current browser tab.",{deltaX:l("Horizontal scroll amount."),deltaY:l("Vertical scroll amount."),tabId:o("Optional browser tab id.")},[]),e("browser.back","Navigate the current browser tab back.",{tabId:o("Optional browser tab id.")},[]),e("browser.forward","Navigate the current browser tab forward.",{tabId:o("Optional browser tab id.")},[]),e("browser.reload","Reload the current browser tab.",{tabId:o("Optional browser tab id.")},[]),e("browser.waitFor","Wait until a URL, text fragment, or CSS selector appears.",{condition:x(),timeoutMs:l("Maximum wait time in milliseconds.")},["condition"]),e("browser.tabs","List tabs in the agent browser session.",{},[])];function R(){return f}class U{options;constructor(r){this.options=r}listTools(){return R()}getToolInfo(r){if(!f.some(n=>g(n)===r))return;const s=O.has(r);return{toolName:r,source:"custom",executorId:"desktop-browser-host",metadata:{risk:s?"read":"unknown"}}}async execute(r,s,n){if(!f.some(a=>g(a)===r))return{content:`Unknown browser tool: ${r}`,isError:!0};const b=this.options.onActivity?.start({key:`${n.runId}:${r}`,toolName:r,source:"browser",label:E(r,s)});try{let a=await this.options.request(this.request(r,s,n),n.signal);if(!a.ok&&a.error?.code==="SANDBOX_FALLBACK_REQUIRED"&&this.options.hostFallback==="ask"){const p=this.getToolInfo(r),c=await this.options.onFallbackApproval?.({toolName:r,input:s,context:n,...p===void 0?{}:{toolInfo:p}},a.error.message)??!1;if(typeof c=="boolean"?c:c.decision==="allow")a=await this.options.request({...this.request(r,s,n),executionBoundary:"host",hostFallback:"deny"},n.signal);else if(typeof c!="boolean"&&c.decision==="redirect")return b?.complete(!0,{userRedirect:!0}),{content:c.message,isError:!0,metadata:{code:"USER_REDIRECTED_ACTION",boundary:this.options.executionBoundary}}}if(!a.ok){const p=a.error?.message??"Desktop rejected the browser action.";return b?.complete(!0),{content:p,isError:!0,metadata:{code:a.error?.code??"BROWSER_HOST_ERROR",retryable:a.error?.retryable??!1}}}const u=r==="browser.screenshot"&&B(a.result)?a.result:void 0,w=u===void 0?void 0:v(u.dataUrl);if(u!==void 0&&u.dataUrl!==void 0&&w===void 0)throw new Error("Desktop returned an invalid browser screenshot payload.");const m=r==="browser.screenshot"?I(a.result,"dataUrl"):a.result,y=T(m,n.maxResultBytes);return b?.complete(!1),{content:y,isError:!1,...w===void 0?{}:{contentBlocks:[w]},metadata:{browser:!0,boundary:a.executionBoundary??this.options.executionBoundary,...a.environmentId===void 0?{}:{environmentId:a.environmentId},...a.fallbackReason===void 0?{}:{fallbackReason:a.fallbackReason}}}}catch(a){return b?.complete(!0),{content:a instanceof Error?a.message:"Browser host request failed.",isError:!0}}}request(r,s,n){return{version:1,type:"host.request",requestId:k(),tool:"browser",sessionId:n.sessionId,runId:n.runId,action:r,params:s,executionBoundary:this.options.executionBoundary,hostFallback:this.options.hostFallback,...n.workspaceRoot===void 0?{}:{projectRoot:n.workspaceRoot},...n.cwd===void 0?{}:{executionCwd:n.cwd},...typeof n.metadata?.executionWorkspaceId=="string"?{executionWorkspaceId:n.metadata.executionWorkspaceId}:{}}}}function e(t,r,s,n){return{type:"function",function:{name:t,description:r,parameters:{type:"object",properties:s,required:n,additionalProperties:!1}}}}function o(t){return{type:"string",description:t}}function l(t){return{type:"number",description:t}}function d(t){return{type:"boolean",description:t}}function h(t,r){return{type:"string",enum:[...t],description:r}}function S(t){return{type:"array",items:{type:"string"},description:t}}function i(){return{type:"object",properties:{type:{type:"string",enum:["accessibility","text","css","coordinates"]},role:{type:"string"},name:{type:"string"},value:{type:"string"},selector:{type:"string"},x:{type:"number"},y:{type:"number"}},required:["type"],additionalProperties:!1}}function x(){return{type:"object",properties:{type:{type:"string",enum:["selector","text","url"]},value:{type:"string"}},required:["type","value"],additionalProperties:!1}}function g(t){return"function"in t?t.function.name:void 0}function T(t,r){const s=JSON.stringify(t??null);return Buffer.byteLength(s,"utf8")<=r?s:`${s.slice(0,Math.max(0,r-12))}
|
|
2
|
+
[truncated]`}function E(t,r){return t==="browser.navigate"?`Open ${typeof r.url=="string"?r.url:"URL"}`:t==="browser.type"?"Enter text in browser":t==="browser.click"?"Click page element":t.replace(/^browser\./u,"Browser ")}function B(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}export{U as BrowserHostToolExecutor,R as browserToolDefinitions};
|
|
@@ -30,10 +30,13 @@ export interface ComputerHostResponse {
|
|
|
30
30
|
}
|
|
31
31
|
export type ComputerHostInvoker = (request: ComputerHostRequest, signal?: AbortSignal) => Promise<ComputerHostResponse>;
|
|
32
32
|
export declare function computerToolDefinitions(): readonly ToolDefinition[];
|
|
33
|
+
export declare function computerToolDefinitionsForOperations(operations: readonly string[]): readonly ToolDefinition[];
|
|
33
34
|
export declare class ComputerHostToolExecutor implements ToolExecutor {
|
|
34
35
|
private readonly options;
|
|
36
|
+
private readonly definitions;
|
|
35
37
|
constructor(options: {
|
|
36
38
|
request: ComputerHostInvoker;
|
|
39
|
+
operations?: readonly string[];
|
|
37
40
|
onActivity?: ToolActivityObserver;
|
|
38
41
|
});
|
|
39
42
|
listTools(): readonly ToolDefinition[];
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{randomUUID as g}from"node:crypto";import{imageContentBlockFromResult as h,omitImageData as y}from"./tool-image-content.js";const p=[t("computer.listWindows","List visible Windows application windows that can be targeted.",{includeMinimized:u("Whether minimized windows should be included.")},[]),t("computer.inspect","Inspect the accessible UI elements of a target Windows application window.",{windowId:e("Target window id."),query:T(),maxDepth:i("Maximum UI tree depth.")},["windowId"]),t("computer.screenshot","Capture the target Windows application window for visual verification.",{windowId:e("Target window id."),region:w()},["windowId"]),t("computer.readText","Read text or the current value from an inspected Windows UI element.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect."),scope:c(["value","document","selection"],"Text source to read.")},["windowId","elementId"]),t("computer.readSelection","Read selected items from a Windows selection control.",{windowId:e("Target window id."),elementId:e("Selection control element id.")},["windowId","elementId"]),t("computer.readGrid","Read a bounded rectangular region from a Windows grid control.",{windowId:e("Target window id."),elementId:e("Grid control element id."),rowStart:i("Zero-based first row."),rowCount:i("Maximum rows to read."),columnStart:i("Zero-based first column."),columnCount:i("Maximum columns to read.")},["windowId","elementId"]),t("computer.recognizeText","Recognize visible text in a Windows application screenshot.",{windowId:e("Target window id."),region:w(),language:e("Optional BCP-47 OCR language tag.")},["windowId"]),t("computer.focus","Bring a Windows application window or one of its inspected elements to the foreground.",{windowId:e("Target window id."),elementId:e("Optional element id from computer.inspect.")},["windowId"]),t("computer.click","Click a visible target window element or validated point.",{windowId:e("Target window id."),elementId:e("Optional element id from computer.inspect."),point:m(),button:c(["left","right","middle"],"Mouse button."),clickCount:i("Number of clicks, one or two.")},["windowId"]),t("computer.type","Type text into the focused Windows control.",{windowId:e("Target window id."),text:e("Text to type."),elementId:e("Optional editable element id from computer.inspect.")},["windowId","text"]),t("computer.keypress","Press a keyboard key with optional modifiers in the target window.",{windowId:e("Target window id."),key:e("Key name, for example Enter or Tab."),modifiers:b("Optional modifiers: Alt, Control, Shift, or Meta.")},["windowId","key"]),t("computer.scroll","Scroll the target Windows application.",{windowId:e("Target window id."),deltaX:i("Horizontal scroll amount."),deltaY:i("Vertical scroll amount."),point:m()},["windowId"]),t("computer.drag","Drag from one validated point or element to another within a target window.",{windowId:e("Target window id."),from:f(),to:f(),durationMs:i("Drag duration in milliseconds.")},["windowId","from","to"]),t("computer.selectText","Select an occurrence of text in an inspected Windows text control.",{windowId:e("Target window id."),elementId:e("Text control element id."),text:e("Text to select."),occurrence:i("One-based occurrence to select.")},["windowId","elementId","text"]),t("computer.listDisplays","List connected Windows displays and their work areas.",{},[]),t("computer.launch","Launch an allowlisted Windows application by app id.",{appId:e("Registered application id.")},["appId"]),t("computer.wait","Wait for a target window, UI element, text, or idle state.",{windowId:e("Optional target window id."),condition:c(["window","element","text","idle"],"Condition to wait for."),elementId:e("Optional element id."),text:e("Optional text to find."),timeoutMs:i("Maximum wait time in milliseconds."),idleMs:i("Minimum system idle time for the idle condition.")},["condition","timeoutMs"]),t("computer.move","Move the pointer to a target point or element, including hover interactions.",{windowId:e("Target window id."),elementId:e("Optional element id from computer.inspect."),point:m(),durationMs:i("Movement duration in milliseconds.")},["windowId"]),t("computer.setValue","Set the value of an editable or range UI Automation control.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect."),value:e("New control value.")},["windowId","elementId","value"]),t("computer.invoke","Invoke the default action of an inspected button or menu item.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect.")},["windowId","elementId"]),t("computer.select","Set the selection state of an inspected selectable UI element.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect."),mode:c(["replace","add","remove"],"Selection operation.")},["windowId","elementId"]),t("computer.setToggleState","Set an inspected toggle or checkbox to a specific state.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect."),state:c(["on","off","indeterminate"],"Desired toggle state.")},["windowId","elementId","state"]),t("computer.setExpandedState","Expand or collapse an inspected tree, menu, or group control.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect."),expanded:u("Whether the element should be expanded.")},["windowId","elementId","expanded"]),t("computer.scrollIntoView","Scroll an inspected element into the visible area of its container.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect.")},["windowId","elementId"]),t("computer.setWindowState","Set the target window visual state and optionally its screen bounds.",{windowId:e("Target window id."),state:c(["normal","minimized","maximized"],"Desired window state."),bounds:v()},["windowId","state"]),t("computer.closeWindow","Request a normal close of the target Windows application window.",{windowId:e("Target window id.")},["windowId"]),t("computer.readClipboard","Read the current Windows text clipboard contents.",{},[]),t("computer.writeClipboard","Replace the Windows text clipboard contents.",{text:e("Text to place on the clipboard.")},["text"]),t("computer.waitForState","Wait until an inspected Windows UI element exposes the requested property value.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect."),property:c(["name","value","isEnabled","isOffscreen","toggleState","expandCollapseState","selectionState"],"UI Automation property to observe."),expected:e("Expected property value."),timeoutMs:i("Maximum wait time in milliseconds."),intervalMs:i("Polling interval in milliseconds.")},["windowId","elementId","property","expected","timeoutMs"]),t("computer.manageFileDialog","Set, confirm, or cancel a standard Windows file dialog.",{windowId:e("File dialog window id."),action:c(["setPath","confirm","cancel"],"File dialog operation."),path:e("File path to enter when using setPath or confirm.")},["windowId","action"])];function x(){return p}class C{options;constructor(o){this.options=o}listTools(){return x()}getToolInfo(o){if(!p.some(a=>I(a)===o))return;const d=["computer.listWindows","computer.inspect","computer.screenshot","computer.readText","computer.readSelection","computer.readGrid","computer.recognizeText","computer.listDisplays","computer.wait","computer.readClipboard","computer.waitForState"].includes(o);return{toolName:o,source:"custom",executorId:"desktop-computer-host",metadata:{risk:d?"read":"unknown"}}}async execute(o,d,a){if(!p.some(r=>I(r)===o))return{content:`Unknown computer tool: ${o}`,isError:!0};const s=this.options.onActivity?.start({key:`${a.runId}:${o}`,toolName:o,source:"computer",label:W(o)});try{const r=await this.options.request({version:1,type:"host.request",requestId:g(),tool:"computer",sessionId:a.sessionId,runId:a.runId,action:o,params:d,executionBoundary:"host",hostFallback:"deny"},a.signal);if(!r.ok)return s?.complete(!0),{content:r.error?.message??"Desktop rejected the computer action.",isError:!0,metadata:{code:r.error?.code??"COMPUTER_HOST_ERROR",retryable:r.error?.retryable??!1}};s?.complete(!1);const l=o==="computer.screenshot"?h(r.result):void 0;return{content:S(l===void 0?r.result:y(r.result,"dataBase64"),a.maxResultBytes),isError:!1,...l===void 0?{}:{contentBlocks:[l]},metadata:{computer:!0}}}catch(r){return s?.complete(!0),{content:r instanceof Error?r.message:"Computer host request failed.",isError:!0}}}}function t(n,o,d,a){return{type:"function",function:{name:n,description:o,parameters:{type:"object",properties:d,required:a,additionalProperties:!1}}}}function e(n){return{type:"string",description:n}}function i(n){return{type:"number",description:n}}function u(n){return{type:"boolean",description:n}}function c(n,o){return{type:"string",enum:[...n],description:o}}function b(n){return{type:"array",items:{type:"string"},description:n}}function T(){return{type:"object",properties:{role:e("Exact UI Automation control type."),name:e("Case-insensitive text contained in the element name."),text:e("Case-insensitive text contained in the element name or help text.")},additionalProperties:!1,description:"Optional role, name, or text filter."}}function w(){return{type:"object",properties:{x:{type:"number",description:"Left offset within the window."},y:{type:"number",description:"Top offset within the window."},width:{type:"number",description:"Region width."},height:{type:"number",description:"Region height."}},required:["x","y","width","height"],additionalProperties:!1,description:"Optional region within the target window."}}function v(){return{type:"object",properties:{x:i("Screen left coordinate."),y:i("Screen top coordinate."),width:i("Window width."),height:i("Window height.")},required:["x","y","width","height"],additionalProperties:!1,description:"Optional screen bounds."}}function m(){return{type:"object",properties:{x:{type:"number"},y:{type:"number"}},required:["x","y"],additionalProperties:!1}}function f(){return{type:"object",properties:{elementId:{type:"string"},x:{type:"number"},y:{type:"number"}},additionalProperties:!1}}function I(n){return"function"in n?n.function.name:void 0}function S(n,o){const d=JSON.stringify(n??null);return Buffer.byteLength(d,"utf8")<=o?d:`${d.slice(0,Math.max(0,o-12))}
|
|
2
|
-
[truncated]`}function
|
|
1
|
+
import{randomUUID as g}from"node:crypto";import{imageContentBlockFromResult as h,omitImageData as y}from"./tool-image-content.js";import{READ_ONLY_COMPUTER_TOOLS as x}from"../security/tool-policy-registry.js";const s=[t("computer.listWindows","List visible desktop application windows that can be targeted.",{includeMinimized:w("Whether minimized windows should be included.")},[]),t("computer.inspect","Inspect accessible UI elements of a target desktop application window.",{windowId:e("Target window id."),query:v(),maxDepth:i("Maximum UI tree depth.")},["windowId"]),t("computer.screenshot","Capture the target application window or screen for visual verification.",{windowId:e("Target window id."),region:f()},["windowId"]),t("computer.readText","Read text or the current value from an inspected UI element.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect."),scope:c(["value","document","selection"],"Text source to read.")},["windowId","elementId"]),t("computer.readSelection","Read selected items from a selection control.",{windowId:e("Target window id."),elementId:e("Selection control element id.")},["windowId","elementId"]),t("computer.readGrid","Read a bounded rectangular region from a grid control.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect."),rowStart:i("Zero-based first row."),rowCount:i("Maximum rows to read."),columnStart:i("Zero-based first column."),columnCount:i("Maximum columns to read.")},["windowId","elementId"]),t("computer.recognizeText","Recognize visible text in an application screenshot.",{windowId:e("Target window id."),region:f(),language:e("Optional BCP-47 OCR language tag.")},["windowId"]),t("computer.focus","Bring an application window or inspected element to the foreground.",{windowId:e("Target window id."),elementId:e("Optional element id from computer.inspect.")},["windowId"]),t("computer.click","Click a visible target window element or validated point.",{windowId:e("Target window id."),elementId:e("Optional element id from computer.inspect."),point:m(),button:c(["left","right","middle"],"Mouse button."),clickCount:i("Number of clicks, one or two.")},["windowId"]),t("computer.type","Type text into the focused application control.",{windowId:e("Target window id."),text:e("Text to type."),elementId:e("Optional editable element id from computer.inspect.")},["windowId","text"]),t("computer.keypress","Press a keyboard key with optional modifiers in the target window.",{windowId:e("Target window id."),key:e("Key name, for example Enter or Tab."),modifiers:T("Optional modifiers: Alt, Control, Shift, or Meta.")},["windowId","key"]),t("computer.scroll","Scroll the target application.",{windowId:e("Target window id."),deltaX:i("Horizontal scroll amount."),deltaY:i("Vertical scroll amount."),point:m()},["windowId"]),t("computer.drag","Drag from one validated point or element to another within a target window.",{windowId:e("Target window id."),from:I(),to:I(),durationMs:i("Drag duration in milliseconds.")},["windowId","from","to"]),t("computer.selectText","Select an occurrence of text in an inspected text control.",{windowId:e("Target window id."),elementId:e("Text control element id."),text:e("Text to select."),occurrence:i("One-based occurrence to select.")},["windowId","elementId","text"]),t("computer.listDisplays","List connected displays and their work areas.",{},[]),t("computer.launch","Launch an allowlisted desktop application by app id.",{appId:e("Registered application id.")},["appId"]),t("computer.wait","Wait for a target window, UI element, text, or idle state.",{windowId:e("Optional target window id."),condition:c(["window","element","text","idle"],"Condition to wait for."),elementId:e("Optional element id."),text:e("Optional text to find."),timeoutMs:i("Maximum wait time in milliseconds."),idleMs:i("Minimum system idle time for the idle condition.")},["condition","timeoutMs"]),t("computer.move","Move the pointer to a target point or element, including hover interactions.",{windowId:e("Target window id."),elementId:e("Optional element id from computer.inspect."),point:m(),durationMs:i("Movement duration in milliseconds.")},["windowId"]),t("computer.setValue","Set the value of an editable or range UI Automation control.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect."),value:e("New control value.")},["windowId","elementId","value"]),t("computer.invoke","Invoke the default action of an inspected button or menu item.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect.")},["windowId","elementId"]),t("computer.select","Set the selection state of an inspected selectable UI element.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect."),mode:c(["replace","add","remove"],"Selection operation.")},["windowId","elementId"]),t("computer.setToggleState","Set an inspected toggle or checkbox to a specific state.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect."),state:c(["on","off","indeterminate"],"Desired toggle state.")},["windowId","elementId","state"]),t("computer.setExpandedState","Expand or collapse an inspected tree, menu, or group control.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect."),expanded:w("Whether the element should be expanded.")},["windowId","elementId","expanded"]),t("computer.scrollIntoView","Scroll an inspected element into the visible area of its container.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect.")},["windowId","elementId"]),t("computer.setWindowState","Set the target window visual state and optionally its screen bounds.",{windowId:e("Target window id."),state:c(["normal","minimized","maximized"],"Desired window state."),bounds:S()},["windowId","state"]),t("computer.closeWindow","Request a normal close of the target application window.",{windowId:e("Target window id.")},["windowId"]),t("computer.readClipboard","Read the current text clipboard contents.",{},[]),t("computer.writeClipboard","Replace the text clipboard contents.",{text:e("Text to place on the clipboard.")},["text"]),t("computer.waitForState","Wait until an inspected UI element exposes the requested property value.",{windowId:e("Target window id."),elementId:e("Element id from computer.inspect."),property:c(["name","value","isEnabled","isOffscreen","toggleState","expandCollapseState","selectionState"],"UI property to observe."),expected:e("Expected property value."),timeoutMs:i("Maximum wait time in milliseconds."),intervalMs:i("Polling interval in milliseconds.")},["windowId","elementId","property","expected","timeoutMs"]),t("computer.manageFileDialog","Set, confirm, or cancel a standard file dialog.",{windowId:e("File dialog window id."),action:c(["setPath","confirm","cancel"],"File dialog operation."),path:e("File path to enter when using setPath or confirm.")},["windowId","action"])];function R(){return s}function b(n){if(n.includes("*"))return s;const o=new Set(n);return s.filter(a=>{const r=u(a);return r!==void 0&&o.has(r)})}class U{options;definitions;constructor(o){this.options=o,this.definitions=o.operations===void 0?s:b(o.operations)}listTools(){return this.definitions}getToolInfo(o){if(!this.definitions.some(r=>u(r)===o))return;const a=x.has(o);return{toolName:o,source:"custom",executorId:"desktop-computer-host",metadata:{risk:a?"read":"unknown"}}}async execute(o,a,r){if(!this.definitions.some(d=>u(d)===o))return{content:`Computer capability is unavailable for ${o}.`,isError:!0,metadata:{code:"COMPUTER_CAPABILITY_UNAVAILABLE"}};const l=this.options.onActivity?.start({key:`${r.runId}:${o}`,toolName:o,source:"computer",label:E(o)});try{const d=await this.options.request({version:1,type:"host.request",requestId:g(),tool:"computer",sessionId:r.sessionId,runId:r.runId,action:o,params:a,executionBoundary:"host",hostFallback:"deny"},r.signal);if(!d.ok)return l?.complete(!0),{content:d.error?.message??"Desktop rejected the computer action.",isError:!0,metadata:{code:d.error?.code??"COMPUTER_HOST_ERROR",retryable:d.error?.retryable??!1}};l?.complete(!1);const p=o==="computer.screenshot"?h(d.result):void 0;return{content:O(p===void 0?d.result:y(d.result,"dataBase64"),r.maxResultBytes),isError:!1,...p===void 0?{}:{contentBlocks:[p]},metadata:{computer:!0}}}catch(d){return l?.complete(!0),{content:d instanceof Error?d.message:"Computer host request failed.",isError:!0}}}}function t(n,o,a,r){return{type:"function",function:{name:n,description:o,parameters:{type:"object",properties:a,required:r,additionalProperties:!1}}}}function e(n){return{type:"string",description:n}}function i(n){return{type:"number",description:n}}function w(n){return{type:"boolean",description:n}}function c(n,o){return{type:"string",enum:[...n],description:o}}function T(n){return{type:"array",items:{type:"string"},description:n}}function v(){return{type:"object",properties:{role:e("Exact UI Automation control type."),name:e("Case-insensitive text contained in the element name."),text:e("Case-insensitive text contained in the element name or help text.")},additionalProperties:!1,description:"Optional role, name, or text filter."}}function f(){return{type:"object",properties:{x:{type:"number",description:"Left offset within the window."},y:{type:"number",description:"Top offset within the window."},width:{type:"number",description:"Region width."},height:{type:"number",description:"Region height."}},required:["x","y","width","height"],additionalProperties:!1,description:"Optional region within the target window."}}function S(){return{type:"object",properties:{x:i("Screen left coordinate."),y:i("Screen top coordinate."),width:i("Window width."),height:i("Window height.")},required:["x","y","width","height"],additionalProperties:!1,description:"Optional screen bounds."}}function m(){return{type:"object",properties:{x:{type:"number"},y:{type:"number"}},required:["x","y"],additionalProperties:!1}}function I(){return{type:"object",properties:{elementId:{type:"string"},x:{type:"number"},y:{type:"number"}},additionalProperties:!1}}function u(n){return"function"in n?n.function.name:void 0}function O(n,o){const a=JSON.stringify(n??null);return Buffer.byteLength(a,"utf8")<=o?a:`${a.slice(0,Math.max(0,o-12))}
|
|
2
|
+
[truncated]`}function E(n){return n.replace(/^computer\./u,"Computer ")}export{U as ComputerHostToolExecutor,R as computerToolDefinitions,b as computerToolDefinitionsForOperations};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Readable, Writable } from 'node:stream';
|
|
2
2
|
import type { CliRuntime } from '../../bootstrap/runtime-factory.js';
|
|
3
|
-
export
|
|
3
|
+
export { DESKTOP_PROTOCOL_VERSION } from './desktop-agent-contracts.js';
|
|
4
4
|
/**
|
|
5
5
|
* Local JSONL bridge for the Desktop application. It is deliberately kept in
|
|
6
6
|
* the CLI application layer: Desktop reuses CLI policy and runtime, while the
|
|
7
7
|
* public SDK packages remain independent libraries.
|
|
8
8
|
*/
|
|
9
|
-
export declare function runDesktopAgentCommand(runtime: CliRuntime, cwd: string, input: Readable, output: Writable): Promise<number>;
|
|
9
|
+
export declare function runDesktopAgentCommand(runtime: CliRuntime, cwd: string, input: Readable, output: Writable, signal?: AbortSignal): Promise<number>;
|