@robota-sdk/agent-transport 3.0.0-beta.65 → 3.0.0-beta.66
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 +97 -0
- package/dist/node/chunk-Bmb41Sf3.cjs +1 -0
- package/dist/node/headless/index.cjs +1 -1
- package/dist/node/headless/index.d.ts +2 -2
- package/dist/node/headless/index.js +1 -1
- package/dist/node/headless-B8yWkXW_.js +15 -0
- package/dist/node/headless-B8yWkXW_.js.map +1 -0
- package/dist/node/headless-Dp3kQVmo.cjs +14 -0
- package/dist/node/http/index.cjs +1 -1
- package/dist/node/http/index.d.ts +1 -1
- package/dist/node/http/index.js +1 -1
- package/dist/node/{http-DwO1AHG-.js → http-Br10Ps8m.js} +1 -1
- package/dist/node/http-Br10Ps8m.js.map +1 -0
- package/dist/node/http-Da6Kw4oy.cjs +1 -0
- package/dist/node/{index-B_rcr14p.d.ts → index-C5KNEBO9.d.ts} +2 -2
- package/dist/node/{index-B_rcr14p.d.ts.map → index-C5KNEBO9.d.ts.map} +1 -1
- package/dist/node/{index-Y0zHb1Bz.d.ts → index-C7DvsmEg.d.ts} +2 -2
- package/dist/node/{index-Y0zHb1Bz.d.ts.map → index-C7DvsmEg.d.ts.map} +1 -1
- package/dist/node/index-C9LWCL4l.d.ts.map +1 -1
- package/dist/node/{index-k3TUjA-T.d.ts → index-CP7kaYMg.d.ts} +17 -2
- package/dist/node/index-CP7kaYMg.d.ts.map +1 -0
- package/dist/node/index-CQsMNXAh.d.ts +67 -0
- package/dist/node/index-CQsMNXAh.d.ts.map +1 -0
- package/dist/node/{index-nBlMTFkZ.d.ts → index-DOA2KIYt.d.ts} +2 -2
- package/dist/node/{index-nBlMTFkZ.d.ts.map → index-DOA2KIYt.d.ts.map} +1 -1
- package/dist/node/{index-D34WUfFH.d.ts → index-Gby9H4q2.d.ts} +17 -2
- package/dist/node/index-Gby9H4q2.d.ts.map +1 -0
- package/dist/node/{index-CvXLpjJO.d.ts → index-X2Zg8FEY.d.ts} +2 -2
- package/dist/node/{index-CEs25wVk.d.ts.map → index-X2Zg8FEY.d.ts.map} +1 -1
- package/dist/node/index-rGmGTQ9o.d.ts +67 -0
- package/dist/node/index-rGmGTQ9o.d.ts.map +1 -0
- package/dist/node/{index-CEs25wVk.d.ts → index-yvGShbDx.d.ts} +2 -2
- package/dist/node/{index-CvXLpjJO.d.ts.map → index-yvGShbDx.d.ts.map} +1 -1
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.ts +28 -6
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +2 -1
- package/dist/node/index.js.map +1 -0
- package/dist/node/mcp/index.cjs +1 -1
- package/dist/node/mcp/index.d.ts +1 -1
- package/dist/node/mcp/index.js +1 -1
- package/dist/node/{mcp-BXBwF6Wu.js → mcp-BAujHOMr.js} +1 -1
- package/dist/node/mcp-BAujHOMr.js.map +1 -0
- package/dist/node/mcp-Bl8jUfev.cjs +1 -0
- package/dist/node/tui/index.cjs +1 -1
- package/dist/node/tui/index.d.ts +2 -2
- package/dist/node/tui/index.js +1 -1
- package/dist/node/tui-B8G3yHrL.cjs +24 -0
- package/dist/node/tui-DUIfVw3G.js +25 -0
- package/dist/node/tui-DUIfVw3G.js.map +1 -0
- package/dist/node/ws/index.cjs +1 -1
- package/dist/node/ws/index.d.ts +1 -1
- package/dist/node/ws/index.js +1 -1
- package/dist/node/{ws-B-oRccFl.js → ws-BWel8nzl.js} +1 -1
- package/dist/node/ws-BWel8nzl.js.map +1 -0
- package/dist/node/ws-tCjj2gPu.cjs +1 -0
- package/package.json +19 -18
- package/src/headless/cli-input.ts +50 -0
- package/src/headless/headless-runner.ts +2 -1
- package/src/headless/headless-stream-json.ts +1 -0
- package/src/headless/headless-transport.ts +3 -2
- package/src/headless/index.ts +2 -0
- package/src/headless/print-terminal.ts +57 -0
- package/src/http/http-transport.ts +3 -3
- package/src/http/routes.ts +2 -1
- package/src/index.ts +2 -1
- package/src/mcp/mcp-server.ts +1 -0
- package/src/mcp/mcp-transport.ts +3 -2
- package/src/transport-registry.ts +100 -0
- package/src/tui/App.tsx +52 -34
- package/src/tui/BackgroundTaskPanel.tsx +4 -2
- package/src/tui/CjkTextInput.tsx +3 -2
- package/src/tui/ConfirmPrompt.tsx +2 -1
- package/src/tui/ExecutionWorkspaceDetailPane.tsx +7 -5
- package/src/tui/ExecutionWorkspaceSwitcher.tsx +8 -6
- package/src/tui/InputArea.tsx +20 -19
- package/src/tui/InteractivePrompt.tsx +5 -3
- package/src/tui/ListPicker.tsx +2 -1
- package/src/tui/MenuSelect.tsx +2 -1
- package/src/tui/MessageList.tsx +8 -6
- package/src/tui/PermissionPrompt.tsx +5 -3
- package/src/tui/PluginTUI.tsx +5 -3
- package/src/tui/SessionPicker.tsx +4 -2
- package/src/tui/SessionStatusBar.tsx +7 -3
- package/src/tui/SlashAutocomplete.tsx +4 -3
- package/src/tui/StatusBar.tsx +5 -3
- package/src/tui/StreamingIndicator.tsx +4 -2
- package/src/tui/TextPrompt.tsx +2 -1
- package/src/tui/ToolCommandOutput.tsx +4 -2
- package/src/tui/ToolDiffBlock.tsx +4 -2
- package/src/tui/TransportTUI.tsx +3 -2
- package/src/tui/UpdateNotice.tsx +1 -1
- package/src/tui/UsageSummaryEntry.tsx +3 -2
- package/src/tui/WaveText.tsx +1 -1
- package/src/tui/__tests__/fixtures/provider-setup-prompt-driver.tsx +7 -4
- package/src/tui/background-task-row-format.ts +2 -1
- package/src/tui/command-interaction-registry.ts +66 -0
- package/src/tui/command-interaction.ts +9 -35
- package/src/tui/create-default-tui-cli-adapter.ts +42 -0
- package/src/tui/flows/input-area-flow.ts +3 -2
- package/src/tui/hooks/command-effect-handler.ts +4 -3
- package/src/tui/hooks/side-effects-types.ts +1 -1
- package/src/tui/hooks/use-interactive-session-init.ts +4 -2
- package/src/tui/hooks/useAutocomplete.ts +1 -0
- package/src/tui/hooks/useInteractiveSession.ts +22 -19
- package/src/tui/hooks/usePermissionQueue.ts +2 -1
- package/src/tui/hooks/usePluginCallbacks.ts +1 -0
- package/src/tui/hooks/usePluginScreenData.ts +2 -1
- package/src/tui/hooks/useSideEffects.ts +8 -6
- package/src/tui/hooks/useSlashRouting.ts +4 -3
- package/src/tui/hooks/useStatusLineSettings.ts +4 -2
- package/src/tui/index.ts +3 -1
- package/src/tui/interactions/CommandConfirm.tsx +2 -1
- package/src/tui/interactions/CommandPicker.tsx +2 -1
- package/src/tui/render-markdown.ts +2 -1
- package/src/tui/render.tsx +12 -28
- package/src/tui/tui-cli-adapter-context.tsx +1 -0
- package/src/tui/tui-cli-adapter.ts +1 -1
- package/src/tui/tui-transport.ts +5 -4
- package/src/tui/utils/edit-diff.ts +1 -0
- package/src/tui/utils/tool-call-extractor.ts +1 -0
- package/src/ws/ws-background-messages.ts +1 -1
- package/src/ws/ws-handler.ts +6 -5
- package/src/ws/ws-transport-configurable.ts +6 -3
- package/src/ws/ws-transport.ts +3 -2
- package/dist/node/headless-CWEpJXFK.js +0 -7
- package/dist/node/headless-CWEpJXFK.js.map +0 -1
- package/dist/node/headless-DJ5pnxM6.cjs +0 -6
- package/dist/node/http-CuQE6V6t.cjs +0 -1
- package/dist/node/http-DwO1AHG-.js.map +0 -1
- package/dist/node/index-CSgNoyPK.d.ts +0 -85
- package/dist/node/index-CSgNoyPK.d.ts.map +0 -1
- package/dist/node/index-D34WUfFH.d.ts.map +0 -1
- package/dist/node/index-_dNm-2J3.d.ts +0 -85
- package/dist/node/index-_dNm-2J3.d.ts.map +0 -1
- package/dist/node/index-k3TUjA-T.d.ts.map +0 -1
- package/dist/node/mcp-BXBwF6Wu.js.map +0 -1
- package/dist/node/mcp-BiJsIywJ.cjs +0 -1
- package/dist/node/tui-BIpIcT7-.cjs +0 -24
- package/dist/node/tui-DBLn1T15.js +0 -25
- package/dist/node/tui-DBLn1T15.js.map +0 -1
- package/dist/node/ws-B-oRccFl.js.map +0 -1
- package/dist/node/ws-XRTSFZOK.cjs +0 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { IHistoryEntry, TUniversalValue } from '@robota-sdk/agent-core';
|
|
2
|
-
import type { ICommand } from '@robota-sdk/agent-framework';
|
|
3
1
|
import { parseSlashInput } from '../hooks/useAutocomplete.js';
|
|
2
|
+
|
|
4
3
|
import type { ITuiCommandInteraction } from '../command-interaction.js';
|
|
4
|
+
import type { IHistoryEntry, TUniversalValue } from '@robota-sdk/agent-core';
|
|
5
|
+
import type { ICommand } from '@robota-sdk/agent-framework';
|
|
5
6
|
|
|
6
7
|
export interface IAutocompleteInputKey {
|
|
7
8
|
upArrow?: boolean;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { TCommandEffect, TStatusLineCommandSettingsPatch } from '@robota-sdk/agent-framework';
|
|
2
|
-
import { isStatusLineCommandSettingsPatch } from '@robota-sdk/agent-framework';
|
|
3
1
|
import { createSystemMessage, messageToHistoryEntry } from '@robota-sdk/agent-core';
|
|
4
|
-
import
|
|
2
|
+
import { isStatusLineCommandSettingsPatch } from '@robota-sdk/agent-framework';
|
|
3
|
+
|
|
5
4
|
import type { ITuiCliAdapter } from '../tui-cli-adapter.js';
|
|
5
|
+
import type { IHistoryEntry, TSessionEndReason } from '@robota-sdk/agent-core';
|
|
6
|
+
import type { TCommandEffect, TStatusLineCommandSettingsPatch } from '@robota-sdk/agent-framework';
|
|
6
7
|
|
|
7
8
|
export interface ICommandEffectHandlerDeps {
|
|
8
9
|
addEntry: (entry: IHistoryEntry) => void;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import type { ICommandEffectQueue } from './command-effect-queue.js';
|
|
1
2
|
import type { IHistoryEntry } from '@robota-sdk/agent-core';
|
|
2
3
|
import type { InteractiveSession } from '@robota-sdk/agent-framework';
|
|
3
4
|
import type {
|
|
4
5
|
TCommandInteractionPrompt as TInteractivePrompt,
|
|
5
6
|
IStatusLineCommandSettings as TStatusLineSettings,
|
|
6
7
|
} from '@robota-sdk/agent-framework';
|
|
7
|
-
import type { ICommandEffectQueue } from './command-effect-queue.js';
|
|
8
8
|
|
|
9
9
|
export type { TInteractivePrompt, TStatusLineSettings };
|
|
10
10
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { InteractiveSession, CommandRegistry } from '@robota-sdk/agent-framework';
|
|
2
|
-
|
|
3
|
-
import type { TPermissionResultValue } from '@robota-sdk/agent-framework';
|
|
2
|
+
|
|
4
3
|
import { TuiStateManager } from '../tui-state-manager.js';
|
|
5
4
|
import { CommandEffectQueue, type ICommandEffectQueue } from './command-effect-queue.js';
|
|
5
|
+
|
|
6
6
|
import type { IInteractiveSessionProps } from './useInteractiveSession.js';
|
|
7
|
+
import type { TToolArgs } from '@robota-sdk/agent-core';
|
|
8
|
+
import type { TPermissionResultValue } from '@robota-sdk/agent-framework';
|
|
7
9
|
|
|
8
10
|
export interface IInitState {
|
|
9
11
|
interactiveSession: InteractiveSession;
|
|
@@ -1,30 +1,34 @@
|
|
|
1
|
+
import { createSystemMessage, messageToHistoryEntry } from '@robota-sdk/agent-core';
|
|
1
2
|
import { useState, useCallback, useEffect } from 'react';
|
|
2
|
-
|
|
3
|
-
import type
|
|
3
|
+
|
|
4
|
+
import { CommandEffectQueue, type ICommandEffectQueue } from './command-effect-queue.js';
|
|
5
|
+
import { initializeSession, type IInitState } from './use-interactive-session-init.js';
|
|
6
|
+
import { usePermissionQueue } from './usePermissionQueue.js';
|
|
7
|
+
import { useSlashRouting } from './useSlashRouting.js';
|
|
8
|
+
|
|
9
|
+
import type { TuiStateManager } from '../tui-state-manager.js';
|
|
10
|
+
import type { IPermissionRequest } from '../types.js';
|
|
11
|
+
import type {
|
|
12
|
+
IAIProvider,
|
|
13
|
+
TPermissionMode,
|
|
14
|
+
IHistoryEntry,
|
|
15
|
+
TSessionEndReason,
|
|
16
|
+
} from '@robota-sdk/agent-core';
|
|
17
|
+
import type { InteractiveSession, CommandRegistry } from '@robota-sdk/agent-framework';
|
|
4
18
|
import type {
|
|
5
19
|
IBackgroundTaskRunner,
|
|
6
20
|
ICommandHostAdapters,
|
|
7
21
|
ICommandModule,
|
|
8
22
|
IInteractiveSession,
|
|
9
23
|
IInteractiveSessionStore,
|
|
24
|
+
IExecutionWorkspaceEvent,
|
|
10
25
|
TSubagentRunnerFactory,
|
|
11
26
|
IExecutionDetailPage,
|
|
12
27
|
IExecutionWorkspaceSnapshot,
|
|
28
|
+
IToolState,
|
|
13
29
|
TShellExecFn,
|
|
14
30
|
} from '@robota-sdk/agent-framework';
|
|
15
|
-
import type {
|
|
16
|
-
IAIProvider,
|
|
17
|
-
TPermissionMode,
|
|
18
|
-
IHistoryEntry,
|
|
19
|
-
TSessionEndReason,
|
|
20
|
-
} from '@robota-sdk/agent-core';
|
|
21
|
-
import { createSystemMessage, messageToHistoryEntry } from '@robota-sdk/agent-core';
|
|
22
|
-
import type { IPermissionRequest } from '../types.js';
|
|
23
|
-
import { TuiStateManager } from '../tui-state-manager.js';
|
|
24
|
-
import { useSlashRouting } from './useSlashRouting.js';
|
|
25
|
-
import { CommandEffectQueue, type ICommandEffectQueue } from './command-effect-queue.js';
|
|
26
|
-
import { usePermissionQueue } from './usePermissionQueue.js';
|
|
27
|
-
import { initializeSession, type IInitState } from './use-interactive-session-init.js';
|
|
31
|
+
import type { ITransportRegistryView } from '@robota-sdk/agent-interface-transport';
|
|
28
32
|
|
|
29
33
|
const SESSION_INIT_POLL_MS = 200;
|
|
30
34
|
|
|
@@ -55,7 +59,7 @@ export interface IInteractiveSessionState {
|
|
|
55
59
|
history: IHistoryEntry[];
|
|
56
60
|
addEntry: (entry: IHistoryEntry) => void;
|
|
57
61
|
streamingText: string;
|
|
58
|
-
activeTools:
|
|
62
|
+
activeTools: IToolState[];
|
|
59
63
|
isThinking: boolean;
|
|
60
64
|
isAborting: boolean;
|
|
61
65
|
isShuttingDown: boolean;
|
|
@@ -144,9 +148,8 @@ export function useInteractiveSession(props: IInteractiveSessionProps): IInterac
|
|
|
144
148
|
const onCompact = (): void => applyCompactEventToManager(interactiveSession, manager);
|
|
145
149
|
const onSkillActivation = (): void =>
|
|
146
150
|
applySkillActivationEventToManager(interactiveSession, manager);
|
|
147
|
-
const onExecutionWorkspaceEvent = (
|
|
148
|
-
event
|
|
149
|
-
): void => manager.syncExecutionWorkspaceSnapshot(event.snapshot);
|
|
151
|
+
const onExecutionWorkspaceEvent = (event: IExecutionWorkspaceEvent): void =>
|
|
152
|
+
manager.syncExecutionWorkspaceSnapshot(event.snapshot);
|
|
150
153
|
|
|
151
154
|
interactiveSession.on('text_delta', manager.onTextDelta);
|
|
152
155
|
interactiveSession.on('tool_start', manager.onToolStart);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { useState, useRef, useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { IPermissionRequest } from '../types.js';
|
|
2
4
|
import type { TToolArgs } from '@robota-sdk/agent-core';
|
|
3
5
|
import type { TPermissionResultValue } from '@robota-sdk/agent-framework';
|
|
4
|
-
import type { IPermissionRequest } from '../types.js';
|
|
5
6
|
|
|
6
7
|
export function usePermissionQueue(): {
|
|
7
8
|
permissionHandler: (toolName: string, toolArgs: TToolArgs) => Promise<TPermissionResultValue>;
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { useState, useEffect } from 'react';
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
import type { IMenuSelectItem } from '../MenuSelect.js';
|
|
9
|
+
import type { ICommandPluginAdapter } from '@robota-sdk/agent-framework';
|
|
9
10
|
|
|
10
11
|
export function usePluginScreenData(
|
|
11
12
|
screen: string,
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import { useState, useRef, useCallback } from 'react';
|
|
2
|
-
import { useApp } from 'ink';
|
|
3
|
-
import type { ICommandInteraction, ICommandResult } from '@robota-sdk/agent-framework';
|
|
4
1
|
import { createSystemMessage, messageToHistoryEntry } from '@robota-sdk/agent-core';
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
|
|
2
|
+
import { useApp } from 'ink';
|
|
3
|
+
import { useState, useRef, useCallback } from 'react';
|
|
4
|
+
|
|
8
5
|
import { applyCommandEffects } from './command-effect-handler.js';
|
|
9
6
|
import { useTuiCliAdapter } from '../tui-cli-adapter-context.js';
|
|
10
7
|
import {
|
|
@@ -12,6 +9,11 @@ import {
|
|
|
12
9
|
applyConfirmedModelChange,
|
|
13
10
|
} from './model-change-side-effect.js';
|
|
14
11
|
|
|
12
|
+
import type { IUseSideEffectsOptions, IUseSideEffectsResult } from './side-effects-types.js';
|
|
13
|
+
import type { TInteractivePrompt } from './side-effects-types.js';
|
|
14
|
+
import type { TSessionEndReason } from '@robota-sdk/agent-core';
|
|
15
|
+
import type { ICommandInteraction, ICommandResult } from '@robota-sdk/agent-framework';
|
|
16
|
+
|
|
15
17
|
const EXIT_DELAY_MS = 500;
|
|
16
18
|
|
|
17
19
|
export function useSideEffects({
|
|
@@ -3,16 +3,17 @@
|
|
|
3
3
|
* Extracted from useInteractiveSession for single-responsibility.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { createSystemMessage, messageToHistoryEntry } from '@robota-sdk/agent-core';
|
|
6
7
|
import { useCallback } from 'react';
|
|
8
|
+
|
|
9
|
+
import type { TuiStateManager } from '../tui-state-manager.js';
|
|
10
|
+
import type { ICommandEffectQueue } from './command-effect-queue.js';
|
|
7
11
|
import type {
|
|
8
12
|
IInteractiveSession,
|
|
9
13
|
CommandRegistry,
|
|
10
14
|
ICommandResult,
|
|
11
15
|
TCommandEffect,
|
|
12
16
|
} from '@robota-sdk/agent-framework';
|
|
13
|
-
import { createSystemMessage, messageToHistoryEntry } from '@robota-sdk/agent-core';
|
|
14
|
-
import type { TuiStateManager } from '../tui-state-manager.js';
|
|
15
|
-
import type { ICommandEffectQueue } from './command-effect-queue.js';
|
|
16
17
|
|
|
17
18
|
export function useSlashRouting(
|
|
18
19
|
interactiveSession: IInteractiveSession,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
2
|
-
import type { IStatusLineCommandSettings } from '@robota-sdk/agent-framework';
|
|
3
1
|
import { DEFAULT_STATUS_LINE_COMMAND_SETTINGS } from '@robota-sdk/agent-framework';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
|
|
4
4
|
import { useTuiCliAdapter } from '../tui-cli-adapter-context.js';
|
|
5
|
+
|
|
5
6
|
import type { TUniversalValue } from '@robota-sdk/agent-core';
|
|
7
|
+
import type { IStatusLineCommandSettings } from '@robota-sdk/agent-framework';
|
|
6
8
|
|
|
7
9
|
function readStatusLineSettings(
|
|
8
10
|
settings: Record<string, TUniversalValue>,
|
package/src/tui/index.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { TuiTransport } from './tui-transport.js';
|
|
2
2
|
export type { ITuiCliAdapter } from './tui-cli-adapter.js';
|
|
3
|
-
export type {
|
|
3
|
+
export type { IDefaultTuiCliAdapterOptions } from './create-default-tui-cli-adapter.js';
|
|
4
|
+
export { createDefaultTuiCliAdapter } from './create-default-tui-cli-adapter.js';
|
|
5
|
+
export type { ITuiRenderOptions } from './render.js';
|
|
4
6
|
export type {
|
|
5
7
|
TOnMissingArgsAction,
|
|
6
8
|
ITuiPickerItem,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { marked } from 'marked';
|
|
2
|
-
import type { Renderer } from 'marked';
|
|
3
2
|
// @ts-expect-error — marked-terminal has no type declarations
|
|
4
3
|
import TerminalRenderer from 'marked-terminal';
|
|
5
4
|
|
|
5
|
+
import type { Renderer } from 'marked';
|
|
6
|
+
|
|
6
7
|
const ANSI_LIGHT_RED = '\u001b[38;5;210m';
|
|
7
8
|
const ANSI_LIGHT_GREEN = '\u001b[38;5;120m';
|
|
8
9
|
const ANSI_CYAN = '\u001b[36m';
|
package/src/tui/render.tsx
CHANGED
|
@@ -2,28 +2,19 @@
|
|
|
2
2
|
* Ink render entry point.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import React from 'react';
|
|
6
5
|
import { render } from 'ink';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
7
8
|
import App from './App.js';
|
|
8
|
-
|
|
9
|
-
import type { TPermissionMode } from '@robota-sdk/agent-core';
|
|
10
|
-
import type {
|
|
11
|
-
IBackgroundTaskRunner,
|
|
12
|
-
ICommandHostAdapters,
|
|
13
|
-
ICommandModule,
|
|
14
|
-
IInteractiveSession,
|
|
15
|
-
IInteractiveSessionStore,
|
|
16
|
-
TSubagentRunnerFactory,
|
|
17
|
-
TShellExecFn,
|
|
18
|
-
CommandRegistry,
|
|
19
|
-
} from '@robota-sdk/agent-framework';
|
|
20
|
-
import type { ITransportRegistryView } from '@robota-sdk/agent-interface-transport';
|
|
9
|
+
|
|
21
10
|
import type { ITuiCliAdapter } from './tui-cli-adapter.js';
|
|
22
|
-
import type {
|
|
11
|
+
import type { TPermissionMode } from '@robota-sdk/agent-core';
|
|
12
|
+
import type { IAgentRuntime } from '@robota-sdk/agent-framework';
|
|
13
|
+
import type { TShellExecFn } from '@robota-sdk/agent-framework';
|
|
14
|
+
|
|
15
|
+
export interface ITuiRenderOptions {
|
|
16
|
+
runtime: IAgentRuntime;
|
|
23
17
|
|
|
24
|
-
export interface IRenderOptions {
|
|
25
|
-
cwd: string;
|
|
26
|
-
provider: IAIProvider;
|
|
27
18
|
providerOverride?: string | undefined;
|
|
28
19
|
providerType?: string | undefined;
|
|
29
20
|
modelId?: string;
|
|
@@ -31,25 +22,17 @@ export interface IRenderOptions {
|
|
|
31
22
|
permissionMode?: TPermissionMode;
|
|
32
23
|
maxTurns?: number;
|
|
33
24
|
version?: string;
|
|
34
|
-
sessionStore?: IInteractiveSessionStore;
|
|
35
25
|
resumeSessionId?: string;
|
|
36
26
|
showSessionPickerOnStart?: boolean;
|
|
37
27
|
forkSession?: boolean;
|
|
38
28
|
sessionName?: string;
|
|
39
|
-
backgroundTaskRunners?: IBackgroundTaskRunner[];
|
|
40
|
-
subagentRunnerFactory?: TSubagentRunnerFactory;
|
|
41
|
-
commandModules?: readonly ICommandModule[];
|
|
42
|
-
commandHostAdapters?: ICommandHostAdapters;
|
|
43
29
|
shellExec?: TShellExecFn;
|
|
44
30
|
startupUpdateNotice?: Promise<string | undefined>;
|
|
45
|
-
transportRegistry?: ITransportRegistryView<IInteractiveSession>;
|
|
46
31
|
cliAdapter: ITuiCliAdapter;
|
|
47
|
-
reloadPluginCommandSource?: (registry: CommandRegistry) => void;
|
|
48
32
|
agentName?: string;
|
|
49
|
-
resolveInteraction?: (commandName: string) => ITuiCommandInteraction | undefined;
|
|
50
33
|
}
|
|
51
34
|
|
|
52
|
-
export async function renderApp(options:
|
|
35
|
+
export async function renderApp(options: ITuiRenderOptions): Promise<void> {
|
|
53
36
|
process.on('unhandledRejection', (reason) => {
|
|
54
37
|
process.stderr.write(`\n[UNHANDLED REJECTION] ${reason}\n`);
|
|
55
38
|
if (reason instanceof Error) {
|
|
@@ -57,6 +40,7 @@ export async function renderApp(options: IRenderOptions): Promise<void> {
|
|
|
57
40
|
}
|
|
58
41
|
});
|
|
59
42
|
|
|
60
|
-
const
|
|
43
|
+
const { runtime, ...tuiOptions } = options;
|
|
44
|
+
const instance = render(<App {...runtime} {...tuiOptions} />, { exitOnCtrlC: false });
|
|
61
45
|
await instance.waitUntilExit();
|
|
62
46
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import type { TUniversalValue } from '@robota-sdk/agent-core';
|
|
1
2
|
import type {
|
|
2
3
|
TStatusLineCommandSettingsPatch,
|
|
3
4
|
IStatusLineCommandSettings,
|
|
4
5
|
CommandRegistry,
|
|
5
6
|
} from '@robota-sdk/agent-framework';
|
|
6
|
-
import type { TUniversalValue } from '@robota-sdk/agent-core';
|
|
7
7
|
|
|
8
8
|
export interface ITuiCliAdapter {
|
|
9
9
|
getUserSettingsPath(): string;
|
package/src/tui/tui-transport.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
+
import { renderApp, type ITuiRenderOptions } from './render.js';
|
|
2
|
+
|
|
3
|
+
import type { TUniversalValue } from '@robota-sdk/agent-core';
|
|
1
4
|
import type { IInteractiveSession } from '@robota-sdk/agent-framework';
|
|
2
5
|
import type { IConfigurableTransport } from '@robota-sdk/agent-interface-transport';
|
|
3
|
-
import type { TUniversalValue } from '@robota-sdk/agent-core';
|
|
4
|
-
import { renderApp, type IRenderOptions } from './render.js';
|
|
5
6
|
|
|
6
7
|
export class TuiTransport implements IConfigurableTransport<IInteractiveSession> {
|
|
7
8
|
readonly name = 'tui';
|
|
8
9
|
readonly defaultEnabled = true;
|
|
9
10
|
readonly optionsSchema = {};
|
|
10
11
|
|
|
11
|
-
private readonly options:
|
|
12
|
+
private readonly options: ITuiRenderOptions;
|
|
12
13
|
|
|
13
|
-
constructor(options:
|
|
14
|
+
constructor(options: ITuiRenderOptions) {
|
|
14
15
|
this.options = options;
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { IInteractiveSession } from '@robota-sdk/agent-framework';
|
|
2
1
|
import type { TBackgroundControlAction, TClientMessage, TServerMessage } from './ws-protocol.js';
|
|
2
|
+
import type { IInteractiveSession } from '@robota-sdk/agent-framework';
|
|
3
3
|
|
|
4
4
|
export function handleBackgroundQueryMessage(
|
|
5
5
|
session: IInteractiveSession,
|
package/src/ws/ws-handler.ts
CHANGED
|
@@ -8,6 +8,12 @@
|
|
|
8
8
|
* Server pushes IInteractiveSession events to client in real-time.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import {
|
|
12
|
+
handleBackgroundControlMessage,
|
|
13
|
+
handleBackgroundQueryMessage,
|
|
14
|
+
} from './ws-background-messages.js';
|
|
15
|
+
|
|
16
|
+
import type { TClientMessage, TServerMessage } from './ws-protocol.js';
|
|
11
17
|
import type {
|
|
12
18
|
IInteractiveSession,
|
|
13
19
|
IExecutionResult,
|
|
@@ -16,11 +22,6 @@ import type {
|
|
|
16
22
|
TBackgroundTaskEvent,
|
|
17
23
|
IToolState,
|
|
18
24
|
} from '@robota-sdk/agent-framework';
|
|
19
|
-
import type { TClientMessage, TServerMessage } from './ws-protocol.js';
|
|
20
|
-
import {
|
|
21
|
-
handleBackgroundControlMessage,
|
|
22
|
-
handleBackgroundQueryMessage,
|
|
23
|
-
} from './ws-background-messages.js';
|
|
24
25
|
|
|
25
26
|
export interface IWsHandlerOptions {
|
|
26
27
|
/** IInteractiveSession to expose. */
|
|
@@ -4,12 +4,15 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { createServer, type Server } from 'node:http';
|
|
7
|
+
|
|
7
8
|
import { WebSocketServer, WebSocket } from 'ws';
|
|
8
|
-
|
|
9
|
-
import type { TUniversalValue } from '@robota-sdk/agent-core';
|
|
10
|
-
import type { IConfigurableTransport } from '@robota-sdk/agent-interface-transport';
|
|
9
|
+
|
|
11
10
|
import { createWsHandler } from './ws-handler.js';
|
|
11
|
+
|
|
12
12
|
import type { TServerMessage } from './ws-protocol.js';
|
|
13
|
+
import type { TUniversalValue } from '@robota-sdk/agent-core';
|
|
14
|
+
import type { IInteractiveSession } from '@robota-sdk/agent-framework';
|
|
15
|
+
import type { IConfigurableTransport } from '@robota-sdk/agent-interface-transport';
|
|
13
16
|
|
|
14
17
|
const DEFAULT_PORT = 7070;
|
|
15
18
|
const DEFAULT_MAX_RETRIES = 20;
|
package/src/ws/ws-transport.ts
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* After start(), the consumer must wire onMessage to their WebSocket.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { IInteractiveSession } from '@robota-sdk/agent-framework';
|
|
9
|
-
import type { ITransportAdapter } from '@robota-sdk/agent-interface-transport';
|
|
10
8
|
import { createWsHandler } from './ws-handler.js';
|
|
9
|
+
|
|
11
10
|
import type { TServerMessage } from './ws-protocol.js';
|
|
11
|
+
import type { IInteractiveSession } from '@robota-sdk/agent-framework';
|
|
12
|
+
import type { ITransportAdapter } from '@robota-sdk/agent-interface-transport';
|
|
12
13
|
|
|
13
14
|
export interface IWsTransportOptions {
|
|
14
15
|
/** Send a JSON message to the connected WebSocket client. */
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import{randomUUID as e}from"node:crypto";function t(e){let t=e.trimStart();if(!t.startsWith(`/`))return null;let[n=``,...r]=t.slice(1).split(/\s+/);return n.length===0?null:{name:n,args:r.join(` `)}}async function n(e,n){let r=t(n);if(!r)return{kind:`not-slash`};let i=await e.executeCommand(r.name,r.args);return i?i.effects?.some(e=>e.type===`session-execution-started`)?{kind:`session-execution`}:{kind:`command-result`,result:i}:{kind:`command-result`,result:{message:`Unknown command "/${r.name}".`,success:!1}}}function r(t,n,r){let i=JSON.stringify({type:`stream_event`,event:r,session_id:n(t),uuid:e()});process.stdout.write(i+`
|
|
2
|
-
`)}function i(e,t,n,i){let o=n=>r(e,t,n),s=e=>o({type:`content_block_delta`,delta:{type:`text_delta`,text:e}}),c=e=>o({type:`background_task_event`,background_task_event:e}),l=e=>o({type:`background_job_group_event`,background_job_group_event:e}),u=()=>a(e,{onTextDelta:s,onBackgroundTaskEvent:c,onBackgroundJobGroupEvent:l,onComplete:d,onInterrupted:f,onError:p}),d=r=>{u(),n(t(e),r.response,`success`),i(0)},f=r=>{u(),n(t(e),r.response,`success`),i(0)},p=r=>{u(),n(t(e),``,`error`),i(1)};return e.on(`text_delta`,s),e.on(`background_task_event`,c),e.on(`background_job_group_event`,l),e.on(`complete`,d),e.on(`interrupted`,f),e.on(`error`,p),u}function a(e,t){e.off(`text_delta`,t.onTextDelta),e.off(`background_task_event`,t.onBackgroundTaskEvent),e.off(`background_job_group_event`,t.onBackgroundJobGroupEvent),e.off(`complete`,t.onComplete),e.off(`interrupted`,t.onInterrupted),e.off(`error`,t.onError)}function o(e){let{session:t,outputFormat:n}=e;return{run:e=>n===`text`?l(t,e):n===`json`?u(t,e):d(t,e)}}function s(e,t,n){let r=JSON.stringify({type:`result`,result:t,session_id:e,subtype:n});process.stdout.write(r+`
|
|
3
|
-
`)}function c(e){try{return e.getSession().getSessionId()}catch{return``}}function l(e,t){return new Promise(r=>{let i=()=>{e.off(`complete`,a),e.off(`interrupted`,o),e.off(`error`,s)},a=e=>{i(),process.stdout.write(e.response+`
|
|
4
|
-
`),r(0)},o=e=>{i(),e.response&&process.stdout.write(e.response+`
|
|
5
|
-
`),r(0)},s=e=>{i(),r(1)};e.on(`complete`,a),e.on(`interrupted`,o),e.on(`error`,s),n(e,t).then(n=>{if(n.kind===`command-result`){i(),process.stdout.write(n.result.message+`
|
|
6
|
-
`),r(+!n.result.success);return}n.kind!==`session-execution`&&e.submit(t)})})}function u(e,t){return new Promise(r=>{let i=()=>{e.off(`complete`,a),e.off(`interrupted`,o),e.off(`error`,l)},a=t=>{i(),s(c(e),t.response,`success`),r(0)},o=t=>{i(),s(c(e),t.response,`success`),r(0)},l=t=>{i(),s(c(e),``,`error`),r(1)};e.on(`complete`,a),e.on(`interrupted`,o),e.on(`error`,l),n(e,t).then(n=>{if(n.kind===`command-result`){i(),s(c(e),n.result.message,n.result.success?`success`:`error`),r(+!n.result.success);return}n.kind!==`session-execution`&&e.submit(t)})})}function d(e,t){return new Promise(r=>{let a=i(e,c,s,r);n(e,t).then(n=>{if(n.kind===`command-result`){a(),s(c(e),n.result.message,n.result.success?`success`:`error`),r(+!n.result.success);return}n.kind!==`session-execution`&&e.submit(t)})})}function f(e){let t=null,n=0;return{name:`headless`,attach(e){t=e},async start(){if(!t)throw Error(`No session attached. Call attach() first.`);n=await o({session:t,outputFormat:e.outputFormat}).run(e.prompt)},async stop(){},getExitCode(){return n}}}export{o as n,f as t};
|
|
7
|
-
//# sourceMappingURL=headless-CWEpJXFK.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"headless-CWEpJXFK.js","names":[],"sources":["../../src/headless/headless-stream-json.ts","../../src/headless/headless-runner.ts","../../src/headless/headless-transport.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type {\n IInteractiveSession,\n IExecutionResult,\n ICommandResult,\n TBackgroundJobGroupEvent,\n TBackgroundTaskEvent,\n} from '@robota-sdk/agent-framework';\n\ntype TSlashCommandExecution =\n | { readonly kind: 'not-slash' }\n | { readonly kind: 'command-result'; readonly result: ICommandResult }\n | { readonly kind: 'session-execution' };\n\nfunction parseSlashCommand(prompt: string): { name: string; args: string } | null {\n const trimmed = prompt.trimStart();\n if (!trimmed.startsWith('/')) return null;\n const withoutSlash = trimmed.slice(1);\n const [name = '', ...args] = withoutSlash.split(/\\s+/);\n if (name.length === 0) return null;\n return { name, args: args.join(' ') };\n}\n\nexport async function executeSlashCommandIfPresent(\n session: IInteractiveSession,\n prompt: string,\n): Promise<TSlashCommandExecution> {\n const command = parseSlashCommand(prompt);\n if (!command) return { kind: 'not-slash' };\n\n const result = await session.executeCommand(command.name, command.args);\n if (result) {\n if (result.effects?.some((effect) => effect.type === 'session-execution-started')) {\n return { kind: 'session-execution' };\n }\n return { kind: 'command-result', result };\n }\n return {\n kind: 'command-result',\n result: { message: `Unknown command \"/${command.name}\".`, success: false },\n };\n}\n\ntype TStreamJsonEvent =\n | {\n type: 'content_block_delta';\n delta: { type: 'text_delta'; text: string };\n }\n | {\n type: 'background_task_event';\n background_task_event: TBackgroundTaskEvent;\n }\n | {\n type: 'background_job_group_event';\n background_job_group_event: TBackgroundJobGroupEvent;\n };\n\ninterface IStreamJsonHandlers {\n onTextDelta: (text: string) => void;\n onBackgroundTaskEvent: (event: TBackgroundTaskEvent) => void;\n onBackgroundJobGroupEvent: (event: TBackgroundJobGroupEvent) => void;\n onComplete: (result: IExecutionResult) => void;\n onInterrupted: (result: IExecutionResult) => void;\n onError: (error: Error) => void;\n}\n\nexport function writeStreamJsonEvent(\n session: IInteractiveSession,\n getSessionId: (s: IInteractiveSession) => string,\n event: TStreamJsonEvent,\n): void {\n const output = JSON.stringify({\n type: 'stream_event',\n event,\n session_id: getSessionId(session),\n uuid: randomUUID(),\n });\n process.stdout.write(output + '\\n');\n}\n\nexport function subscribeStreamJsonEvents(\n session: IInteractiveSession,\n getSessionId: (s: IInteractiveSession) => string,\n writeJsonResult: (sessionId: string, result: string, subtype: 'success' | 'error') => void,\n resolve: (exitCode: number) => void,\n): () => void {\n const emit = (event: TStreamJsonEvent): void =>\n writeStreamJsonEvent(session, getSessionId, event);\n\n const onTextDelta = (text: string): void =>\n emit({ type: 'content_block_delta', delta: { type: 'text_delta', text } });\n const onBackgroundTaskEvent = (event: TBackgroundTaskEvent): void =>\n emit({ type: 'background_task_event', background_task_event: event });\n const onBackgroundJobGroupEvent = (event: TBackgroundJobGroupEvent): void =>\n emit({ type: 'background_job_group_event', background_job_group_event: event });\n\n const cleanup = (): void =>\n unsubscribeStreamJsonEvents(session, {\n onTextDelta,\n onBackgroundTaskEvent,\n onBackgroundJobGroupEvent,\n onComplete,\n onInterrupted,\n onError,\n });\n\n const onComplete = (result: IExecutionResult): void => {\n cleanup();\n writeJsonResult(getSessionId(session), result.response, 'success');\n resolve(0);\n };\n const onInterrupted = (result: IExecutionResult): void => {\n cleanup();\n writeJsonResult(getSessionId(session), result.response, 'success');\n resolve(0);\n };\n const onError = (_error: Error): void => {\n cleanup();\n writeJsonResult(getSessionId(session), '', 'error');\n resolve(1);\n };\n\n session.on('text_delta', onTextDelta);\n session.on('background_task_event', onBackgroundTaskEvent);\n session.on('background_job_group_event', onBackgroundJobGroupEvent);\n session.on('complete', onComplete);\n session.on('interrupted', onInterrupted);\n session.on('error', onError);\n return cleanup;\n}\n\nfunction unsubscribeStreamJsonEvents(\n session: IInteractiveSession,\n handlers: IStreamJsonHandlers,\n): void {\n session.off('text_delta', handlers.onTextDelta);\n session.off('background_task_event', handlers.onBackgroundTaskEvent);\n session.off('background_job_group_event', handlers.onBackgroundJobGroupEvent);\n session.off('complete', handlers.onComplete);\n session.off('interrupted', handlers.onInterrupted);\n session.off('error', handlers.onError);\n}\n","import type { IInteractiveSession, IExecutionResult } from '@robota-sdk/agent-framework';\nimport { executeSlashCommandIfPresent, subscribeStreamJsonEvents } from './headless-stream-json.js';\n\nexport type TOutputFormat = 'text' | 'json' | 'stream-json';\n\nexport interface IHeadlessRunnerOptions {\n session: IInteractiveSession;\n outputFormat: TOutputFormat;\n}\n\nexport function createHeadlessRunner(options: IHeadlessRunnerOptions): {\n run: (prompt: string) => Promise<number>;\n} {\n const { session, outputFormat } = options;\n return {\n run: (prompt: string): Promise<number> => {\n if (outputFormat === 'text') return runTextFormat(session, prompt);\n if (outputFormat === 'json') return runJsonFormat(session, prompt);\n return runStreamJsonFormat(session, prompt);\n },\n };\n}\n\nexport function writeJsonResult(\n sessionId: string,\n result: string,\n subtype: 'success' | 'error',\n): void {\n const output = JSON.stringify({ type: 'result', result, session_id: sessionId, subtype });\n process.stdout.write(output + '\\n');\n}\n\nexport function getSessionId(session: IInteractiveSession): string {\n try {\n return session.getSession().getSessionId();\n } catch {\n // allow-fallback: session may not be initialized yet\n return '';\n }\n}\n\nfunction runTextFormat(session: IInteractiveSession, prompt: string): Promise<number> {\n return new Promise<number>((resolve) => {\n const cleanup = (): void => {\n session.off('complete', onComplete);\n session.off('interrupted', onInterrupted);\n session.off('error', onError);\n };\n const onComplete = (result: IExecutionResult): void => {\n cleanup();\n process.stdout.write(result.response + '\\n');\n resolve(0);\n };\n const onInterrupted = (result: IExecutionResult): void => {\n cleanup();\n if (result.response) process.stdout.write(result.response + '\\n');\n resolve(0);\n };\n const onError = (_error: Error): void => {\n cleanup();\n resolve(1);\n };\n\n session.on('complete', onComplete);\n session.on('interrupted', onInterrupted);\n session.on('error', onError);\n\n void executeSlashCommandIfPresent(session, prompt).then((cmd) => {\n if (cmd.kind === 'command-result') {\n cleanup();\n process.stdout.write(cmd.result.message + '\\n');\n resolve(cmd.result.success ? 0 : 1);\n return;\n }\n if (cmd.kind !== 'session-execution') void session.submit(prompt);\n });\n });\n}\n\nfunction runJsonFormat(session: IInteractiveSession, prompt: string): Promise<number> {\n return new Promise<number>((resolve) => {\n const cleanup = (): void => {\n session.off('complete', onComplete);\n session.off('interrupted', onInterrupted);\n session.off('error', onError);\n };\n const onComplete = (result: IExecutionResult): void => {\n cleanup();\n writeJsonResult(getSessionId(session), result.response, 'success');\n resolve(0);\n };\n const onInterrupted = (result: IExecutionResult): void => {\n cleanup();\n writeJsonResult(getSessionId(session), result.response, 'success');\n resolve(0);\n };\n const onError = (_error: Error): void => {\n cleanup();\n writeJsonResult(getSessionId(session), '', 'error');\n resolve(1);\n };\n\n session.on('complete', onComplete);\n session.on('interrupted', onInterrupted);\n session.on('error', onError);\n\n void executeSlashCommandIfPresent(session, prompt).then((cmd) => {\n if (cmd.kind === 'command-result') {\n cleanup();\n writeJsonResult(\n getSessionId(session),\n cmd.result.message,\n cmd.result.success ? 'success' : 'error',\n );\n resolve(cmd.result.success ? 0 : 1);\n return;\n }\n if (cmd.kind !== 'session-execution') void session.submit(prompt);\n });\n });\n}\n\nfunction runStreamJsonFormat(session: IInteractiveSession, prompt: string): Promise<number> {\n return new Promise<number>((resolve) => {\n const cleanup = subscribeStreamJsonEvents(session, getSessionId, writeJsonResult, resolve);\n\n void executeSlashCommandIfPresent(session, prompt).then((cmd) => {\n if (cmd.kind === 'command-result') {\n cleanup();\n writeJsonResult(\n getSessionId(session),\n cmd.result.message,\n cmd.result.success ? 'success' : 'error',\n );\n resolve(cmd.result.success ? 0 : 1);\n return;\n }\n if (cmd.kind !== 'session-execution') void session.submit(prompt);\n });\n });\n}\n","/**\n * ITransportAdapter implementation for headless transport.\n *\n * Wraps createHeadlessRunner into the unified ITransportAdapter interface.\n * After start() completes, getExitCode() returns the runner's exit code.\n */\n\nimport type { IInteractiveSession } from '@robota-sdk/agent-framework';\nimport type { ITransportAdapter } from '@robota-sdk/agent-interface-transport';\nimport { createHeadlessRunner } from './headless-runner.js';\nimport type { TOutputFormat } from './headless-runner.js';\n\nexport interface IHeadlessTransportOptions {\n /** Output format: 'text', 'json', or 'stream-json'. */\n outputFormat: TOutputFormat;\n /** The prompt to execute. */\n prompt: string;\n}\n\nexport function createHeadlessTransport(\n options: IHeadlessTransportOptions,\n): ITransportAdapter<IInteractiveSession> & { getExitCode(): number } {\n let session: IInteractiveSession | null = null;\n let exitCode = 0;\n\n return {\n name: 'headless',\n attach(s: IInteractiveSession) {\n session = s;\n },\n async start() {\n if (!session) throw new Error('No session attached. Call attach() first.');\n const runner = createHeadlessRunner({ session, outputFormat: options.outputFormat });\n exitCode = await runner.run(options.prompt);\n },\n async stop() {\n /* no-op: headless runner completes in start() */\n },\n getExitCode() {\n return exitCode;\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
require(`./tui-BIpIcT7-.cjs`);let e=require(`node:crypto`);function t(e){let t=e.trimStart();if(!t.startsWith(`/`))return null;let[n=``,...r]=t.slice(1).split(/\s+/);return n.length===0?null:{name:n,args:r.join(` `)}}async function n(e,n){let r=t(n);if(!r)return{kind:`not-slash`};let i=await e.executeCommand(r.name,r.args);return i?i.effects?.some(e=>e.type===`session-execution-started`)?{kind:`session-execution`}:{kind:`command-result`,result:i}:{kind:`command-result`,result:{message:`Unknown command "/${r.name}".`,success:!1}}}function r(t,n,r){let i=JSON.stringify({type:`stream_event`,event:r,session_id:n(t),uuid:(0,e.randomUUID)()});process.stdout.write(i+`
|
|
2
|
-
`)}function i(e,t,n,i){let o=n=>r(e,t,n),s=e=>o({type:`content_block_delta`,delta:{type:`text_delta`,text:e}}),c=e=>o({type:`background_task_event`,background_task_event:e}),l=e=>o({type:`background_job_group_event`,background_job_group_event:e}),u=()=>a(e,{onTextDelta:s,onBackgroundTaskEvent:c,onBackgroundJobGroupEvent:l,onComplete:d,onInterrupted:f,onError:p}),d=r=>{u(),n(t(e),r.response,`success`),i(0)},f=r=>{u(),n(t(e),r.response,`success`),i(0)},p=r=>{u(),n(t(e),``,`error`),i(1)};return e.on(`text_delta`,s),e.on(`background_task_event`,c),e.on(`background_job_group_event`,l),e.on(`complete`,d),e.on(`interrupted`,f),e.on(`error`,p),u}function a(e,t){e.off(`text_delta`,t.onTextDelta),e.off(`background_task_event`,t.onBackgroundTaskEvent),e.off(`background_job_group_event`,t.onBackgroundJobGroupEvent),e.off(`complete`,t.onComplete),e.off(`interrupted`,t.onInterrupted),e.off(`error`,t.onError)}function o(e){let{session:t,outputFormat:n}=e;return{run:e=>n===`text`?l(t,e):n===`json`?u(t,e):d(t,e)}}function s(e,t,n){let r=JSON.stringify({type:`result`,result:t,session_id:e,subtype:n});process.stdout.write(r+`
|
|
3
|
-
`)}function c(e){try{return e.getSession().getSessionId()}catch{return``}}function l(e,t){return new Promise(r=>{let i=()=>{e.off(`complete`,a),e.off(`interrupted`,o),e.off(`error`,s)},a=e=>{i(),process.stdout.write(e.response+`
|
|
4
|
-
`),r(0)},o=e=>{i(),e.response&&process.stdout.write(e.response+`
|
|
5
|
-
`),r(0)},s=e=>{i(),r(1)};e.on(`complete`,a),e.on(`interrupted`,o),e.on(`error`,s),n(e,t).then(n=>{if(n.kind===`command-result`){i(),process.stdout.write(n.result.message+`
|
|
6
|
-
`),r(+!n.result.success);return}n.kind!==`session-execution`&&e.submit(t)})})}function u(e,t){return new Promise(r=>{let i=()=>{e.off(`complete`,a),e.off(`interrupted`,o),e.off(`error`,l)},a=t=>{i(),s(c(e),t.response,`success`),r(0)},o=t=>{i(),s(c(e),t.response,`success`),r(0)},l=t=>{i(),s(c(e),``,`error`),r(1)};e.on(`complete`,a),e.on(`interrupted`,o),e.on(`error`,l),n(e,t).then(n=>{if(n.kind===`command-result`){i(),s(c(e),n.result.message,n.result.success?`success`:`error`),r(+!n.result.success);return}n.kind!==`session-execution`&&e.submit(t)})})}function d(e,t){return new Promise(r=>{let a=i(e,c,s,r);n(e,t).then(n=>{if(n.kind===`command-result`){a(),s(c(e),n.result.message,n.result.success?`success`:`error`),r(+!n.result.success);return}n.kind!==`session-execution`&&e.submit(t)})})}function f(e){let t=null,n=0;return{name:`headless`,attach(e){t=e},async start(){if(!t)throw Error(`No session attached. Call attach() first.`);n=await o({session:t,outputFormat:e.outputFormat}).run(e.prompt)},async stop(){},getExitCode(){return n}}}Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return f}});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
require(`./tui-BIpIcT7-.cjs`);let e=require(`hono`),t=require(`hono/streaming`);function n(n){let{sessionFactory:r}=n,i=new e.Hono;return i.post(`/submit`,async e=>{let n=await r(e),i=await e.req.json();return!i.prompt||typeof i.prompt!=`string`?e.json({error:`prompt is required`},400):(0,t.streamSSE)(e,async e=>{let t=[],r=(e,r)=>{n.on(e,r),t.push(()=>n.off(e,r))},a=!1,o=new Promise(t=>{r(`text_delta`,t=>{e.writeSSE({event:`text_delta`,data:JSON.stringify({delta:t})})}),r(`tool_start`,t=>{e.writeSSE({event:`tool_start`,data:JSON.stringify(t)})}),r(`tool_end`,t=>{e.writeSSE({event:`tool_end`,data:JSON.stringify(t)})}),r(`thinking`,n=>{e.writeSSE({event:`thinking`,data:JSON.stringify({isThinking:n})}),!n&&a&&t()}),r(`complete`,t=>{a=!0,e.writeSSE({event:`complete`,data:JSON.stringify(t)})}),r(`interrupted`,t=>{a=!0,e.writeSSE({event:`interrupted`,data:JSON.stringify(t)})}),r(`error`,t=>{a=!0,e.writeSSE({event:`error`,data:JSON.stringify({message:t.message})})})});await n.submit(i.prompt),await o;for(let e of t)e()})}),i.post(`/command`,async e=>{let t=await r(e),n=await e.req.json();if(!n.name||typeof n.name!=`string`)return e.json({error:`name is required`},400);let i=await t.executeCommand(n.name,n.args??``);return i?e.json(i):e.json({error:`Unknown command: ${n.name}`},404)}),i.post(`/abort`,async e=>((await r(e)).abort(),e.json({ok:!0}))),i.post(`/cancel-queue`,async e=>((await r(e)).cancelQueue(),e.json({ok:!0}))),i.get(`/messages`,async e=>{let t=await r(e);return e.json(t.getMessages())}),i.get(`/context`,async e=>{let t=await r(e);return e.json(t.getContextState())}),i.get(`/executing`,async e=>{let t=await r(e);return e.json({executing:t.isExecuting()})}),i.get(`/pending`,async e=>{let t=await r(e);return e.json({pending:t.getPendingPrompt()})}),i}function r(e){let t=null,r=null;return{name:`http`,attach(e){t=e},async start(){if(!t)throw Error(`No session attached. Call attach() first.`);r=n({sessionFactory:()=>t})},async stop(){r=null},getApp(){if(!r)throw Error(`Transport not started. Call start() first.`);return r}}}Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return r}});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http-DwO1AHG-.js","names":[],"sources":["../../src/http/routes.ts","../../src/http/http-transport.ts"],"sourcesContent":["/**\n * HTTP transport adapter — exposes IInteractiveSession over REST API.\n *\n * Built on Hono for Cloudflare Workers + Node.js + AWS Lambda compatibility.\n * Each endpoint maps 1:1 to an IInteractiveSession API method.\n */\n\nimport { Hono } from 'hono';\nimport { streamSSE } from 'hono/streaming';\nimport type { Context } from 'hono';\nimport type { IInteractiveSession } from '@robota-sdk/agent-framework';\n\n/** Callback that resolves an IInteractiveSession from the request context. */\nexport type TSessionFactory = (c: Context) => IInteractiveSession | Promise<IInteractiveSession>;\n\nexport interface IAgentRoutesOptions {\n /** Resolve an IInteractiveSession per request (e.g., by auth token, session ID). */\n sessionFactory: TSessionFactory;\n}\n\n/**\n * Create a Hono router with all agent HTTP endpoints.\n *\n * Usage:\n * ```typescript\n * const routes = createAgentRoutes({ sessionFactory });\n * app.route('/agent', routes); // mount on existing app\n * export default routes; // or use standalone (CF Workers)\n * ```\n */\nexport function createAgentRoutes(options: IAgentRoutesOptions): Hono {\n const { sessionFactory } = options;\n const app = new Hono();\n\n // POST /submit — execute prompt, stream events via SSE\n app.post('/submit', async (c) => {\n const session = await sessionFactory(c);\n const body = await c.req.json<{ prompt: string }>();\n\n if (!body.prompt || typeof body.prompt !== 'string') {\n return c.json({ error: 'prompt is required' }, 400);\n }\n\n return streamSSE(c, async (stream) => {\n const cleanup: Array<() => void> = [];\n\n const subscribe = <T>(event: string, handler: (data: T) => void): void => {\n session.on(event as 'text_delta', handler as () => void);\n cleanup.push(() => session.off(event as 'text_delta', handler as () => void));\n };\n\n let completed = false;\n const done = new Promise<void>((resolve) => {\n subscribe('text_delta', (delta: string) => {\n stream.writeSSE({ event: 'text_delta', data: JSON.stringify({ delta }) });\n });\n\n subscribe('tool_start', (state) => {\n stream.writeSSE({ event: 'tool_start', data: JSON.stringify(state) });\n });\n\n subscribe('tool_end', (state) => {\n stream.writeSSE({ event: 'tool_end', data: JSON.stringify(state) });\n });\n\n subscribe('thinking', (isThinking: boolean) => {\n stream.writeSSE({ event: 'thinking', data: JSON.stringify({ isThinking }) });\n if (!isThinking && completed) {\n resolve();\n }\n });\n\n subscribe('complete', (result) => {\n completed = true;\n stream.writeSSE({ event: 'complete', data: JSON.stringify(result) });\n });\n\n subscribe('interrupted', (result) => {\n completed = true;\n stream.writeSSE({ event: 'interrupted', data: JSON.stringify(result) });\n });\n\n subscribe('error', (error: Error) => {\n completed = true;\n stream.writeSSE({ event: 'error', data: JSON.stringify({ message: error.message }) });\n });\n });\n\n await session.submit(body.prompt);\n await done;\n\n for (const fn of cleanup) fn();\n });\n });\n\n // POST /command — execute system command\n app.post('/command', async (c) => {\n const session = await sessionFactory(c);\n const body = await c.req.json<{ name: string; args?: string }>();\n\n if (!body.name || typeof body.name !== 'string') {\n return c.json({ error: 'name is required' }, 400);\n }\n\n const result = await session.executeCommand(body.name, body.args ?? '');\n if (!result) {\n return c.json({ error: `Unknown command: ${body.name}` }, 404);\n }\n return c.json(result);\n });\n\n // POST /abort — abort current execution\n app.post('/abort', async (c) => {\n const session = await sessionFactory(c);\n session.abort();\n return c.json({ ok: true });\n });\n\n // POST /cancel-queue — cancel queued prompt\n app.post('/cancel-queue', async (c) => {\n const session = await sessionFactory(c);\n session.cancelQueue();\n return c.json({ ok: true });\n });\n\n // GET /messages — get message history\n app.get('/messages', async (c) => {\n const session = await sessionFactory(c);\n return c.json(session.getMessages());\n });\n\n // GET /context — get context window state\n app.get('/context', async (c) => {\n const session = await sessionFactory(c);\n return c.json(session.getContextState());\n });\n\n // GET /executing — check if currently executing\n app.get('/executing', async (c) => {\n const session = await sessionFactory(c);\n return c.json({ executing: session.isExecuting() });\n });\n\n // GET /pending — get pending queued prompt\n app.get('/pending', async (c) => {\n const session = await sessionFactory(c);\n return c.json({ pending: session.getPendingPrompt() });\n });\n\n return app;\n}\n","/**\n * ITransportAdapter implementation for HTTP transport.\n *\n * Wraps createAgentRoutes into the unified ITransportAdapter interface\n * while exposing the underlying Hono app via getApp().\n */\n\nimport type { ITransportAdapter } from '@robota-sdk/agent-interface-transport';\nimport type { IInteractiveSession } from '@robota-sdk/agent-framework';\n\nimport { createAgentRoutes } from './routes.js';\nimport type { Hono } from 'hono';\n\nexport interface IHttpTransportOptions {\n /** Optional: base path prefix for routes. */\n basePath?: string;\n}\n\nexport function createHttpTransport(\n options?: IHttpTransportOptions,\n): ITransportAdapter<IInteractiveSession> & { getApp(): Hono } {\n let session: IInteractiveSession | null = null;\n let app: Hono | null = null;\n\n return {\n name: 'http',\n attach(s: IInteractiveSession) {\n session = s;\n },\n async start() {\n if (!session) throw new Error('No session attached. Call attach() first.');\n app = createAgentRoutes({ sessionFactory: () => session! });\n },\n async stop() {\n app = null;\n },\n getApp() {\n if (!app) throw new Error('Transport not started. Call start() first.');\n return app;\n },\n };\n}\n"],"mappings":"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"}
|