@agent-api/app-engine 0.0.2 → 0.0.3

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/dist/agent.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { type AgentRunOptions, type AgentTurnEvent, type AgentTurnResult, type LocalToolApprovalRequest, type WorkdirAccessMode, agentResponseFailureMessage, agentTurnEventFromStreamEvent, clearPresetToolCatalogCache, isAvailablePreset, listAvailablePresets, resolveAgentRequestTools, resumeAgentAfterLocalApproval, runAgent, runAgentTurn, } from "./agent/runner.js";
2
- export { conversationSummary, deleteConversation, getConversation, listConversations, } from "./conversation/index.js";
2
+ export { conversationSummary, deleteConversation, ensureConversation, getConversation, listConversations, startFreshConversation, } from "./conversation/index.js";
package/dist/agent.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export { agentResponseFailureMessage, agentTurnEventFromStreamEvent, clearPresetToolCatalogCache, isAvailablePreset, listAvailablePresets, resolveAgentRequestTools, resumeAgentAfterLocalApproval, runAgent, runAgentTurn, } from "./agent/runner.js";
2
- export { conversationSummary, deleteConversation, getConversation, listConversations, } from "./conversation/index.js";
2
+ export { conversationSummary, deleteConversation, ensureConversation, getConversation, listConversations, startFreshConversation, } from "./conversation/index.js";
package/dist/config.d.ts CHANGED
@@ -25,9 +25,11 @@ export interface CLIConfig {
25
25
  profiles: Record<string, Profile>;
26
26
  }
27
27
  export interface ConversationState {
28
+ id: string;
28
29
  name: string;
29
30
  profile: string;
30
31
  previousResponseId?: string;
32
+ createdAt: number;
31
33
  updatedAt: number;
32
34
  }
33
35
  export interface WorkbenchPreferences {
@@ -51,6 +53,8 @@ export declare function activeProfile(profileName?: string): Promise<Profile>;
51
53
  export declare function emptyConfig(): CLIConfig;
52
54
  export declare function emptyAppConfiguration(): AppConfiguration;
53
55
  export declare function emptyConversationConfiguration(): ConversationConfiguration;
56
+ export declare function createConversationID(): string;
57
+ export declare function legacyConversationID(profile: string, name: string): string;
54
58
  export declare function loadWorkbenchPreferences(): Promise<WorkbenchPreferences>;
55
59
  export declare function updateWorkbenchPreferences(patch: {
56
60
  defaultPreset?: string | null | undefined;
package/dist/config.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { createHash, randomUUID } from "node:crypto";
2
3
  import { ensureRuntime, runtime } from "./runtime/index.js";
3
4
  export const defaultBaseURL = "https://api.agentsway.dev";
4
5
  export const configFile = "profiles.json";
@@ -25,9 +26,11 @@ const profileSchema = z.object({
25
26
  updatedAt: z.number(),
26
27
  });
27
28
  const conversationSchema = z.object({
29
+ id: z.string().optional(),
28
30
  name: z.string(),
29
31
  profile: z.string(),
30
32
  previousResponseId: z.string().optional(),
33
+ createdAt: z.number().optional(),
31
34
  updatedAt: z.number(),
32
35
  });
33
36
  const workbenchPreferencesSchema = z.object({
@@ -88,7 +91,11 @@ export async function loadConversationConfiguration() {
88
91
  if (!parsed.success) {
89
92
  throw new Error(`Invalid conversation configuration: ${parsed.error.issues.map((issue) => issue.message).join("; ")}`);
90
93
  }
91
- return parsed.data;
94
+ const normalized = normalizeConversationConfiguration(parsed.data);
95
+ if (normalized.changed) {
96
+ await saveConversationConfiguration(normalized.config);
97
+ }
98
+ return normalized.config;
92
99
  }
93
100
  export async function saveConversationConfiguration(config) {
94
101
  await ensureRuntime();
@@ -126,6 +133,31 @@ export function emptyAppConfiguration() {
126
133
  export function emptyConversationConfiguration() {
127
134
  return { conversations: {} };
128
135
  }
136
+ export function createConversationID() {
137
+ return `conv_${randomUUID().replace(/-/g, "").slice(0, 24)}`;
138
+ }
139
+ export function legacyConversationID(profile, name) {
140
+ return `conv_${createHash("sha256").update(`${profile}:${name}`).digest("hex").slice(0, 24)}`;
141
+ }
142
+ function normalizeConversationConfiguration(config) {
143
+ let changed = false;
144
+ const conversations = {};
145
+ for (const [key, conversation] of Object.entries(config.conversations)) {
146
+ const id = conversation.id || legacyConversationID(conversation.profile, conversation.name);
147
+ const createdAt = conversation.createdAt ?? conversation.updatedAt;
148
+ if (!conversation.id || !conversation.createdAt)
149
+ changed = true;
150
+ conversations[key] = {
151
+ id,
152
+ name: conversation.name,
153
+ profile: conversation.profile,
154
+ previousResponseId: conversation.previousResponseId,
155
+ createdAt,
156
+ updatedAt: conversation.updatedAt,
157
+ };
158
+ }
159
+ return { config: { conversations }, changed };
160
+ }
129
161
  export async function loadWorkbenchPreferences() {
130
162
  const appConfig = await loadAppConfiguration();
131
163
  return appConfig.workbench;
@@ -11,6 +11,8 @@ export declare function updateConversation(options: {
11
11
  profile?: string;
12
12
  conversation?: string;
13
13
  }, responseID: string): Promise<void>;
14
+ export declare function ensureConversation(name: string, profileName?: string): Promise<ConversationState>;
15
+ export declare function startFreshConversation(name: string, profileName?: string): Promise<ConversationState>;
14
16
  export declare function listConversations(profileName?: string): Promise<ConversationState[]>;
15
17
  export declare function getConversation(name: string, profileName?: string): Promise<ConversationState>;
16
18
  export declare function deleteConversation(name: string, profileName?: string): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { activeProfile, loadConversationConfiguration, saveConversationConfiguration } from "../config.js";
1
+ import { activeProfile, createConversationID, loadConversationConfiguration, saveConversationConfiguration, } from "../config.js";
2
2
  export function conversationKey(profile, name) {
3
3
  return `${profile}:${name}`;
4
4
  }
@@ -18,14 +18,53 @@ export async function updateConversation(options, responseID) {
18
18
  return;
19
19
  const profile = await activeProfile(options.profile);
20
20
  const config = await loadConversationConfiguration();
21
+ const key = conversationKey(profile.name, options.conversation);
22
+ const existing = config.conversations[key];
23
+ const now = Math.floor(Date.now() / 1000);
21
24
  config.conversations[conversationKey(profile.name, options.conversation)] = {
25
+ id: existing?.id ?? createConversationID(),
22
26
  name: options.conversation,
23
27
  profile: profile.name,
24
28
  previousResponseId: responseID,
25
- updatedAt: Math.floor(Date.now() / 1000),
29
+ createdAt: existing?.createdAt ?? now,
30
+ updatedAt: now,
26
31
  };
27
32
  await saveConversationConfiguration(config);
28
33
  }
34
+ export async function ensureConversation(name, profileName) {
35
+ const profile = await activeProfile(profileName);
36
+ const config = await loadConversationConfiguration();
37
+ const key = conversationKey(profile.name, name);
38
+ const existing = config.conversations[key];
39
+ if (existing)
40
+ return existing;
41
+ const now = Math.floor(Date.now() / 1000);
42
+ const conversation = {
43
+ id: createConversationID(),
44
+ name,
45
+ profile: profile.name,
46
+ createdAt: now,
47
+ updatedAt: now,
48
+ };
49
+ config.conversations[key] = conversation;
50
+ await saveConversationConfiguration(config);
51
+ return conversation;
52
+ }
53
+ export async function startFreshConversation(name, profileName) {
54
+ const profile = await activeProfile(profileName);
55
+ const config = await loadConversationConfiguration();
56
+ const now = Math.floor(Date.now() / 1000);
57
+ const conversation = {
58
+ id: createConversationID(),
59
+ name,
60
+ profile: profile.name,
61
+ createdAt: now,
62
+ updatedAt: now,
63
+ };
64
+ config.conversations[conversationKey(profile.name, name)] = conversation;
65
+ await saveConversationConfiguration(config);
66
+ return conversation;
67
+ }
29
68
  export async function listConversations(profileName) {
30
69
  const profile = await activeProfile(profileName);
31
70
  const config = await loadConversationConfiguration();
@@ -50,5 +89,5 @@ export async function deleteConversation(name, profileName) {
50
89
  export function conversationSummary(conversation) {
51
90
  const updated = new Date(conversation.updatedAt * 1000).toISOString();
52
91
  const response = conversation.previousResponseId ? ` response=${conversation.previousResponseId}` : "";
53
- return `${conversation.name}\t${conversation.profile}\t${updated}${response}`;
92
+ return `${conversation.name}\t${conversation.profile}\t${updated}\t${conversation.id}${response}`;
54
93
  }
@@ -12,6 +12,7 @@ export interface AgentEngineApp {
12
12
  subscribe(listener: () => void): () => void;
13
13
  dispatch(action: WorkbenchAction): void;
14
14
  maybeCheckForUpdate(options?: AgentEngineLifecycleOptions): Promise<void>;
15
+ loadInitialConversation(options?: AgentEngineLifecycleOptions): Promise<void>;
15
16
  loadInitialSettings(options?: AgentEngineLifecycleOptions): Promise<void>;
16
17
  loadWorkdir(path?: string, options?: AgentEngineLifecycleOptions): Promise<void>;
17
18
  refreshAuth(profile?: string, options?: AgentEngineLifecycleOptions): Promise<void>;
@@ -35,6 +35,37 @@ export function createAgentEngine(options) {
35
35
  const effects = await session.lifecycle.maybeCheckForUpdate();
36
36
  runLifecycleEffects(effects, lifecycleOptions);
37
37
  }
38
+ async function loadInitialConversation(lifecycleOptions = {}) {
39
+ try {
40
+ const state = session.engine.snapshot();
41
+ const conversation = await session.conversation.resolveConversation(state.currentConversation, options.baseOptions.profile);
42
+ if (lifecycleOptions.isMounted && !lifecycleOptions.isMounted())
43
+ return;
44
+ session.engine.dispatch({
45
+ type: "conversation.set",
46
+ id: conversation.id,
47
+ name: conversation.name,
48
+ previousResponseId: conversation.previousResponseId,
49
+ status: conversation.status,
50
+ });
51
+ if (conversation.previousResponseId) {
52
+ session.engine.dispatch({
53
+ type: "message.add",
54
+ role: "system",
55
+ text: `Continuing conversation "${conversation.name}" from ${conversation.previousResponseId}. Use /new to start without prior context.`,
56
+ });
57
+ }
58
+ }
59
+ catch (error) {
60
+ if (lifecycleOptions.isMounted && !lifecycleOptions.isMounted())
61
+ return;
62
+ session.engine.dispatch({
63
+ type: "activity.add",
64
+ level: "warning",
65
+ text: `Conversation state unavailable: ${userFacingError(error)}`,
66
+ });
67
+ }
68
+ }
38
69
  async function loadInitialSettings(lifecycleOptions = {}) {
39
70
  try {
40
71
  const settings = await session.settings.loadInitial({
@@ -127,6 +158,7 @@ export function createAgentEngine(options) {
127
158
  subscribe: session.engine.subscribe,
128
159
  dispatch: session.engine.dispatch,
129
160
  maybeCheckForUpdate,
161
+ loadInitialConversation,
130
162
  loadInitialSettings,
131
163
  loadWorkdir,
132
164
  refreshAuth,
@@ -1,7 +1,7 @@
1
1
  export type { AgentEngineApp, AgentEngineAppOptions, AgentEngineLifecycleOptions, } from "./agent-engine.js";
2
2
  export { createAgentEngine, } from "./agent-engine.js";
3
3
  export type { AgentRunOptions, AgentTurnEvent, LocalToolApprovalRequest, WorkdirAccessMode, } from "../agent.js";
4
- export { agentResponseFailureMessage, agentTurnEventFromStreamEvent, clearPresetToolCatalogCache, conversationSummary, deleteConversation, getConversation, isAvailablePreset, listAvailablePresets, listConversations, resumeAgentAfterLocalApproval, runAgent, resolveAgentRequestTools, runAgentTurn, } from "../agent.js";
4
+ export { agentResponseFailureMessage, agentTurnEventFromStreamEvent, clearPresetToolCatalogCache, conversationSummary, deleteConversation, ensureConversation, getConversation, isAvailablePreset, listAvailablePresets, listConversations, resumeAgentAfterLocalApproval, runAgent, resolveAgentRequestTools, runAgentTurn, startFreshConversation, } from "../agent.js";
5
5
  export type { ChatOptions } from "../chat-options.js";
6
6
  export { normalizeChatOptions } from "../chat-options.js";
7
7
  export type { AgentEngineServices } from "./services.js";
@@ -1,5 +1,5 @@
1
1
  export { createAgentEngine, } from "./agent-engine.js";
2
- export { agentResponseFailureMessage, agentTurnEventFromStreamEvent, clearPresetToolCatalogCache, conversationSummary, deleteConversation, getConversation, isAvailablePreset, listAvailablePresets, listConversations, resumeAgentAfterLocalApproval, runAgent, resolveAgentRequestTools, runAgentTurn, } from "../agent.js";
2
+ export { agentResponseFailureMessage, agentTurnEventFromStreamEvent, clearPresetToolCatalogCache, conversationSummary, deleteConversation, ensureConversation, getConversation, isAvailablePreset, listAvailablePresets, listConversations, resumeAgentAfterLocalApproval, runAgent, resolveAgentRequestTools, runAgentTurn, startFreshConversation, } from "../agent.js";
3
3
  export { normalizeChatOptions } from "../chat-options.js";
4
4
  export { defaultBaseURL } from "../config.js";
5
5
  export { activeProfile, loadAppConfiguration, loadConfig, loadConversationConfiguration, loadWorkbenchPreferences, redactSecret, saveAppConfiguration, saveConfig, saveConversationConfiguration, updateWorkbenchPreferences, } from "../config.js";
@@ -32,7 +32,7 @@ export function createWorkbenchCommandController(options) {
32
32
  await startNewConversation(command.name);
33
33
  return;
34
34
  case "switch_conversation":
35
- switchConversation(command.name);
35
+ await switchConversation(command.name);
36
36
  return;
37
37
  case "list_conversations":
38
38
  await showConversations();
@@ -278,17 +278,29 @@ export function createWorkbenchCommandController(options) {
278
278
  async function startNewConversation(name) {
279
279
  const conversation = await options.conversationController.startNewConversation(name, options.options.profile);
280
280
  dispatch({ type: "messages.clear" });
281
- dispatch({ type: "conversation.set", name: conversation.name });
281
+ dispatch({
282
+ type: "conversation.set",
283
+ id: conversation.id,
284
+ name: conversation.name,
285
+ previousResponseId: conversation.previousResponseId,
286
+ status: conversation.status,
287
+ });
282
288
  dispatch({
283
289
  type: "message.add",
284
290
  role: "system",
285
291
  text: conversation.message,
286
292
  });
287
293
  }
288
- function switchConversation(name) {
289
- const conversation = options.conversationController.switchConversation(name);
294
+ async function switchConversation(name) {
295
+ const conversation = await options.conversationController.switchConversation(name, options.options.profile);
290
296
  dispatch({ type: "messages.clear" });
291
- dispatch({ type: "conversation.set", name: conversation.name });
297
+ dispatch({
298
+ type: "conversation.set",
299
+ id: conversation.id,
300
+ name: conversation.name,
301
+ previousResponseId: conversation.previousResponseId,
302
+ status: conversation.status,
303
+ });
292
304
  dispatch({
293
305
  type: "message.add",
294
306
  role: "system",
@@ -1,14 +1,9 @@
1
1
  import { mkdir, writeFile } from "node:fs/promises";
2
- import { deleteConversation, listConversations } from "../agent.js";
2
+ import { deleteConversation, ensureConversation, listConversations, startFreshConversation } from "../agent.js";
3
3
  export interface WorkbenchConversationController {
4
- startNewConversation(name: string | undefined, profileName?: string): Promise<{
5
- name: string;
6
- message: string;
7
- }>;
8
- switchConversation(name: string): {
9
- name: string;
10
- message: string;
11
- };
4
+ resolveConversation(name: string, profileName?: string): Promise<ConversationSelection>;
5
+ startNewConversation(name: string | undefined, profileName?: string): Promise<ConversationSelection>;
6
+ switchConversation(name: string, profileName?: string): Promise<ConversationSelection>;
12
7
  listConversations(profileName?: string): Promise<string>;
13
8
  exportTranscript(input: {
14
9
  path?: string;
@@ -16,6 +11,13 @@ export interface WorkbenchConversationController {
16
11
  conversation: string;
17
12
  }): Promise<string>;
18
13
  }
14
+ export interface ConversationSelection {
15
+ id: string;
16
+ name: string;
17
+ previousResponseId?: string;
18
+ status: "fresh" | "continued";
19
+ message: string;
20
+ }
19
21
  export interface WorkbenchConversationControllerOptions {
20
22
  deleteConversationImpl?: typeof deleteConversation;
21
23
  listConversationsImpl?: typeof listConversations;
@@ -23,6 +25,8 @@ export interface WorkbenchConversationControllerOptions {
23
25
  writeFileImpl?: typeof writeFile;
24
26
  now?: () => Date;
25
27
  dataDir?: string;
28
+ ensureConversationImpl?: typeof ensureConversation;
29
+ startFreshConversationImpl?: typeof startFreshConversation;
26
30
  }
27
31
  export declare function createWorkbenchConversationController(options?: WorkbenchConversationControllerOptions): WorkbenchConversationController;
28
32
  export declare function defaultTranscriptExportPath(conversation: string, options?: {
@@ -1,27 +1,31 @@
1
1
  import { mkdir, writeFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
- import { conversationSummary, deleteConversation, listConversations, } from "../agent.js";
3
+ import { conversationSummary, deleteConversation, ensureConversation, listConversations, startFreshConversation, } from "../agent.js";
4
4
  import { runtime } from "../runtime/index.js";
5
5
  export function createWorkbenchConversationController(options = {}) {
6
6
  const deleteConversationImpl = options.deleteConversationImpl ?? deleteConversation;
7
7
  const listConversationsImpl = options.listConversationsImpl ?? listConversations;
8
+ const ensureConversationImpl = options.ensureConversationImpl ?? ensureConversation;
9
+ const startFreshConversationImpl = options.startFreshConversationImpl ?? startFreshConversation;
8
10
  const mkdirImpl = options.mkdirImpl ?? mkdir;
9
11
  const writeFileImpl = options.writeFileImpl ?? writeFile;
10
12
  const now = options.now ?? (() => new Date());
11
13
  return {
14
+ async resolveConversation(name, profileName) {
15
+ const conversation = await ensureConversationImpl(name, profileName);
16
+ return conversationSelection(conversation, `Conversation "${conversation.name}" is ${conversation.previousResponseId ? `continuing from ${conversation.previousResponseId}` : "fresh"}.`);
17
+ },
12
18
  async startNewConversation(name, profileName) {
13
- const conversation = name || createConversationName(now());
14
- await deleteConversationImpl(conversation, profileName);
15
- return {
16
- name: conversation,
17
- message: `Started fresh conversation "${conversation}".`,
18
- };
19
+ const nameToUse = name || createConversationName(now());
20
+ await deleteConversationImpl(nameToUse, profileName);
21
+ const conversation = await startFreshConversationImpl(nameToUse, profileName);
22
+ return conversationSelection(conversation, `Started fresh conversation "${conversation.name}" (${conversation.id}).`);
19
23
  },
20
- switchConversation(name) {
21
- return {
22
- name,
23
- message: `Switched to conversation "${name}". Future turns will continue this handle when history exists.`,
24
- };
24
+ async switchConversation(name, profileName) {
25
+ const conversation = await ensureConversationImpl(name, profileName);
26
+ return conversationSelection(conversation, conversation.previousResponseId
27
+ ? `Switched to conversation "${name}" (${conversation.id}). Continuing from ${conversation.previousResponseId}.`
28
+ : `Switched to fresh conversation "${name}" (${conversation.id}).`);
25
29
  },
26
30
  async listConversations(profileName) {
27
31
  const conversations = await listConversationsImpl(profileName);
@@ -42,6 +46,17 @@ export function createWorkbenchConversationController(options = {}) {
42
46
  },
43
47
  };
44
48
  }
49
+ function conversationSelection(conversation, message) {
50
+ const selection = {
51
+ id: conversation.id,
52
+ name: conversation.name,
53
+ status: conversation.previousResponseId ? "continued" : "fresh",
54
+ message,
55
+ };
56
+ if (conversation.previousResponseId)
57
+ selection.previousResponseId = conversation.previousResponseId;
58
+ return selection;
59
+ }
45
60
  export function defaultTranscriptExportPath(conversation, options = {}) {
46
61
  const safeConversation = conversation.replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "") || "conversation";
47
62
  const stamp = (options.now?.() ?? new Date()).toISOString().replace(/[:.]/g, "-");
@@ -11,6 +11,9 @@ export interface WorkbenchRenderModel {
11
11
  accessMode: string;
12
12
  contextEnabled: boolean;
13
13
  conversation: string;
14
+ conversationId: string;
15
+ conversationPreviousResponseId: string;
16
+ conversationStatus: "fresh" | "continued" | "unknown";
14
17
  model: string;
15
18
  pendingLocalLabel: string;
16
19
  preset: string;
@@ -28,6 +28,9 @@ export function buildWorkbenchRenderModel(input) {
28
28
  accessMode: input.state.accessMode,
29
29
  contextEnabled: input.state.contextEnabled,
30
30
  conversation: input.state.currentConversation,
31
+ conversationId: input.state.conversationId || "unresolved",
32
+ conversationPreviousResponseId: input.state.conversationPreviousResponseId || "",
33
+ conversationStatus: input.state.conversationStatus,
31
34
  model: input.state.runModel || "auto",
32
35
  pendingLocalLabel: pendingLocalLabel(input.state),
33
36
  preset: input.state.runPreset || "none",
@@ -34,6 +34,9 @@ export interface WorkbenchState {
34
34
  activeAssistantMessageId: string | null;
35
35
  pendingLocalTool: LocalToolApproval | null;
36
36
  accessMode: WorkdirAccessMode;
37
+ conversationId?: string;
38
+ conversationPreviousResponseId?: string;
39
+ conversationStatus: "fresh" | "continued" | "unknown";
37
40
  currentConversation: string;
38
41
  runPreset?: string;
39
42
  runModel?: string;
@@ -87,7 +90,10 @@ export type WorkbenchAction = {
87
90
  mode: WorkdirAccessMode;
88
91
  } | {
89
92
  type: "conversation.set";
93
+ id?: string;
90
94
  name: string;
95
+ previousResponseId?: string;
96
+ status?: "fresh" | "continued" | "unknown";
91
97
  } | {
92
98
  type: "settings.set";
93
99
  settings: Partial<Pick<WorkbenchState, "runPreset" | "runModel" | "renderMode" | "defaultPreset" | "shellIsolation">>;
@@ -13,6 +13,9 @@ export function createInitialWorkbenchState(options) {
13
13
  activeAssistantMessageId: null,
14
14
  pendingLocalTool: null,
15
15
  accessMode,
16
+ conversationId: undefined,
17
+ conversationPreviousResponseId: undefined,
18
+ conversationStatus: "unknown",
16
19
  currentConversation: options.conversation || "default",
17
20
  runPreset: options.preset,
18
21
  runModel: options.model,
@@ -132,8 +135,11 @@ export function workbenchReducer(state, action) {
132
135
  case "conversation.set":
133
136
  return {
134
137
  ...state,
138
+ conversationId: action.id,
135
139
  currentConversation: action.name,
136
- activities: [...state.activities, newActivity("info", `Conversation: ${action.name}`)].slice(-20),
140
+ conversationPreviousResponseId: action.previousResponseId,
141
+ conversationStatus: action.status ?? (action.previousResponseId ? "continued" : "fresh"),
142
+ activities: [...state.activities, newActivity("info", conversationActivityText(action))].slice(-20),
137
143
  };
138
144
  case "settings.set":
139
145
  return {
@@ -144,6 +150,10 @@ export function workbenchReducer(state, action) {
144
150
  return state;
145
151
  }
146
152
  }
153
+ function conversationActivityText(action) {
154
+ const suffix = action.previousResponseId ? ` continues ${action.previousResponseId}` : action.status === "fresh" ? " fresh" : "";
155
+ return `Conversation: ${action.name}${suffix}`;
156
+ }
147
157
  function setLocalAccess(state, mode) {
148
158
  return {
149
159
  ...state,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-api/app-engine",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Renderer-neutral application engine for Agent API apps",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/scalebox-dev/agent-tui#readme",