@robota-sdk/agent-sdk 3.0.0-beta.45 → 3.0.0-beta.47

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 CHANGED
@@ -84,7 +84,9 @@ const session = new InteractiveSession({
84
84
  config,
85
85
  context,
86
86
  projectInfo,
87
- sessionStore,
87
+ sessionStore, // SessionStore instance for persistence
88
+ resumeSessionId, // Session ID to restore (optional)
89
+ forkSession, // Session ID to fork from (optional)
88
90
  permissionMode: 'default',
89
91
  maxTurns: 10,
90
92
  cwd: process.cwd(),
@@ -144,6 +146,10 @@ session.getContextState(); // IContextWindowState
144
146
  session.getStreamingText(); // string (accumulated so far)
145
147
  session.getActiveTools(); // IToolState[]
146
148
 
149
+ // Session naming
150
+ session.getName(); // string | undefined
151
+ session.setName('my-task'); // sets the session name
152
+
147
153
  // Access underlying Session for advanced use
148
154
  session.getSession(); // Session
149
155
  ```
@@ -713,6 +713,7 @@ function createSession(options) {
713
713
  model: options.config.provider.model,
714
714
  maxTurns: options.maxTurns,
715
715
  sessionStore: options.sessionStore,
716
+ sessionId: options.sessionId,
716
717
  permissionHandler: options.permissionHandler,
717
718
  onTextDelta: options.onTextDelta,
718
719
  onToolExecution: options.onToolExecution,
@@ -1117,6 +1118,8 @@ function createSystemCommands() {
1117
1118
  " cost \u2014 Show session info",
1118
1119
  " context \u2014 Context window info",
1119
1120
  " permissions \u2014 Permission rules",
1121
+ " resume \u2014 Resume a previous session",
1122
+ " rename <name> \u2014 Rename the current session",
1120
1123
  " reset \u2014 Delete settings and exit"
1121
1124
  ].join("\n"),
1122
1125
  success: true
@@ -1255,6 +1258,30 @@ Messages: ${messageCount}`,
1255
1258
  };
1256
1259
  }
1257
1260
  },
1261
+ {
1262
+ name: "resume",
1263
+ description: "Resume a previous session",
1264
+ execute: (_session, _args) => ({
1265
+ message: "Opening session picker...",
1266
+ success: true,
1267
+ data: { triggerResumePicker: true }
1268
+ })
1269
+ },
1270
+ {
1271
+ name: "rename",
1272
+ description: "Rename the current session",
1273
+ execute: (_session, args) => {
1274
+ const name = args.trim();
1275
+ if (!name) {
1276
+ return { message: "Usage: rename <name>", success: false };
1277
+ }
1278
+ return {
1279
+ message: `Session renamed to "${name}".`,
1280
+ success: true,
1281
+ data: { name }
1282
+ };
1283
+ }
1284
+ },
1258
1285
  {
1259
1286
  name: "reset",
1260
1287
  description: "Delete settings",
@@ -2180,6 +2207,14 @@ var InteractiveSession = class {
2180
2207
  pendingRawInput;
2181
2208
  // Full history timeline (chat messages + events)
2182
2209
  history = [];
2210
+ // Session persistence
2211
+ sessionStore;
2212
+ sessionName;
2213
+ cwd;
2214
+ // Session restore state
2215
+ pendingRestoreMessages = null;
2216
+ resumeSessionId;
2217
+ forkSession;
2183
2218
  constructor(options) {
2184
2219
  this.commandExecutor = new SystemCommandExecutor(createSystemCommands());
2185
2220
  if ("session" in options && options.session) {
@@ -2189,6 +2224,30 @@ var InteractiveSession = class {
2189
2224
  const stdOpts = options;
2190
2225
  this.initPromise = this.initializeAsync(stdOpts);
2191
2226
  }
2227
+ this.sessionStore = options.sessionStore;
2228
+ this.sessionName = options.sessionName;
2229
+ this.cwd = ("cwd" in options ? options.cwd : void 0) ?? "";
2230
+ this.resumeSessionId = options.resumeSessionId;
2231
+ this.forkSession = options.forkSession ?? false;
2232
+ if (options.resumeSessionId && this.sessionStore) {
2233
+ const record = this.sessionStore.load(options.resumeSessionId);
2234
+ if (record) {
2235
+ this.history = record.history ?? [];
2236
+ this.sessionName = record.name;
2237
+ if (record.messages) {
2238
+ if (this.session) {
2239
+ for (const msg of record.messages) {
2240
+ const m = msg;
2241
+ if (m.role && m.content) {
2242
+ this.session.injectMessage(m.role, m.content);
2243
+ }
2244
+ }
2245
+ } else {
2246
+ this.pendingRestoreMessages = record.messages;
2247
+ }
2248
+ }
2249
+ }
2250
+ }
2192
2251
  }
2193
2252
  async initializeAsync(options) {
2194
2253
  const cwd = options.cwd;
@@ -2215,6 +2274,7 @@ var InteractiveSession = class {
2215
2274
  } catch {
2216
2275
  }
2217
2276
  const paths = projectPaths(cwd);
2277
+ const sessionId = this.resumeSessionId && !this.forkSession ? this.resumeSessionId : void 0;
2218
2278
  this.session = createSession({
2219
2279
  config: mergedConfig,
2220
2280
  context,
@@ -2226,8 +2286,20 @@ var InteractiveSession = class {
2226
2286
  permissionHandler: options.permissionHandler,
2227
2287
  provider: options.provider,
2228
2288
  onTextDelta: (delta) => this.handleTextDelta(delta),
2229
- onToolExecution: (event) => this.handleToolExecution(event)
2289
+ onToolExecution: (event) => this.handleToolExecution(event),
2290
+ sessionId
2230
2291
  });
2292
+ if (this.pendingRestoreMessages) {
2293
+ for (const msg of this.pendingRestoreMessages) {
2294
+ if (msg && typeof msg === "object" && "role" in msg && "content" in msg) {
2295
+ this.session.injectMessage(
2296
+ msg.role,
2297
+ msg.content
2298
+ );
2299
+ }
2300
+ }
2301
+ this.pendingRestoreMessages = null;
2302
+ }
2231
2303
  this.initialized = true;
2232
2304
  }
2233
2305
  async ensureInitialized() {
@@ -2317,6 +2389,30 @@ var InteractiveSession = class {
2317
2389
  getContextState() {
2318
2390
  return this.getSessionOrThrow().getContextState();
2319
2391
  }
2392
+ /** Get session name. */
2393
+ getName() {
2394
+ return this.sessionName;
2395
+ }
2396
+ /** Set session name and persist if store is available. */
2397
+ setName(name) {
2398
+ this.sessionName = name;
2399
+ if (this.sessionStore && this.session) {
2400
+ try {
2401
+ const id = this.getSessionOrThrow().getSessionId();
2402
+ const existing = this.sessionStore.load(id);
2403
+ if (existing) {
2404
+ existing.name = name;
2405
+ existing.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
2406
+ this.sessionStore.save(existing);
2407
+ }
2408
+ } catch {
2409
+ }
2410
+ }
2411
+ }
2412
+ /** Attach a transport adapter to this session. Calls transport.attach(this). */
2413
+ attachTransport(transport) {
2414
+ transport.attach(this);
2415
+ }
2320
2416
  /** Access underlying Session. For advanced use / testing only. */
2321
2417
  getSession() {
2322
2418
  return this.getSessionOrThrow();
@@ -2358,6 +2454,22 @@ var InteractiveSession = class {
2358
2454
  } finally {
2359
2455
  this.executing = false;
2360
2456
  this.emit("thinking", false);
2457
+ if (this.sessionStore && this.session) {
2458
+ try {
2459
+ const sessionId = this.getSessionOrThrow().getSessionId();
2460
+ const existing = this.sessionStore.load(sessionId);
2461
+ this.sessionStore.save({
2462
+ id: sessionId,
2463
+ name: this.sessionName ?? existing?.name,
2464
+ cwd: this.cwd ?? "",
2465
+ createdAt: existing?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
2466
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
2467
+ messages: this.getSessionOrThrow().getHistory(),
2468
+ history: this.history
2469
+ });
2470
+ } catch {
2471
+ }
2472
+ }
2361
2473
  if (this.pendingPrompt) {
2362
2474
  const queued = this.pendingPrompt;
2363
2475
  const queuedDisplay = this.pendingDisplayInput;
@@ -2645,6 +2757,8 @@ function createBuiltinCommands() {
2645
2757
  { name: "cost", description: "Show session info", source: "builtin" },
2646
2758
  { name: "context", description: "Context window info", source: "builtin" },
2647
2759
  { name: "permissions", description: "Permission rules", source: "builtin" },
2760
+ { name: "resume", description: "Resume a previous session", source: "builtin" },
2761
+ { name: "rename", description: "Rename the current session", source: "builtin" },
2648
2762
  { name: "plugin", description: "Manage plugins", source: "builtin" },
2649
2763
  { name: "reload-plugins", description: "Reload all plugin resources", source: "builtin" },
2650
2764
  { name: "reset", description: "Delete settings and exit", source: "builtin" },
@@ -210,6 +210,8 @@ interface ICreateSessionOptions {
210
210
  sessionFactory?: TSessionFactory;
211
211
  /** Additional hook type executors beyond the defaults (prompt, agent). */
212
212
  additionalHookExecutors?: IHookTypeExecutor[];
213
+ /** Override session ID (used when resuming a session to reuse the original ID) */
214
+ sessionId?: string;
213
215
  }
214
216
 
215
217
  /**
@@ -402,6 +404,20 @@ interface IInteractiveSessionEvents {
402
404
  interrupted: (result: IExecutionResult) => void;
403
405
  }
404
406
  type TInteractiveEventName = keyof IInteractiveSessionEvents;
407
+ /**
408
+ * Common interface for all transport adapters.
409
+ * Each transport exposes InteractiveSession over a specific protocol.
410
+ */
411
+ interface ITransportAdapter {
412
+ /** Human-readable transport name (e.g., 'http', 'ws', 'mcp', 'headless') */
413
+ readonly name: string;
414
+ /** Attach an InteractiveSession to this transport. */
415
+ attach(session: InteractiveSession): void;
416
+ /** Start serving. What this means depends on the transport. */
417
+ start(): Promise<void>;
418
+ /** Stop serving and clean up resources. */
419
+ stop(): Promise<void>;
420
+ }
405
421
 
406
422
  /**
407
423
  * InteractiveSession — the single entry point for all SDK consumers.
@@ -420,6 +436,10 @@ interface IInteractiveSessionStandardOptions {
420
436
  permissionMode?: ICreateSessionOptions['permissionMode'];
421
437
  maxTurns?: number;
422
438
  permissionHandler?: TInteractivePermissionHandler;
439
+ sessionStore?: SessionStore;
440
+ sessionName?: string;
441
+ resumeSessionId?: string;
442
+ forkSession?: boolean;
423
443
  }
424
444
  /** Test/advanced construction: inject pre-built session directly. */
425
445
  interface IInteractiveSessionInjectedOptions {
@@ -429,6 +449,10 @@ interface IInteractiveSessionInjectedOptions {
429
449
  permissionMode?: ICreateSessionOptions['permissionMode'];
430
450
  maxTurns?: number;
431
451
  permissionHandler?: TInteractivePermissionHandler;
452
+ sessionStore?: SessionStore;
453
+ sessionName?: string;
454
+ resumeSessionId?: string;
455
+ forkSession?: boolean;
432
456
  }
433
457
  type IInteractiveSessionOptions = IInteractiveSessionStandardOptions | IInteractiveSessionInjectedOptions;
434
458
  declare class InteractiveSession {
@@ -445,6 +469,12 @@ declare class InteractiveSession {
445
469
  private pendingDisplayInput;
446
470
  private pendingRawInput;
447
471
  private history;
472
+ private sessionStore?;
473
+ private sessionName?;
474
+ private cwd?;
475
+ private pendingRestoreMessages;
476
+ private resumeSessionId?;
477
+ private forkSession;
448
478
  constructor(options: IInteractiveSessionOptions);
449
479
  private initializeAsync;
450
480
  private ensureInitialized;
@@ -478,6 +508,12 @@ declare class InteractiveSession {
478
508
  getStreamingText(): string;
479
509
  getActiveTools(): IToolState[];
480
510
  getContextState(): IContextWindowState;
511
+ /** Get session name. */
512
+ getName(): string | undefined;
513
+ /** Set session name and persist if store is available. */
514
+ setName(name: string): void;
515
+ /** Attach a transport adapter to this session. Calls transport.attach(this). */
516
+ attachTransport(transport: ITransportAdapter): void;
481
517
  /** Access underlying Session. For advanced use / testing only. */
482
518
  getSession(): Session;
483
519
  private executePrompt;
@@ -1135,4 +1171,4 @@ declare function userPaths(): {
1135
1171
  */
1136
1172
  declare function promptForApproval(terminal: ITerminalOutput, toolName: string, toolArgs: TToolArgs): Promise<boolean>;
1137
1173
 
1138
- export { AgentExecutor, BUILT_IN_AGENTS, BuiltinCommandSource, BundlePluginInstaller, BundlePluginLoader, CommandRegistry, type IAgentDefinition, type IAgentExecutorOptions, type IAgentSession, type IAgentToolDeps, type IBundlePluginFeatures, type IBundlePluginInstallerOptions, type IBundlePluginManifest, type IBundleSkill, type ICommand, type ICommandResult, type ICommandSource, type ICreateQueryOptions, type IDiffLine, type IExecutionResult, type IInstalledPluginRecord, type IInstalledPluginsRegistry, type IInteractiveSessionEvents, type IInteractiveSessionOptions, type IKnownMarketplaceEntry, type IKnownMarketplacesRegistry, type ILoadedBundlePlugin, type IMarketplaceClientOptions, type IMarketplaceManifest, type IMarketplacePluginEntry, type IMarketplaceSource, type IPluginSettings, type IPromptExecutorOptions, type IPromptProvider, type ISubagentOptions, type ISubagentPromptOptions, type ISystemCommand, type IToolState, type IToolSummary, InteractiveSession, MarketplaceClient, PluginCommandSource, PluginSettingsStore, PromptExecutor, SkillCommandSource, type SkillPromptContext, type TEnabledPlugins, type TInteractiveEventName, type TInteractivePermissionHandler, type TPermissionResultValue, type TProviderFactory, type TSessionFactory, assembleSubagentPrompt, buildSkillPrompt, createAgentTool, createQuery, createSubagentLogger, createSubagentSession, getBuiltInAgent, getForkWorkerSuffix, getSubagentSuffix, parseFrontmatter, preprocessShellCommands, projectPaths, promptForApproval, resolveSubagentLogDir, retrieveAgentToolDeps, storeAgentToolDeps, substituteVariables, userPaths };
1174
+ export { AgentExecutor, BUILT_IN_AGENTS, BuiltinCommandSource, BundlePluginInstaller, BundlePluginLoader, CommandRegistry, type IAgentDefinition, type IAgentExecutorOptions, type IAgentSession, type IAgentToolDeps, type IBundlePluginFeatures, type IBundlePluginInstallerOptions, type IBundlePluginManifest, type IBundleSkill, type ICommand, type ICommandResult, type ICommandSource, type ICreateQueryOptions, type IDiffLine, type IExecutionResult, type IInstalledPluginRecord, type IInstalledPluginsRegistry, type IInteractiveSessionEvents, type IInteractiveSessionOptions, type IKnownMarketplaceEntry, type IKnownMarketplacesRegistry, type ILoadedBundlePlugin, type IMarketplaceClientOptions, type IMarketplaceManifest, type IMarketplacePluginEntry, type IMarketplaceSource, type IPluginSettings, type IPromptExecutorOptions, type IPromptProvider, type ISubagentOptions, type ISubagentPromptOptions, type ISystemCommand, type IToolState, type IToolSummary, type ITransportAdapter, InteractiveSession, MarketplaceClient, PluginCommandSource, PluginSettingsStore, PromptExecutor, SkillCommandSource, type SkillPromptContext, type TEnabledPlugins, type TInteractiveEventName, type TInteractivePermissionHandler, type TPermissionResultValue, type TProviderFactory, type TSessionFactory, assembleSubagentPrompt, buildSkillPrompt, createAgentTool, createQuery, createSubagentLogger, createSubagentSession, getBuiltInAgent, getForkWorkerSuffix, getSubagentSuffix, parseFrontmatter, preprocessShellCommands, projectPaths, promptForApproval, resolveSubagentLogDir, retrieveAgentToolDeps, storeAgentToolDeps, substituteVariables, userPaths };
@@ -210,6 +210,8 @@ interface ICreateSessionOptions {
210
210
  sessionFactory?: TSessionFactory;
211
211
  /** Additional hook type executors beyond the defaults (prompt, agent). */
212
212
  additionalHookExecutors?: IHookTypeExecutor[];
213
+ /** Override session ID (used when resuming a session to reuse the original ID) */
214
+ sessionId?: string;
213
215
  }
214
216
 
215
217
  /**
@@ -402,6 +404,20 @@ interface IInteractiveSessionEvents {
402
404
  interrupted: (result: IExecutionResult) => void;
403
405
  }
404
406
  type TInteractiveEventName = keyof IInteractiveSessionEvents;
407
+ /**
408
+ * Common interface for all transport adapters.
409
+ * Each transport exposes InteractiveSession over a specific protocol.
410
+ */
411
+ interface ITransportAdapter {
412
+ /** Human-readable transport name (e.g., 'http', 'ws', 'mcp', 'headless') */
413
+ readonly name: string;
414
+ /** Attach an InteractiveSession to this transport. */
415
+ attach(session: InteractiveSession): void;
416
+ /** Start serving. What this means depends on the transport. */
417
+ start(): Promise<void>;
418
+ /** Stop serving and clean up resources. */
419
+ stop(): Promise<void>;
420
+ }
405
421
 
406
422
  /**
407
423
  * InteractiveSession — the single entry point for all SDK consumers.
@@ -420,6 +436,10 @@ interface IInteractiveSessionStandardOptions {
420
436
  permissionMode?: ICreateSessionOptions['permissionMode'];
421
437
  maxTurns?: number;
422
438
  permissionHandler?: TInteractivePermissionHandler;
439
+ sessionStore?: SessionStore;
440
+ sessionName?: string;
441
+ resumeSessionId?: string;
442
+ forkSession?: boolean;
423
443
  }
424
444
  /** Test/advanced construction: inject pre-built session directly. */
425
445
  interface IInteractiveSessionInjectedOptions {
@@ -429,6 +449,10 @@ interface IInteractiveSessionInjectedOptions {
429
449
  permissionMode?: ICreateSessionOptions['permissionMode'];
430
450
  maxTurns?: number;
431
451
  permissionHandler?: TInteractivePermissionHandler;
452
+ sessionStore?: SessionStore;
453
+ sessionName?: string;
454
+ resumeSessionId?: string;
455
+ forkSession?: boolean;
432
456
  }
433
457
  type IInteractiveSessionOptions = IInteractiveSessionStandardOptions | IInteractiveSessionInjectedOptions;
434
458
  declare class InteractiveSession {
@@ -445,6 +469,12 @@ declare class InteractiveSession {
445
469
  private pendingDisplayInput;
446
470
  private pendingRawInput;
447
471
  private history;
472
+ private sessionStore?;
473
+ private sessionName?;
474
+ private cwd?;
475
+ private pendingRestoreMessages;
476
+ private resumeSessionId?;
477
+ private forkSession;
448
478
  constructor(options: IInteractiveSessionOptions);
449
479
  private initializeAsync;
450
480
  private ensureInitialized;
@@ -478,6 +508,12 @@ declare class InteractiveSession {
478
508
  getStreamingText(): string;
479
509
  getActiveTools(): IToolState[];
480
510
  getContextState(): IContextWindowState;
511
+ /** Get session name. */
512
+ getName(): string | undefined;
513
+ /** Set session name and persist if store is available. */
514
+ setName(name: string): void;
515
+ /** Attach a transport adapter to this session. Calls transport.attach(this). */
516
+ attachTransport(transport: ITransportAdapter): void;
481
517
  /** Access underlying Session. For advanced use / testing only. */
482
518
  getSession(): Session;
483
519
  private executePrompt;
@@ -1135,4 +1171,4 @@ declare function userPaths(): {
1135
1171
  */
1136
1172
  declare function promptForApproval(terminal: ITerminalOutput, toolName: string, toolArgs: TToolArgs): Promise<boolean>;
1137
1173
 
1138
- export { AgentExecutor, BUILT_IN_AGENTS, BuiltinCommandSource, BundlePluginInstaller, BundlePluginLoader, CommandRegistry, type IAgentDefinition, type IAgentExecutorOptions, type IAgentSession, type IAgentToolDeps, type IBundlePluginFeatures, type IBundlePluginInstallerOptions, type IBundlePluginManifest, type IBundleSkill, type ICommand, type ICommandResult, type ICommandSource, type ICreateQueryOptions, type IDiffLine, type IExecutionResult, type IInstalledPluginRecord, type IInstalledPluginsRegistry, type IInteractiveSessionEvents, type IInteractiveSessionOptions, type IKnownMarketplaceEntry, type IKnownMarketplacesRegistry, type ILoadedBundlePlugin, type IMarketplaceClientOptions, type IMarketplaceManifest, type IMarketplacePluginEntry, type IMarketplaceSource, type IPluginSettings, type IPromptExecutorOptions, type IPromptProvider, type ISubagentOptions, type ISubagentPromptOptions, type ISystemCommand, type IToolState, type IToolSummary, InteractiveSession, MarketplaceClient, PluginCommandSource, PluginSettingsStore, PromptExecutor, SkillCommandSource, type SkillPromptContext, type TEnabledPlugins, type TInteractiveEventName, type TInteractivePermissionHandler, type TPermissionResultValue, type TProviderFactory, type TSessionFactory, assembleSubagentPrompt, buildSkillPrompt, createAgentTool, createQuery, createSubagentLogger, createSubagentSession, getBuiltInAgent, getForkWorkerSuffix, getSubagentSuffix, parseFrontmatter, preprocessShellCommands, projectPaths, promptForApproval, resolveSubagentLogDir, retrieveAgentToolDeps, storeAgentToolDeps, substituteVariables, userPaths };
1174
+ export { AgentExecutor, BUILT_IN_AGENTS, BuiltinCommandSource, BundlePluginInstaller, BundlePluginLoader, CommandRegistry, type IAgentDefinition, type IAgentExecutorOptions, type IAgentSession, type IAgentToolDeps, type IBundlePluginFeatures, type IBundlePluginInstallerOptions, type IBundlePluginManifest, type IBundleSkill, type ICommand, type ICommandResult, type ICommandSource, type ICreateQueryOptions, type IDiffLine, type IExecutionResult, type IInstalledPluginRecord, type IInstalledPluginsRegistry, type IInteractiveSessionEvents, type IInteractiveSessionOptions, type IKnownMarketplaceEntry, type IKnownMarketplacesRegistry, type ILoadedBundlePlugin, type IMarketplaceClientOptions, type IMarketplaceManifest, type IMarketplacePluginEntry, type IMarketplaceSource, type IPluginSettings, type IPromptExecutorOptions, type IPromptProvider, type ISubagentOptions, type ISubagentPromptOptions, type ISystemCommand, type IToolState, type IToolSummary, type ITransportAdapter, InteractiveSession, MarketplaceClient, PluginCommandSource, PluginSettingsStore, PromptExecutor, SkillCommandSource, type SkillPromptContext, type TEnabledPlugins, type TInteractiveEventName, type TInteractivePermissionHandler, type TPermissionResultValue, type TProviderFactory, type TSessionFactory, assembleSubagentPrompt, buildSkillPrompt, createAgentTool, createQuery, createSubagentLogger, createSubagentSession, getBuiltInAgent, getForkWorkerSuffix, getSubagentSuffix, parseFrontmatter, preprocessShellCommands, projectPaths, promptForApproval, resolveSubagentLogDir, retrieveAgentToolDeps, storeAgentToolDeps, substituteVariables, userPaths };
@@ -650,6 +650,7 @@ function createSession(options) {
650
650
  model: options.config.provider.model,
651
651
  maxTurns: options.maxTurns,
652
652
  sessionStore: options.sessionStore,
653
+ sessionId: options.sessionId,
653
654
  permissionHandler: options.permissionHandler,
654
655
  onTextDelta: options.onTextDelta,
655
656
  onToolExecution: options.onToolExecution,
@@ -1059,6 +1060,8 @@ function createSystemCommands() {
1059
1060
  " cost \u2014 Show session info",
1060
1061
  " context \u2014 Context window info",
1061
1062
  " permissions \u2014 Permission rules",
1063
+ " resume \u2014 Resume a previous session",
1064
+ " rename <name> \u2014 Rename the current session",
1062
1065
  " reset \u2014 Delete settings and exit"
1063
1066
  ].join("\n"),
1064
1067
  success: true
@@ -1197,6 +1200,30 @@ Messages: ${messageCount}`,
1197
1200
  };
1198
1201
  }
1199
1202
  },
1203
+ {
1204
+ name: "resume",
1205
+ description: "Resume a previous session",
1206
+ execute: (_session, _args) => ({
1207
+ message: "Opening session picker...",
1208
+ success: true,
1209
+ data: { triggerResumePicker: true }
1210
+ })
1211
+ },
1212
+ {
1213
+ name: "rename",
1214
+ description: "Rename the current session",
1215
+ execute: (_session, args) => {
1216
+ const name = args.trim();
1217
+ if (!name) {
1218
+ return { message: "Usage: rename <name>", success: false };
1219
+ }
1220
+ return {
1221
+ message: `Session renamed to "${name}".`,
1222
+ success: true,
1223
+ data: { name }
1224
+ };
1225
+ }
1226
+ },
1200
1227
  {
1201
1228
  name: "reset",
1202
1229
  description: "Delete settings",
@@ -2130,6 +2157,14 @@ var InteractiveSession = class {
2130
2157
  pendingRawInput;
2131
2158
  // Full history timeline (chat messages + events)
2132
2159
  history = [];
2160
+ // Session persistence
2161
+ sessionStore;
2162
+ sessionName;
2163
+ cwd;
2164
+ // Session restore state
2165
+ pendingRestoreMessages = null;
2166
+ resumeSessionId;
2167
+ forkSession;
2133
2168
  constructor(options) {
2134
2169
  this.commandExecutor = new SystemCommandExecutor(createSystemCommands());
2135
2170
  if ("session" in options && options.session) {
@@ -2139,6 +2174,30 @@ var InteractiveSession = class {
2139
2174
  const stdOpts = options;
2140
2175
  this.initPromise = this.initializeAsync(stdOpts);
2141
2176
  }
2177
+ this.sessionStore = options.sessionStore;
2178
+ this.sessionName = options.sessionName;
2179
+ this.cwd = ("cwd" in options ? options.cwd : void 0) ?? "";
2180
+ this.resumeSessionId = options.resumeSessionId;
2181
+ this.forkSession = options.forkSession ?? false;
2182
+ if (options.resumeSessionId && this.sessionStore) {
2183
+ const record = this.sessionStore.load(options.resumeSessionId);
2184
+ if (record) {
2185
+ this.history = record.history ?? [];
2186
+ this.sessionName = record.name;
2187
+ if (record.messages) {
2188
+ if (this.session) {
2189
+ for (const msg of record.messages) {
2190
+ const m = msg;
2191
+ if (m.role && m.content) {
2192
+ this.session.injectMessage(m.role, m.content);
2193
+ }
2194
+ }
2195
+ } else {
2196
+ this.pendingRestoreMessages = record.messages;
2197
+ }
2198
+ }
2199
+ }
2200
+ }
2142
2201
  }
2143
2202
  async initializeAsync(options) {
2144
2203
  const cwd = options.cwd;
@@ -2165,6 +2224,7 @@ var InteractiveSession = class {
2165
2224
  } catch {
2166
2225
  }
2167
2226
  const paths = projectPaths(cwd);
2227
+ const sessionId = this.resumeSessionId && !this.forkSession ? this.resumeSessionId : void 0;
2168
2228
  this.session = createSession({
2169
2229
  config: mergedConfig,
2170
2230
  context,
@@ -2176,8 +2236,20 @@ var InteractiveSession = class {
2176
2236
  permissionHandler: options.permissionHandler,
2177
2237
  provider: options.provider,
2178
2238
  onTextDelta: (delta) => this.handleTextDelta(delta),
2179
- onToolExecution: (event) => this.handleToolExecution(event)
2239
+ onToolExecution: (event) => this.handleToolExecution(event),
2240
+ sessionId
2180
2241
  });
2242
+ if (this.pendingRestoreMessages) {
2243
+ for (const msg of this.pendingRestoreMessages) {
2244
+ if (msg && typeof msg === "object" && "role" in msg && "content" in msg) {
2245
+ this.session.injectMessage(
2246
+ msg.role,
2247
+ msg.content
2248
+ );
2249
+ }
2250
+ }
2251
+ this.pendingRestoreMessages = null;
2252
+ }
2181
2253
  this.initialized = true;
2182
2254
  }
2183
2255
  async ensureInitialized() {
@@ -2267,6 +2339,30 @@ var InteractiveSession = class {
2267
2339
  getContextState() {
2268
2340
  return this.getSessionOrThrow().getContextState();
2269
2341
  }
2342
+ /** Get session name. */
2343
+ getName() {
2344
+ return this.sessionName;
2345
+ }
2346
+ /** Set session name and persist if store is available. */
2347
+ setName(name) {
2348
+ this.sessionName = name;
2349
+ if (this.sessionStore && this.session) {
2350
+ try {
2351
+ const id = this.getSessionOrThrow().getSessionId();
2352
+ const existing = this.sessionStore.load(id);
2353
+ if (existing) {
2354
+ existing.name = name;
2355
+ existing.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
2356
+ this.sessionStore.save(existing);
2357
+ }
2358
+ } catch {
2359
+ }
2360
+ }
2361
+ }
2362
+ /** Attach a transport adapter to this session. Calls transport.attach(this). */
2363
+ attachTransport(transport) {
2364
+ transport.attach(this);
2365
+ }
2270
2366
  /** Access underlying Session. For advanced use / testing only. */
2271
2367
  getSession() {
2272
2368
  return this.getSessionOrThrow();
@@ -2308,6 +2404,22 @@ var InteractiveSession = class {
2308
2404
  } finally {
2309
2405
  this.executing = false;
2310
2406
  this.emit("thinking", false);
2407
+ if (this.sessionStore && this.session) {
2408
+ try {
2409
+ const sessionId = this.getSessionOrThrow().getSessionId();
2410
+ const existing = this.sessionStore.load(sessionId);
2411
+ this.sessionStore.save({
2412
+ id: sessionId,
2413
+ name: this.sessionName ?? existing?.name,
2414
+ cwd: this.cwd ?? "",
2415
+ createdAt: existing?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
2416
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
2417
+ messages: this.getSessionOrThrow().getHistory(),
2418
+ history: this.history
2419
+ });
2420
+ } catch {
2421
+ }
2422
+ }
2311
2423
  if (this.pendingPrompt) {
2312
2424
  const queued = this.pendingPrompt;
2313
2425
  const queuedDisplay = this.pendingDisplayInput;
@@ -2595,6 +2707,8 @@ function createBuiltinCommands() {
2595
2707
  { name: "cost", description: "Show session info", source: "builtin" },
2596
2708
  { name: "context", description: "Context window info", source: "builtin" },
2597
2709
  { name: "permissions", description: "Permission rules", source: "builtin" },
2710
+ { name: "resume", description: "Resume a previous session", source: "builtin" },
2711
+ { name: "rename", description: "Rename the current session", source: "builtin" },
2598
2712
  { name: "plugin", description: "Manage plugins", source: "builtin" },
2599
2713
  { name: "reload-plugins", description: "Reload all plugin resources", source: "builtin" },
2600
2714
  { name: "reset", description: "Delete settings and exit", source: "builtin" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robota-sdk/agent-sdk",
3
- "version": "3.0.0-beta.45",
3
+ "version": "3.0.0-beta.47",
4
4
  "description": "Programmatic SDK for building AI agents with Robota — provides Session, query(), built-in tools, permissions, hooks, and context loading",
5
5
  "type": "module",
6
6
  "main": "dist/node/index.js",
@@ -24,9 +24,9 @@
24
24
  "dependencies": {
25
25
  "chalk": "^5.3.0",
26
26
  "zod": "^3.24.0",
27
- "@robota-sdk/agent-core": "3.0.0-beta.45",
28
- "@robota-sdk/agent-sessions": "3.0.0-beta.45",
29
- "@robota-sdk/agent-tools": "3.0.0-beta.45"
27
+ "@robota-sdk/agent-core": "3.0.0-beta.47",
28
+ "@robota-sdk/agent-tools": "3.0.0-beta.47",
29
+ "@robota-sdk/agent-sessions": "3.0.0-beta.47"
30
30
  },
31
31
  "devDependencies": {
32
32
  "rimraf": "^5.0.5",