@robota-sdk/agent-transport 3.0.0-beta.64
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/LICENSE +21 -0
- package/dist/node/headless/index.cjs +1 -0
- package/dist/node/headless/index.d.ts +2 -0
- package/dist/node/headless/index.js +1 -0
- package/dist/node/headless-CWEpJXFK.js +7 -0
- package/dist/node/headless-CWEpJXFK.js.map +1 -0
- package/dist/node/headless-CsZFelG9.cjs +6 -0
- package/dist/node/http/index.cjs +1 -0
- package/dist/node/http/index.d.ts +2 -0
- package/dist/node/http/index.js +1 -0
- package/dist/node/http-CM3TJhrF.cjs +1 -0
- package/dist/node/http-DwO1AHG-.js +2 -0
- package/dist/node/http-DwO1AHG-.js.map +1 -0
- package/dist/node/index--Ti9NzQX.d.ts +64 -0
- package/dist/node/index--Ti9NzQX.d.ts.map +1 -0
- package/dist/node/index-B_rcr14p.d.ts +47 -0
- package/dist/node/index-B_rcr14p.d.ts.map +1 -0
- package/dist/node/index-C9LWCL4l.d.ts +34 -0
- package/dist/node/index-C9LWCL4l.d.ts.map +1 -0
- package/dist/node/index-CAr3ioVh.d.ts +64 -0
- package/dist/node/index-CAr3ioVh.d.ts.map +1 -0
- package/dist/node/index-CEs25wVk.d.ts +213 -0
- package/dist/node/index-CEs25wVk.d.ts.map +1 -0
- package/dist/node/index-CvXLpjJO.d.ts +213 -0
- package/dist/node/index-CvXLpjJO.d.ts.map +1 -0
- package/dist/node/index-D34WUfFH.d.ts +26 -0
- package/dist/node/index-D34WUfFH.d.ts.map +1 -0
- package/dist/node/index-Y0zHb1Bz.d.ts +47 -0
- package/dist/node/index-Y0zHb1Bz.d.ts.map +1 -0
- package/dist/node/index-k3TUjA-T.d.ts +26 -0
- package/dist/node/index-k3TUjA-T.d.ts.map +1 -0
- package/dist/node/index-nBlMTFkZ.d.ts +34 -0
- package/dist/node/index-nBlMTFkZ.d.ts.map +1 -0
- package/dist/node/index.cjs +1 -0
- package/dist/node/index.d.ts +6 -0
- package/dist/node/index.js +1 -0
- package/dist/node/mcp/index.cjs +1 -0
- package/dist/node/mcp/index.d.ts +2 -0
- package/dist/node/mcp/index.js +1 -0
- package/dist/node/mcp-BXBwF6Wu.js +2 -0
- package/dist/node/mcp-BXBwF6Wu.js.map +1 -0
- package/dist/node/mcp-DcHuGokt.cjs +1 -0
- package/dist/node/tui/index.cjs +1 -0
- package/dist/node/tui/index.d.ts +2 -0
- package/dist/node/tui/index.js +1 -0
- package/dist/node/tui-CeD_6rSo.cjs +24 -0
- package/dist/node/tui-zmDTPk4b.js +25 -0
- package/dist/node/tui-zmDTPk4b.js.map +1 -0
- package/dist/node/ws/index.cjs +1 -0
- package/dist/node/ws/index.d.ts +2 -0
- package/dist/node/ws/index.js +1 -0
- package/dist/node/ws-B-oRccFl.js +2 -0
- package/dist/node/ws-B-oRccFl.js.map +1 -0
- package/dist/node/ws-COnIgnmn.cjs +1 -0
- package/package.json +141 -0
- package/src/headless/__tests__/headless-runner-initialization.test.ts +45 -0
- package/src/headless/__tests__/headless-runner.test.ts +484 -0
- package/src/headless/__tests__/headless-skill-activation.integration.test.ts +430 -0
- package/src/headless/__tests__/headless-transport.test.ts +268 -0
- package/src/headless/headless-runner.ts +141 -0
- package/src/headless/headless-stream-json.ts +142 -0
- package/src/headless/headless-transport.ts +43 -0
- package/src/headless/index.ts +4 -0
- package/src/http/__tests__/http-transport.test.ts +55 -0
- package/src/http/__tests__/routes.test.ts +168 -0
- package/src/http/http-transport.ts +42 -0
- package/src/http/index.ts +4 -0
- package/src/http/routes.ts +151 -0
- package/src/index.ts +5 -0
- package/src/mcp/__tests__/mcp-server.test.ts +66 -0
- package/src/mcp/__tests__/mcp-transport.test.ts +46 -0
- package/src/mcp/index.ts +4 -0
- package/src/mcp/mcp-server.ts +162 -0
- package/src/mcp/mcp-transport.ts +48 -0
- package/src/tui/App.tsx +478 -0
- package/src/tui/BackgroundTaskPanel.tsx +34 -0
- package/src/tui/CjkTextInput.tsx +204 -0
- package/src/tui/ConfirmPrompt.tsx +69 -0
- package/src/tui/ExecutionWorkspaceDetailPane.tsx +62 -0
- package/src/tui/ExecutionWorkspaceSwitcher.tsx +185 -0
- package/src/tui/InkTerminal.ts +42 -0
- package/src/tui/InputArea.tsx +298 -0
- package/src/tui/InteractivePrompt.tsx +57 -0
- package/src/tui/ListPicker.tsx +94 -0
- package/src/tui/MenuSelect.tsx +103 -0
- package/src/tui/MessageList.tsx +282 -0
- package/src/tui/PermissionPrompt.tsx +84 -0
- package/src/tui/PluginTUI.tsx +256 -0
- package/src/tui/SessionPicker.tsx +66 -0
- package/src/tui/SessionStatusBar.tsx +66 -0
- package/src/tui/SlashAutocomplete.tsx +110 -0
- package/src/tui/StatusBar.tsx +213 -0
- package/src/tui/StreamingIndicator.tsx +91 -0
- package/src/tui/TextPrompt.tsx +80 -0
- package/src/tui/ToolCommandOutput.tsx +37 -0
- package/src/tui/ToolDiffBlock.tsx +30 -0
- package/src/tui/TransportTUI.tsx +116 -0
- package/src/tui/UpdateNotice.tsx +14 -0
- package/src/tui/UsageSummaryEntry.tsx +38 -0
- package/src/tui/WaveText.tsx +44 -0
- package/src/tui/__tests__/InteractivePrompt.test.tsx +82 -0
- package/src/tui/__tests__/ListPicker.test.tsx +159 -0
- package/src/tui/__tests__/MenuSelect.test.tsx +103 -0
- package/src/tui/__tests__/PluginTUI.test.tsx +167 -0
- package/src/tui/__tests__/SlashAutocomplete.test.tsx +140 -0
- package/src/tui/__tests__/TextPrompt.test.tsx +98 -0
- package/src/tui/__tests__/UpdateNotice.test.tsx +15 -0
- package/src/tui/__tests__/abort-after-permission.test.tsx +169 -0
- package/src/tui/__tests__/abort-streaming-e2e.test.tsx +183 -0
- package/src/tui/__tests__/background-task-panel.test.tsx +53 -0
- package/src/tui/__tests__/background-task-row-format.test.ts +59 -0
- package/src/tui/__tests__/cjk-text-input-flow.test.ts +109 -0
- package/src/tui/__tests__/cjk-text-input.test.ts +191 -0
- package/src/tui/__tests__/command-effect-handler.test.ts +128 -0
- package/src/tui/__tests__/command-output-summary.test.ts +95 -0
- package/src/tui/__tests__/compact-event-bridge.test.ts +20 -0
- package/src/tui/__tests__/confirm-permission-flow.test.ts +91 -0
- package/src/tui/__tests__/confirm-prompt.test.tsx +87 -0
- package/src/tui/__tests__/execution-workspace-switcher.test.tsx +110 -0
- package/src/tui/__tests__/execution-workspace-view-model.test.ts +93 -0
- package/src/tui/__tests__/fixtures/provider-setup-prompt-driver.tsx +122 -0
- package/src/tui/__tests__/input-area-flow.test.ts +152 -0
- package/src/tui/__tests__/message-list-rendering.test.tsx +353 -0
- package/src/tui/__tests__/model-change-side-effect.test.ts +91 -0
- package/src/tui/__tests__/prompt-queue.test.tsx +255 -0
- package/src/tui/__tests__/provider-setup-pty-e2e.test.ts +233 -0
- package/src/tui/__tests__/render-markdown.test.ts +72 -0
- package/src/tui/__tests__/selection-flow.test.ts +61 -0
- package/src/tui/__tests__/slash-routing-effects.test.ts +225 -0
- package/src/tui/__tests__/status-activity.test.ts +71 -0
- package/src/tui/__tests__/status-bar.test.tsx +157 -0
- package/src/tui/__tests__/streaming-indicator.test.tsx +137 -0
- package/src/tui/__tests__/text-prompt-flow.test.ts +77 -0
- package/src/tui/__tests__/tui-state-manager.test.ts +401 -0
- package/src/tui/background-task-row-format.ts +52 -0
- package/src/tui/command-output-summary.ts +122 -0
- package/src/tui/execution-workspace-view-model.ts +123 -0
- package/src/tui/flows/cjk-text-input-flow.ts +285 -0
- package/src/tui/flows/confirm-prompt-flow.ts +45 -0
- package/src/tui/flows/input-area-flow.ts +186 -0
- package/src/tui/flows/permission-prompt-flow.ts +76 -0
- package/src/tui/flows/selection-flow.ts +126 -0
- package/src/tui/flows/text-prompt-flow.ts +98 -0
- package/src/tui/hooks/command-effect-handler.ts +98 -0
- package/src/tui/hooks/command-effect-queue.ts +39 -0
- package/src/tui/hooks/model-change-side-effect.ts +63 -0
- package/src/tui/hooks/side-effects-types.ts +38 -0
- package/src/tui/hooks/use-interactive-session-init.ts +50 -0
- package/src/tui/hooks/useAutocomplete.ts +85 -0
- package/src/tui/hooks/useInteractiveSession.ts +273 -0
- package/src/tui/hooks/usePermissionQueue.ts +51 -0
- package/src/tui/hooks/usePluginCallbacks.ts +30 -0
- package/src/tui/hooks/usePluginScreenData.ts +84 -0
- package/src/tui/hooks/useSideEffects.ts +210 -0
- package/src/tui/hooks/useSlashRouting.ts +117 -0
- package/src/tui/hooks/useStatusLineSettings.ts +35 -0
- package/src/tui/index.ts +3 -0
- package/src/tui/plugin-tui-handlers.ts +163 -0
- package/src/tui/render-markdown.ts +129 -0
- package/src/tui/render.tsx +60 -0
- package/src/tui/status-activity.ts +63 -0
- package/src/tui/tui-cli-adapter-context.tsx +12 -0
- package/src/tui/tui-cli-adapter.ts +25 -0
- package/src/tui/tui-state-manager.ts +225 -0
- package/src/tui/tui-transport.ts +32 -0
- package/src/tui/types.ts +14 -0
- package/src/tui/utils/__tests__/edit-diff.test.ts +426 -0
- package/src/tui/utils/__tests__/paste-detection.test.ts +116 -0
- package/src/tui/utils/__tests__/paste-labels.test.ts +46 -0
- package/src/tui/utils/__tests__/tool-call-extractor.test.ts +227 -0
- package/src/tui/utils/__tests__/tool-diff-summary.test.ts +104 -0
- package/src/tui/utils/edit-diff.ts +152 -0
- package/src/tui/utils/paste-labels.ts +9 -0
- package/src/tui/utils/tool-call-extractor.ts +91 -0
- package/src/tui/utils/tool-diff-summary.ts +75 -0
- package/src/ws/__tests__/ws-handler.test.ts +407 -0
- package/src/ws/__tests__/ws-transport.test.ts +53 -0
- package/src/ws/index.ts +13 -0
- package/src/ws/ws-background-messages.ts +170 -0
- package/src/ws/ws-handler.ts +279 -0
- package/src/ws/ws-protocol.ts +76 -0
- package/src/ws/ws-transport-configurable.ts +123 -0
- package/src/ws/ws-transport.ts +42 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../ws-COnIgnmn.cjs`);exports.WsTransport=e.t,exports.createWsHandler=e.r,exports.createWsTransport=e.n;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as IWsTransportConfig, c as createWsTransport, d as TClientMessage, f as TServerMessage, i as TExecutionWorkspaceStatus, l as IWsHandlerOptions, n as IExecutionWorkspaceSnapshot, o as WsTransport, r as TExecutionAttention, s as IWsTransportOptions, t as IExecutionWorkspaceEntry, u as createWsHandler } from "../index-CvXLpjJO.js";
|
|
2
|
+
export { type IExecutionWorkspaceEntry, type IExecutionWorkspaceSnapshot, type IWsHandlerOptions, type IWsTransportConfig, type IWsTransportOptions, type TClientMessage, type TExecutionAttention, type TExecutionWorkspaceStatus, type TServerMessage, WsTransport, createWsHandler, createWsTransport };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e,r as t,t as n}from"../ws-B-oRccFl.js";export{n as WsTransport,t as createWsHandler,e as createWsTransport};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createServer as e}from"node:http";import{WebSocket as t,WebSocketServer as n}from"ws";function r(e,t,n){if(n.type===`get-background-tasks`){t({type:`background_tasks`,tasks:e.listBackgroundTasks(n.filter)});return}if(n.type===`get-background-task`){a(e,t,n);return}if(n.type===`get-background-job-groups`){t({type:`background_job_groups`,groups:e.listBackgroundJobGroups()});return}if(n.type===`get-background-job-group`){s(e,t,n);return}if(n.type===`wait-background-job-group`){c(e,t,n);return}o(e,t,n)}function i(e,t,n){if(!n.taskId){t({type:`protocol_error`,message:`taskId is required`});return}if(n.type===`cancel-background-task`){u(t,`cancel`,n.taskId,e.cancelBackgroundTask(n.taskId,n.reason));return}if(n.type===`close-background-task`){u(t,`close`,n.taskId,e.closeBackgroundTask(n.taskId));return}l(e,t,n)}function a(e,t,n){if(!n.taskId){t({type:`protocol_error`,message:`taskId is required`});return}t({type:`background_task`,taskId:n.taskId,task:e.getBackgroundTask(n.taskId)??null})}function o(e,t,n){if(!n.taskId){t({type:`protocol_error`,message:`taskId is required`});return}e.readBackgroundTaskLog(n.taskId,n.cursor).then(e=>t({type:`background_task_log`,taskId:n.taskId,page:e}),e=>t({type:`protocol_error`,message:e.message}))}function s(e,t,n){if(!n.groupId){t({type:`protocol_error`,message:`groupId is required`});return}t({type:`background_job_group`,groupId:n.groupId,group:e.getBackgroundJobGroup(n.groupId)??null})}function c(e,t,n){if(!n.groupId){t({type:`protocol_error`,message:`groupId is required`});return}e.waitBackgroundJobGroup(n.groupId).then(e=>t({type:`background_job_group`,groupId:n.groupId,group:e}),e=>t({type:`protocol_error`,message:e.message}))}function l(e,t,n){if(!n.input){t({type:`protocol_error`,message:`input is required`});return}u(t,`send`,n.taskId,e.sendBackgroundTask(n.taskId,n.input))}function u(e,t,n,r){r.then(()=>e({type:`background_task_control_result`,action:t,taskId:n,success:!0}),r=>e({type:`background_task_control_result`,action:t,taskId:n,success:!1,message:r.message}))}function d(e){let t=f(e.session,e.send);return{onMessage:p(e.session,e.send),cleanup:t}}function f(e,t){let n=e=>t({type:`user_message`,content:e}),r=e=>t({type:`text_delta`,delta:e}),i=e=>t({type:`tool_start`,state:e}),a=e=>t({type:`tool_end`,state:e}),o=e=>t({type:`thinking`,isThinking:e}),s=e=>t({type:`complete`,result:e}),c=e=>t({type:`interrupted`,result:e}),l=e=>t({type:`error`,message:e.message}),u=e=>t({type:`background_task_event`,event:e}),d=e=>t({type:`background_job_group_event`,event:e}),f=e=>t({type:`execution_workspace_event`,snapshot:e.snapshot});return e.on(`user_message`,n),e.on(`text_delta`,r),e.on(`tool_start`,i),e.on(`tool_end`,a),e.on(`thinking`,o),e.on(`complete`,s),e.on(`interrupted`,c),e.on(`error`,l),e.on(`background_task_event`,u),e.on(`background_job_group_event`,d),e.on(`execution_workspace_event`,f),()=>{e.off(`user_message`,n),e.off(`text_delta`,r),e.off(`tool_start`,i),e.off(`tool_end`,a),e.off(`thinking`,o),e.off(`complete`,s),e.off(`interrupted`,c),e.off(`error`,l),e.off(`background_task_event`,u),e.off(`background_job_group_event`,d),e.off(`execution_workspace_event`,f)}}function p(e,t){return n=>{let r=m(n,t);r&&h(e,t,r)}}function m(e,t){try{return JSON.parse(e)}catch{return t({type:`protocol_error`,message:`Invalid JSON`}),null}}function h(e,t,n){if(_(n)){x(e,t,n);return}if(v(n)){S(e,t,n);return}if(y(n)){r(e,t,n);return}if(b(n)){i(e,t,n);return}t({type:`protocol_error`,message:`Unknown message type: ${g(n)}`})}function g(e){return e.type}function _(e){return e.type===`submit`||e.type===`command`||e.type===`abort`||e.type===`cancel-queue`}function v(e){return e.type===`get-messages`||e.type===`get-context`||e.type===`get-executing`||e.type===`get-pending`||e.type===`get-execution-workspace`}function y(e){return e.type===`get-background-tasks`||e.type===`get-background-task`||e.type===`read-background-task-log`||e.type===`get-background-job-groups`||e.type===`get-background-job-group`||e.type===`wait-background-job-group`}function b(e){return e.type===`cancel-background-task`||e.type===`close-background-task`||e.type===`send-background-task`}function x(e,t,n){if(n.type===`submit`){if(!n.prompt){t({type:`protocol_error`,message:`prompt is required`});return}e.submit(n.prompt)}else if(n.type===`command`){if(!n.name){t({type:`protocol_error`,message:`name is required`});return}e.executeCommand(n.name,n.args??``).then(e=>{t({type:`command_result`,name:n.name,message:e?.message??`Unknown command: ${n.name}`,success:e?.success??!1,data:e?.data})})}else n.type===`abort`?e.abort():e.cancelQueue()}function S(e,t,n){n.type===`get-messages`?t({type:`messages`,messages:e.getMessages()}):n.type===`get-context`?t({type:`context`,state:e.getContextState()}):n.type===`get-executing`?t({type:`executing`,executing:e.isExecuting()}):n.type===`get-execution-workspace`?t({type:`execution_workspace_event`,snapshot:e.getExecutionWorkspaceSnapshot()}):t({type:`pending`,pending:e.getPendingPrompt()})}function C(e){let t=null,n=null;return{name:`ws`,onMessage:null,attach(e){t=e},async start(){if(!t)throw Error(`No session attached. Call attach() first.`);let r=d({session:t,send:e.send});n=r.cleanup,this.onMessage=r.onMessage},async stop(){n?.(),n=null,this.onMessage=null}}}const w=7070;var T=class{name=`ws`;defaultEnabled=!0;optionsSchema={port:{type:`number`,description:`WebSocket server port`,default:w},maxRetries:{type:`number`,description:`Port retry attempts when port is occupied`,default:20}};session=null;stopFn=null;port;maxRetries;constructor(e={}){this.port=e.port??w,this.maxRetries=e.maxRetries??20}attach(e){this.session=e}async start(){if(!this.session)throw Error(`WsTransport: attach() must be called before start()`);let e=await this.bindWithRetry(this.session,this.port,this.maxRetries);this.stopFn=e.stop}async stop(){await this.stopFn?.(),this.stopFn=null}validateOptions(e){let{port:t,maxRetries:n}=e;return!(t!==void 0&&(typeof t!=`number`||t<1||t>65535)||n!==void 0&&(typeof n!=`number`||n<0))}bindWithRetry(e,t,n){return this.tryBind(e,t).catch(r=>{if(r.code===`EADDRINUSE`&&n>0)return this.bindWithRetry(e,t+1,n-1);throw r})}tryBind(r,i){return new Promise((a,o)=>{let s=e((e,t)=>{t.writeHead(400).end(`WebSocket endpoint`)});s.on(`error`,e=>{s.close(),o(e)}),s.listen(i,`127.0.0.1`,()=>{let e=new n({server:s});e.on(`connection`,e=>{let n=n=>{e.readyState===t.OPEN&&e.send(JSON.stringify(n))},{onMessage:i,cleanup:a}=d({session:r,send:n});e.on(`message`,e=>i(String(e))),e.on(`close`,a),e.on(`error`,a),n({type:`messages`,messages:r.getMessages()}),n({type:`execution_workspace_event`,snapshot:r.getExecutionWorkspaceSnapshot()})}),a({stop:()=>new Promise(t=>{e.close(()=>s.close(()=>t()))})})})})}};export{C as n,d as r,T as t};
|
|
2
|
+
//# sourceMappingURL=ws-B-oRccFl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-B-oRccFl.js","names":[],"sources":["../../src/ws/ws-background-messages.ts","../../src/ws/ws-handler.ts","../../src/ws/ws-transport.ts","../../src/ws/ws-transport-configurable.ts"],"sourcesContent":["import type { IInteractiveSession } from '@robota-sdk/agent-framework';\nimport type { TBackgroundControlAction, TClientMessage, TServerMessage } from './ws-protocol.js';\n\nexport function handleBackgroundQueryMessage(\n session: IInteractiveSession,\n send: (message: TServerMessage) => void,\n msg: Extract<\n TClientMessage,\n | { type: 'get-background-tasks' | 'get-background-task' | 'read-background-task-log' }\n | {\n type:\n | 'get-background-job-groups'\n | 'get-background-job-group'\n | 'wait-background-job-group';\n }\n >,\n): void {\n if (msg.type === 'get-background-tasks') {\n send({ type: 'background_tasks', tasks: session.listBackgroundTasks(msg.filter) });\n return;\n }\n if (msg.type === 'get-background-task') {\n sendBackgroundTaskSnapshot(session, send, msg);\n return;\n }\n if (msg.type === 'get-background-job-groups') {\n send({ type: 'background_job_groups', groups: session.listBackgroundJobGroups() });\n return;\n }\n if (msg.type === 'get-background-job-group') {\n sendBackgroundJobGroupSnapshot(session, send, msg);\n return;\n }\n if (msg.type === 'wait-background-job-group') {\n sendBackgroundJobGroupWaitResult(session, send, msg);\n return;\n }\n sendBackgroundTaskLogPage(session, send, msg);\n}\n\nexport function handleBackgroundControlMessage(\n session: IInteractiveSession,\n send: (message: TServerMessage) => void,\n msg: Extract<\n TClientMessage,\n { type: 'cancel-background-task' | 'close-background-task' | 'send-background-task' }\n >,\n): void {\n if (!msg.taskId) {\n send({ type: 'protocol_error', message: 'taskId is required' });\n return;\n }\n if (msg.type === 'cancel-background-task') {\n sendBackgroundTaskControlResult(\n send,\n 'cancel',\n msg.taskId,\n session.cancelBackgroundTask(msg.taskId, msg.reason),\n );\n return;\n }\n if (msg.type === 'close-background-task') {\n sendBackgroundTaskControlResult(\n send,\n 'close',\n msg.taskId,\n session.closeBackgroundTask(msg.taskId),\n );\n return;\n }\n sendBackgroundTaskInput(session, send, msg);\n}\n\nfunction sendBackgroundTaskSnapshot(\n session: IInteractiveSession,\n send: (message: TServerMessage) => void,\n msg: Extract<TClientMessage, { type: 'get-background-task' }>,\n): void {\n if (!msg.taskId) {\n send({ type: 'protocol_error', message: 'taskId is required' });\n return;\n }\n send({\n type: 'background_task',\n taskId: msg.taskId,\n task: session.getBackgroundTask(msg.taskId) ?? null,\n });\n}\n\nfunction sendBackgroundTaskLogPage(\n session: IInteractiveSession,\n send: (message: TServerMessage) => void,\n msg: Extract<TClientMessage, { type: 'read-background-task-log' }>,\n): void {\n if (!msg.taskId) {\n send({ type: 'protocol_error', message: 'taskId is required' });\n return;\n }\n session.readBackgroundTaskLog(msg.taskId, msg.cursor).then(\n (page) => send({ type: 'background_task_log', taskId: msg.taskId, page }),\n (error: Error) => send({ type: 'protocol_error', message: error.message }),\n );\n}\n\nfunction sendBackgroundJobGroupSnapshot(\n session: IInteractiveSession,\n send: (message: TServerMessage) => void,\n msg: Extract<TClientMessage, { type: 'get-background-job-group' }>,\n): void {\n if (!msg.groupId) {\n send({ type: 'protocol_error', message: 'groupId is required' });\n return;\n }\n send({\n type: 'background_job_group',\n groupId: msg.groupId,\n group: session.getBackgroundJobGroup(msg.groupId) ?? null,\n });\n}\n\nfunction sendBackgroundJobGroupWaitResult(\n session: IInteractiveSession,\n send: (message: TServerMessage) => void,\n msg: Extract<TClientMessage, { type: 'wait-background-job-group' }>,\n): void {\n if (!msg.groupId) {\n send({ type: 'protocol_error', message: 'groupId is required' });\n return;\n }\n session.waitBackgroundJobGroup(msg.groupId).then(\n (group) => send({ type: 'background_job_group', groupId: msg.groupId, group }),\n (error: Error) => send({ type: 'protocol_error', message: error.message }),\n );\n}\n\nfunction sendBackgroundTaskInput(\n session: IInteractiveSession,\n send: (message: TServerMessage) => void,\n msg: Extract<TClientMessage, { type: 'send-background-task' }>,\n): void {\n if (!msg.input) {\n send({ type: 'protocol_error', message: 'input is required' });\n return;\n }\n sendBackgroundTaskControlResult(\n send,\n 'send',\n msg.taskId,\n session.sendBackgroundTask(msg.taskId, msg.input),\n );\n}\n\nfunction sendBackgroundTaskControlResult(\n send: (message: TServerMessage) => void,\n action: TBackgroundControlAction,\n taskId: string,\n operation: Promise<void>,\n): void {\n operation.then(\n () => send({ type: 'background_task_control_result', action, taskId, success: true }),\n (error: Error) =>\n send({\n type: 'background_task_control_result',\n action,\n taskId,\n success: false,\n message: error.message,\n }),\n );\n}\n","/**\n * WebSocket transport adapter — exposes IInteractiveSession over WebSocket.\n *\n * Framework-agnostic: works with any WebSocket implementation via\n * send/onMessage callbacks. No dependency on ws, uWebSockets, etc.\n *\n * Protocol: JSON messages with { type, ...payload } structure.\n * Server pushes IInteractiveSession events to client in real-time.\n */\n\nimport type {\n IInteractiveSession,\n IExecutionResult,\n IExecutionWorkspaceEvent,\n TBackgroundJobGroupEvent,\n TBackgroundTaskEvent,\n IToolState,\n} from '@robota-sdk/agent-framework';\nimport type { TClientMessage, TServerMessage } from './ws-protocol.js';\nimport {\n handleBackgroundControlMessage,\n handleBackgroundQueryMessage,\n} from './ws-background-messages.js';\n\nexport interface IWsHandlerOptions {\n /** IInteractiveSession to expose. */\n session: IInteractiveSession;\n /** Send a JSON message to the client. */\n send: (message: TServerMessage) => void;\n}\n\n/**\n * Create a WebSocket message handler for an IInteractiveSession.\n *\n * Returns:\n * - `onMessage(data)`: call this when the WebSocket receives a message\n * - `cleanup()`: call this when the WebSocket disconnects\n *\n * Usage:\n * ```typescript\n * const { onMessage, cleanup } = createWsHandler({\n * session: interactiveSession,\n * send: (msg) => ws.send(JSON.stringify(msg)),\n * });\n *\n * ws.on('message', (data) => onMessage(String(data)));\n * ws.on('close', cleanup);\n * ```\n */\nexport function createWsHandler(options: IWsHandlerOptions): {\n onMessage: (data: string) => void;\n cleanup: () => void;\n} {\n const cleanup = subscribeSessionEvents(options.session, options.send);\n const onMessage = createWsMessageHandler(options.session, options.send);\n\n return { onMessage, cleanup };\n}\n\nfunction subscribeSessionEvents(\n session: IInteractiveSession,\n send: (message: TServerMessage) => void,\n): () => void {\n const onUserMessage = (content: string): void => send({ type: 'user_message', content });\n const onTextDelta = (delta: string): void => send({ type: 'text_delta', delta });\n const onToolStart = (state: IToolState): void => send({ type: 'tool_start', state });\n const onToolEnd = (state: IToolState): void => send({ type: 'tool_end', state });\n const onThinking = (isThinking: boolean): void => send({ type: 'thinking', isThinking });\n const onComplete = (result: IExecutionResult): void => send({ type: 'complete', result });\n const onInterrupted = (result: IExecutionResult): void => send({ type: 'interrupted', result });\n const onError = (error: Error): void => send({ type: 'error', message: error.message });\n const onBackgroundTaskEvent = (event: TBackgroundTaskEvent): void =>\n send({ type: 'background_task_event', event });\n const onBackgroundJobGroupEvent = (event: TBackgroundJobGroupEvent): void =>\n send({ type: 'background_job_group_event', event });\n const onExecutionWorkspace = (event: IExecutionWorkspaceEvent): void =>\n send({ type: 'execution_workspace_event', snapshot: event.snapshot });\n\n session.on('user_message', onUserMessage);\n session.on('text_delta', onTextDelta);\n session.on('tool_start', onToolStart);\n session.on('tool_end', onToolEnd);\n session.on('thinking', onThinking);\n session.on('complete', onComplete);\n session.on('interrupted', onInterrupted);\n session.on('error', onError);\n session.on('background_task_event', onBackgroundTaskEvent);\n session.on('background_job_group_event', onBackgroundJobGroupEvent);\n session.on('execution_workspace_event', onExecutionWorkspace);\n\n return (): void => {\n session.off('user_message', onUserMessage);\n session.off('text_delta', onTextDelta);\n session.off('tool_start', onToolStart);\n session.off('tool_end', onToolEnd);\n session.off('thinking', onThinking);\n session.off('complete', onComplete);\n session.off('interrupted', onInterrupted);\n session.off('error', onError);\n session.off('background_task_event', onBackgroundTaskEvent);\n session.off('background_job_group_event', onBackgroundJobGroupEvent);\n session.off('execution_workspace_event', onExecutionWorkspace);\n };\n}\n\nfunction createWsMessageHandler(\n session: IInteractiveSession,\n send: (message: TServerMessage) => void,\n): (data: string) => void {\n return (data: string): void => {\n const msg = parseClientMessage(data, send);\n if (!msg) return;\n handleClientMessage(session, send, msg);\n };\n}\n\nfunction parseClientMessage(\n data: string,\n send: (message: TServerMessage) => void,\n): TClientMessage | null {\n try {\n return JSON.parse(data) as TClientMessage;\n } catch {\n send({ type: 'protocol_error', message: 'Invalid JSON' });\n return null;\n }\n}\n\nfunction handleClientMessage(\n session: IInteractiveSession,\n send: (message: TServerMessage) => void,\n msg: TClientMessage,\n): void {\n if (isSessionControlMessage(msg)) {\n handleSessionControlMessage(session, send, msg);\n return;\n }\n if (isSessionQueryMessage(msg)) {\n handleSessionQueryMessage(session, send, msg);\n return;\n }\n if (isBackgroundQueryMessage(msg)) {\n handleBackgroundQueryMessage(session, send, msg);\n return;\n }\n if (isBackgroundControlMessage(msg)) {\n handleBackgroundControlMessage(session, send, msg);\n return;\n }\n send({ type: 'protocol_error', message: `Unknown message type: ${getMessageType(msg)}` });\n}\n\nfunction getMessageType(msg: TClientMessage): string {\n return (msg as { type: string }).type;\n}\n\nfunction isSessionControlMessage(\n msg: TClientMessage,\n): msg is Extract<TClientMessage, { type: 'submit' | 'command' | 'abort' | 'cancel-queue' }> {\n return (\n msg.type === 'submit' ||\n msg.type === 'command' ||\n msg.type === 'abort' ||\n msg.type === 'cancel-queue'\n );\n}\n\nfunction isSessionQueryMessage(msg: TClientMessage): msg is Extract<\n TClientMessage,\n {\n type:\n | 'get-messages'\n | 'get-context'\n | 'get-executing'\n | 'get-pending'\n | 'get-execution-workspace';\n }\n> {\n return (\n msg.type === 'get-messages' ||\n msg.type === 'get-context' ||\n msg.type === 'get-executing' ||\n msg.type === 'get-pending' ||\n msg.type === 'get-execution-workspace'\n );\n}\n\nfunction isBackgroundQueryMessage(\n msg: TClientMessage,\n): msg is Extract<\n TClientMessage,\n | { type: 'get-background-tasks' | 'get-background-task' | 'read-background-task-log' }\n | { type: 'get-background-job-groups' | 'get-background-job-group' | 'wait-background-job-group' }\n> {\n return (\n msg.type === 'get-background-tasks' ||\n msg.type === 'get-background-task' ||\n msg.type === 'read-background-task-log' ||\n msg.type === 'get-background-job-groups' ||\n msg.type === 'get-background-job-group' ||\n msg.type === 'wait-background-job-group'\n );\n}\n\nfunction isBackgroundControlMessage(\n msg: TClientMessage,\n): msg is Extract<\n TClientMessage,\n { type: 'cancel-background-task' | 'close-background-task' | 'send-background-task' }\n> {\n return (\n msg.type === 'cancel-background-task' ||\n msg.type === 'close-background-task' ||\n msg.type === 'send-background-task'\n );\n}\n\nfunction handleSessionControlMessage(\n session: IInteractiveSession,\n send: (message: TServerMessage) => void,\n msg: Extract<TClientMessage, { type: 'submit' | 'command' | 'abort' | 'cancel-queue' }>,\n): void {\n if (msg.type === 'submit') {\n if (!msg.prompt) {\n send({ type: 'protocol_error', message: 'prompt is required' });\n return;\n }\n session.submit(msg.prompt);\n } else if (msg.type === 'command') {\n if (!msg.name) {\n send({ type: 'protocol_error', message: 'name is required' });\n return;\n }\n session.executeCommand(msg.name, msg.args ?? '').then((result) => {\n send({\n type: 'command_result',\n name: msg.name,\n message: result?.message ?? `Unknown command: ${msg.name}`,\n success: result?.success ?? false,\n data: result?.data,\n });\n });\n } else if (msg.type === 'abort') {\n session.abort();\n } else {\n session.cancelQueue();\n }\n}\n\nfunction handleSessionQueryMessage(\n session: IInteractiveSession,\n send: (message: TServerMessage) => void,\n msg: Extract<\n TClientMessage,\n {\n type:\n | 'get-messages'\n | 'get-context'\n | 'get-executing'\n | 'get-pending'\n | 'get-execution-workspace';\n }\n >,\n): void {\n if (msg.type === 'get-messages') {\n send({ type: 'messages', messages: session.getMessages() });\n } else if (msg.type === 'get-context') {\n send({ type: 'context', state: session.getContextState() });\n } else if (msg.type === 'get-executing') {\n send({ type: 'executing', executing: session.isExecuting() });\n } else if (msg.type === 'get-execution-workspace') {\n send({\n type: 'execution_workspace_event',\n snapshot: session.getExecutionWorkspaceSnapshot(),\n });\n } else {\n send({ type: 'pending', pending: session.getPendingPrompt() });\n }\n}\n","/**\n * ITransportAdapter implementation for WebSocket transport.\n *\n * Wraps createWsHandler into the unified ITransportAdapter interface.\n * After start(), the consumer must wire onMessage to their WebSocket.\n */\n\nimport type { IInteractiveSession } from '@robota-sdk/agent-framework';\nimport type { ITransportAdapter } from '@robota-sdk/agent-interface-transport';\nimport { createWsHandler } from './ws-handler.js';\nimport type { TServerMessage } from './ws-protocol.js';\n\nexport interface IWsTransportOptions {\n /** Send a JSON message to the connected WebSocket client. */\n send: (message: TServerMessage) => void;\n}\n\nexport function createWsTransport(\n options: IWsTransportOptions,\n): ITransportAdapter<IInteractiveSession> & { onMessage: ((data: string) => void) | null } {\n let session: IInteractiveSession | null = null;\n let cleanup: (() => void) | null = null;\n\n return {\n name: 'ws',\n onMessage: null,\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 handler = createWsHandler({ session, send: options.send });\n cleanup = handler.cleanup;\n this.onMessage = handler.onMessage;\n },\n async stop() {\n cleanup?.();\n cleanup = null;\n this.onMessage = null;\n },\n };\n}\n","/**\n * Self-contained WS transport implementing IConfigurableTransport.\n * Owns the WebSocket server lifecycle (ws package), started/stopped via the transport registry.\n */\n\nimport { createServer, type Server } from 'node:http';\nimport { WebSocketServer, WebSocket } from 'ws';\nimport type { IInteractiveSession } from '@robota-sdk/agent-framework';\nimport type { TUniversalValue } from '@robota-sdk/agent-core';\nimport type { IConfigurableTransport } from '@robota-sdk/agent-interface-transport';\nimport { createWsHandler } from './ws-handler.js';\nimport type { TServerMessage } from './ws-protocol.js';\n\nconst DEFAULT_PORT = 7070;\nconst DEFAULT_MAX_RETRIES = 20;\n\nexport interface IWsTransportConfig {\n port?: number;\n maxRetries?: number;\n}\n\nexport class WsTransport implements IConfigurableTransport<IInteractiveSession> {\n readonly name = 'ws';\n readonly defaultEnabled = true;\n readonly optionsSchema = {\n port: { type: 'number', description: 'WebSocket server port', default: DEFAULT_PORT },\n maxRetries: {\n type: 'number',\n description: 'Port retry attempts when port is occupied',\n default: DEFAULT_MAX_RETRIES,\n },\n };\n\n private session: IInteractiveSession | null = null;\n private stopFn: (() => Promise<void>) | null = null;\n private readonly port: number;\n private readonly maxRetries: number;\n\n constructor(config: IWsTransportConfig = {}) {\n this.port = config.port ?? DEFAULT_PORT;\n this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;\n }\n\n attach(session: IInteractiveSession): void {\n this.session = session;\n }\n\n async start(): Promise<void> {\n if (!this.session) throw new Error('WsTransport: attach() must be called before start()');\n const handle = await this.bindWithRetry(this.session, this.port, this.maxRetries);\n this.stopFn = handle.stop;\n }\n\n async stop(): Promise<void> {\n await this.stopFn?.();\n this.stopFn = null;\n }\n\n validateOptions(options: Record<string, TUniversalValue>): boolean {\n const { port, maxRetries } = options;\n if (port !== undefined && (typeof port !== 'number' || port < 1 || port > 65535)) return false;\n if (maxRetries !== undefined && (typeof maxRetries !== 'number' || maxRetries < 0))\n return false;\n return true;\n }\n\n private bindWithRetry(\n session: IInteractiveSession,\n port: number,\n retriesLeft: number,\n ): Promise<{ stop: () => Promise<void> }> {\n return this.tryBind(session, port).catch((err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE' && retriesLeft > 0)\n return this.bindWithRetry(session, port + 1, retriesLeft - 1);\n throw err;\n });\n }\n\n private tryBind(\n session: IInteractiveSession,\n port: number,\n ): Promise<{ stop: () => Promise<void> }> {\n return new Promise((resolve, reject) => {\n const httpServer: Server = createServer((_, res) => {\n res.writeHead(400).end('WebSocket endpoint');\n });\n\n httpServer.on('error', (err: NodeJS.ErrnoException) => {\n httpServer.close();\n reject(err);\n });\n\n httpServer.listen(port, '127.0.0.1', () => {\n const wss = new WebSocketServer({ server: httpServer });\n\n wss.on('connection', (ws: WebSocket) => {\n const send = (message: TServerMessage): void => {\n if (ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify(message));\n };\n\n const { onMessage, cleanup } = createWsHandler({ session, send });\n\n ws.on('message', (data) => onMessage(String(data)));\n ws.on('close', cleanup);\n ws.on('error', cleanup);\n\n send({ type: 'messages', messages: session.getMessages() });\n send({\n type: 'execution_workspace_event',\n snapshot: session.getExecutionWorkspaceSnapshot(),\n });\n });\n\n resolve({\n stop: () =>\n new Promise<void>((res) => {\n wss.close(() => httpServer.close(() => res()));\n }),\n });\n });\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require(`./tui-CeD_6rSo.cjs`);let e=require(`node:http`),t=require(`ws`);function n(e,t,n){if(n.type===`get-background-tasks`){t({type:`background_tasks`,tasks:e.listBackgroundTasks(n.filter)});return}if(n.type===`get-background-task`){i(e,t,n);return}if(n.type===`get-background-job-groups`){t({type:`background_job_groups`,groups:e.listBackgroundJobGroups()});return}if(n.type===`get-background-job-group`){o(e,t,n);return}if(n.type===`wait-background-job-group`){s(e,t,n);return}a(e,t,n)}function r(e,t,n){if(!n.taskId){t({type:`protocol_error`,message:`taskId is required`});return}if(n.type===`cancel-background-task`){l(t,`cancel`,n.taskId,e.cancelBackgroundTask(n.taskId,n.reason));return}if(n.type===`close-background-task`){l(t,`close`,n.taskId,e.closeBackgroundTask(n.taskId));return}c(e,t,n)}function i(e,t,n){if(!n.taskId){t({type:`protocol_error`,message:`taskId is required`});return}t({type:`background_task`,taskId:n.taskId,task:e.getBackgroundTask(n.taskId)??null})}function a(e,t,n){if(!n.taskId){t({type:`protocol_error`,message:`taskId is required`});return}e.readBackgroundTaskLog(n.taskId,n.cursor).then(e=>t({type:`background_task_log`,taskId:n.taskId,page:e}),e=>t({type:`protocol_error`,message:e.message}))}function o(e,t,n){if(!n.groupId){t({type:`protocol_error`,message:`groupId is required`});return}t({type:`background_job_group`,groupId:n.groupId,group:e.getBackgroundJobGroup(n.groupId)??null})}function s(e,t,n){if(!n.groupId){t({type:`protocol_error`,message:`groupId is required`});return}e.waitBackgroundJobGroup(n.groupId).then(e=>t({type:`background_job_group`,groupId:n.groupId,group:e}),e=>t({type:`protocol_error`,message:e.message}))}function c(e,t,n){if(!n.input){t({type:`protocol_error`,message:`input is required`});return}l(t,`send`,n.taskId,e.sendBackgroundTask(n.taskId,n.input))}function l(e,t,n,r){r.then(()=>e({type:`background_task_control_result`,action:t,taskId:n,success:!0}),r=>e({type:`background_task_control_result`,action:t,taskId:n,success:!1,message:r.message}))}function u(e){let t=d(e.session,e.send);return{onMessage:f(e.session,e.send),cleanup:t}}function d(e,t){let n=e=>t({type:`user_message`,content:e}),r=e=>t({type:`text_delta`,delta:e}),i=e=>t({type:`tool_start`,state:e}),a=e=>t({type:`tool_end`,state:e}),o=e=>t({type:`thinking`,isThinking:e}),s=e=>t({type:`complete`,result:e}),c=e=>t({type:`interrupted`,result:e}),l=e=>t({type:`error`,message:e.message}),u=e=>t({type:`background_task_event`,event:e}),d=e=>t({type:`background_job_group_event`,event:e}),f=e=>t({type:`execution_workspace_event`,snapshot:e.snapshot});return e.on(`user_message`,n),e.on(`text_delta`,r),e.on(`tool_start`,i),e.on(`tool_end`,a),e.on(`thinking`,o),e.on(`complete`,s),e.on(`interrupted`,c),e.on(`error`,l),e.on(`background_task_event`,u),e.on(`background_job_group_event`,d),e.on(`execution_workspace_event`,f),()=>{e.off(`user_message`,n),e.off(`text_delta`,r),e.off(`tool_start`,i),e.off(`tool_end`,a),e.off(`thinking`,o),e.off(`complete`,s),e.off(`interrupted`,c),e.off(`error`,l),e.off(`background_task_event`,u),e.off(`background_job_group_event`,d),e.off(`execution_workspace_event`,f)}}function f(e,t){return n=>{let r=p(n,t);r&&m(e,t,r)}}function p(e,t){try{return JSON.parse(e)}catch{return t({type:`protocol_error`,message:`Invalid JSON`}),null}}function m(e,t,i){if(g(i)){b(e,t,i);return}if(_(i)){x(e,t,i);return}if(v(i)){n(e,t,i);return}if(y(i)){r(e,t,i);return}t({type:`protocol_error`,message:`Unknown message type: ${h(i)}`})}function h(e){return e.type}function g(e){return e.type===`submit`||e.type===`command`||e.type===`abort`||e.type===`cancel-queue`}function _(e){return e.type===`get-messages`||e.type===`get-context`||e.type===`get-executing`||e.type===`get-pending`||e.type===`get-execution-workspace`}function v(e){return e.type===`get-background-tasks`||e.type===`get-background-task`||e.type===`read-background-task-log`||e.type===`get-background-job-groups`||e.type===`get-background-job-group`||e.type===`wait-background-job-group`}function y(e){return e.type===`cancel-background-task`||e.type===`close-background-task`||e.type===`send-background-task`}function b(e,t,n){if(n.type===`submit`){if(!n.prompt){t({type:`protocol_error`,message:`prompt is required`});return}e.submit(n.prompt)}else if(n.type===`command`){if(!n.name){t({type:`protocol_error`,message:`name is required`});return}e.executeCommand(n.name,n.args??``).then(e=>{t({type:`command_result`,name:n.name,message:e?.message??`Unknown command: ${n.name}`,success:e?.success??!1,data:e?.data})})}else n.type===`abort`?e.abort():e.cancelQueue()}function x(e,t,n){n.type===`get-messages`?t({type:`messages`,messages:e.getMessages()}):n.type===`get-context`?t({type:`context`,state:e.getContextState()}):n.type===`get-executing`?t({type:`executing`,executing:e.isExecuting()}):n.type===`get-execution-workspace`?t({type:`execution_workspace_event`,snapshot:e.getExecutionWorkspaceSnapshot()}):t({type:`pending`,pending:e.getPendingPrompt()})}function S(e){let t=null,n=null;return{name:`ws`,onMessage:null,attach(e){t=e},async start(){if(!t)throw Error(`No session attached. Call attach() first.`);let r=u({session:t,send:e.send});n=r.cleanup,this.onMessage=r.onMessage},async stop(){n?.(),n=null,this.onMessage=null}}}const C=7070;var w=class{name=`ws`;defaultEnabled=!0;optionsSchema={port:{type:`number`,description:`WebSocket server port`,default:C},maxRetries:{type:`number`,description:`Port retry attempts when port is occupied`,default:20}};session=null;stopFn=null;port;maxRetries;constructor(e={}){this.port=e.port??C,this.maxRetries=e.maxRetries??20}attach(e){this.session=e}async start(){if(!this.session)throw Error(`WsTransport: attach() must be called before start()`);let e=await this.bindWithRetry(this.session,this.port,this.maxRetries);this.stopFn=e.stop}async stop(){await this.stopFn?.(),this.stopFn=null}validateOptions(e){let{port:t,maxRetries:n}=e;return!(t!==void 0&&(typeof t!=`number`||t<1||t>65535)||n!==void 0&&(typeof n!=`number`||n<0))}bindWithRetry(e,t,n){return this.tryBind(e,t).catch(r=>{if(r.code===`EADDRINUSE`&&n>0)return this.bindWithRetry(e,t+1,n-1);throw r})}tryBind(n,r){return new Promise((i,a)=>{let o=(0,e.createServer)((e,t)=>{t.writeHead(400).end(`WebSocket endpoint`)});o.on(`error`,e=>{o.close(),a(e)}),o.listen(r,`127.0.0.1`,()=>{let e=new t.WebSocketServer({server:o});e.on(`connection`,e=>{let r=n=>{e.readyState===t.WebSocket.OPEN&&e.send(JSON.stringify(n))},{onMessage:i,cleanup:a}=u({session:n,send:r});e.on(`message`,e=>i(String(e))),e.on(`close`,a),e.on(`error`,a),r({type:`messages`,messages:n.getMessages()}),r({type:`execution_workspace_event`,snapshot:n.getExecutionWorkspaceSnapshot()})}),i({stop:()=>new Promise(t=>{e.close(()=>o.close(()=>t()))})})})})}};Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return w}});
|
package/package.json
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@robota-sdk/agent-transport",
|
|
3
|
+
"version": "3.0.0-beta.64",
|
|
4
|
+
"description": "Consolidated transport package for Robota SDK — TUI, headless, HTTP, WebSocket, and MCP adapters",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/node/index.js",
|
|
7
|
+
"types": "dist/node/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/node/index.d.ts",
|
|
11
|
+
"source": "./src/index.ts",
|
|
12
|
+
"node": {
|
|
13
|
+
"import": "./dist/node/index.js",
|
|
14
|
+
"require": "./dist/node/index.cjs"
|
|
15
|
+
},
|
|
16
|
+
"default": {
|
|
17
|
+
"import": "./dist/node/index.js",
|
|
18
|
+
"require": "./dist/node/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"./tui": {
|
|
22
|
+
"types": "./dist/node/tui/index.d.ts",
|
|
23
|
+
"source": "./src/tui/index.ts",
|
|
24
|
+
"node": {
|
|
25
|
+
"import": "./dist/node/tui/index.js",
|
|
26
|
+
"require": "./dist/node/tui/index.cjs"
|
|
27
|
+
},
|
|
28
|
+
"default": {
|
|
29
|
+
"import": "./dist/node/tui/index.js",
|
|
30
|
+
"require": "./dist/node/tui/index.cjs"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"./headless": {
|
|
34
|
+
"types": "./dist/node/headless/index.d.ts",
|
|
35
|
+
"source": "./src/headless/index.ts",
|
|
36
|
+
"node": {
|
|
37
|
+
"import": "./dist/node/headless/index.js",
|
|
38
|
+
"require": "./dist/node/headless/index.cjs"
|
|
39
|
+
},
|
|
40
|
+
"default": {
|
|
41
|
+
"import": "./dist/node/headless/index.js",
|
|
42
|
+
"require": "./dist/node/headless/index.cjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"./http": {
|
|
46
|
+
"types": "./dist/node/http/index.d.ts",
|
|
47
|
+
"source": "./src/http/index.ts",
|
|
48
|
+
"node": {
|
|
49
|
+
"import": "./dist/node/http/index.js",
|
|
50
|
+
"require": "./dist/node/http/index.cjs"
|
|
51
|
+
},
|
|
52
|
+
"default": {
|
|
53
|
+
"import": "./dist/node/http/index.js",
|
|
54
|
+
"require": "./dist/node/http/index.cjs"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"./ws": {
|
|
58
|
+
"types": "./dist/node/ws/index.d.ts",
|
|
59
|
+
"source": "./src/ws/index.ts",
|
|
60
|
+
"node": {
|
|
61
|
+
"import": "./dist/node/ws/index.js",
|
|
62
|
+
"require": "./dist/node/ws/index.cjs"
|
|
63
|
+
},
|
|
64
|
+
"default": {
|
|
65
|
+
"import": "./dist/node/ws/index.js",
|
|
66
|
+
"require": "./dist/node/ws/index.cjs"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"./mcp": {
|
|
70
|
+
"types": "./dist/node/mcp/index.d.ts",
|
|
71
|
+
"source": "./src/mcp/index.ts",
|
|
72
|
+
"node": {
|
|
73
|
+
"import": "./dist/node/mcp/index.js",
|
|
74
|
+
"require": "./dist/node/mcp/index.cjs"
|
|
75
|
+
},
|
|
76
|
+
"default": {
|
|
77
|
+
"import": "./dist/node/mcp/index.js",
|
|
78
|
+
"require": "./dist/node/mcp/index.cjs"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"repository": {
|
|
83
|
+
"type": "git",
|
|
84
|
+
"url": "https://github.com/woojubb/robota.git"
|
|
85
|
+
},
|
|
86
|
+
"homepage": "https://robota.io/",
|
|
87
|
+
"bugs": {
|
|
88
|
+
"url": "https://github.com/woojubb/robota/issues"
|
|
89
|
+
},
|
|
90
|
+
"engines": {
|
|
91
|
+
"node": ">=22.0.0"
|
|
92
|
+
},
|
|
93
|
+
"files": [
|
|
94
|
+
"dist",
|
|
95
|
+
"src"
|
|
96
|
+
],
|
|
97
|
+
"dependencies": {
|
|
98
|
+
"@modelcontextprotocol/sdk": "^1.28.0",
|
|
99
|
+
"chalk": "^5.3.0",
|
|
100
|
+
"hono": "^4.7.0",
|
|
101
|
+
"ink": "^7.0.1",
|
|
102
|
+
"ink-select-input": "^6.2.0",
|
|
103
|
+
"ink-spinner": "^5.0.0",
|
|
104
|
+
"ink-text-input": "^6.0.0",
|
|
105
|
+
"marked": "^9.1.5",
|
|
106
|
+
"marked-terminal": "^7.3.0",
|
|
107
|
+
"react": "19.2.4",
|
|
108
|
+
"string-width": "^8.2.0",
|
|
109
|
+
"ws": "^8.18.3",
|
|
110
|
+
"zod": "^3.24.4",
|
|
111
|
+
"@robota-sdk/agent-interface-transport": "3.0.0-beta.64",
|
|
112
|
+
"@robota-sdk/agent-core": "3.0.0-beta.64",
|
|
113
|
+
"@robota-sdk/agent-framework": "3.0.0-beta.64"
|
|
114
|
+
},
|
|
115
|
+
"devDependencies": {
|
|
116
|
+
"@homebridge/node-pty-prebuilt-multiarch": "^0.13.1",
|
|
117
|
+
"@modelcontextprotocol/sdk": "^1.28.0",
|
|
118
|
+
"@types/react": "^19.2.14",
|
|
119
|
+
"@types/ws": "^8.5.10",
|
|
120
|
+
"ink-testing-library": "^4.0.0",
|
|
121
|
+
"rimraf": "^5.0.5",
|
|
122
|
+
"tsdown": "^0.22.0",
|
|
123
|
+
"tsx": "^4.7.0",
|
|
124
|
+
"typescript": "^5.3.3",
|
|
125
|
+
"vitest": "^1.6.1",
|
|
126
|
+
"@robota-sdk/agent-command": "3.0.0-beta.64"
|
|
127
|
+
},
|
|
128
|
+
"license": "MIT",
|
|
129
|
+
"publishConfig": {
|
|
130
|
+
"access": "public"
|
|
131
|
+
},
|
|
132
|
+
"scripts": {
|
|
133
|
+
"build": "tsdown",
|
|
134
|
+
"build:js": "tsdown --no-dts",
|
|
135
|
+
"build:types": "tsdown --dts",
|
|
136
|
+
"typecheck": "tsc --noEmit",
|
|
137
|
+
"test": "vitest run --passWithNoTests",
|
|
138
|
+
"test:coverage": "vitest run --coverage --passWithNoTests",
|
|
139
|
+
"clean": "rimraf dist"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import type { IInteractiveSession } from '@robota-sdk/agent-framework';
|
|
3
|
+
import { createHeadlessRunner } from '../headless-runner.js';
|
|
4
|
+
|
|
5
|
+
describe('createHeadlessRunner initialization', () => {
|
|
6
|
+
it('stream-json reads the session id after submit initializes the session', async () => {
|
|
7
|
+
const stdoutWriteSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
8
|
+
const listeners = new Map<string, Array<(...args: unknown[]) => void>>();
|
|
9
|
+
let initialized = false;
|
|
10
|
+
const session = {
|
|
11
|
+
on: vi.fn((event: string, handler: (...args: unknown[]) => void) => {
|
|
12
|
+
if (!listeners.has(event)) listeners.set(event, []);
|
|
13
|
+
listeners.get(event)!.push(handler);
|
|
14
|
+
}),
|
|
15
|
+
off: vi.fn(),
|
|
16
|
+
submit: vi.fn(async () => {
|
|
17
|
+
initialized = true;
|
|
18
|
+
for (const h of listeners.get('text_delta') ?? []) {
|
|
19
|
+
h('Hello');
|
|
20
|
+
}
|
|
21
|
+
for (const h of listeners.get('complete') ?? []) {
|
|
22
|
+
h({ response: 'Hello', history: [], toolSummaries: [], contextState: {} });
|
|
23
|
+
}
|
|
24
|
+
}),
|
|
25
|
+
getSession: vi.fn(() => {
|
|
26
|
+
if (!initialized) {
|
|
27
|
+
throw new Error('InteractiveSession not initialized');
|
|
28
|
+
}
|
|
29
|
+
return { getSessionId: () => 'initialized-session' };
|
|
30
|
+
}),
|
|
31
|
+
} as unknown as IInteractiveSession;
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const runner = createHeadlessRunner({ session, outputFormat: 'stream-json' });
|
|
35
|
+
const exitCode = await runner.run('test prompt');
|
|
36
|
+
|
|
37
|
+
expect(exitCode).toBe(0);
|
|
38
|
+
expect(stdoutWriteSpy).toHaveBeenCalledWith(
|
|
39
|
+
expect.stringContaining('"session_id":"initialized-session"'),
|
|
40
|
+
);
|
|
41
|
+
} finally {
|
|
42
|
+
stdoutWriteSpy.mockRestore();
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
});
|