@markusylisiurunen/tau 0.3.45 → 0.3.46

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.
Files changed (62) hide show
  1. package/README.md +1 -1
  2. package/dist/core/agent/agent_runtime.js +1 -1
  3. package/dist/core/agent/agent_runtime.js.map +1 -1
  4. package/dist/core/debug.js +2 -2
  5. package/dist/core/debug.js.map +1 -1
  6. package/dist/core/runtime/chat_runtime.js +10 -6
  7. package/dist/core/runtime/chat_runtime.js.map +1 -1
  8. package/dist/core/runtime/deps.js +0 -1
  9. package/dist/core/runtime/deps.js.map +1 -1
  10. package/dist/core/runtime/runtime_bootstrap.js +20 -3
  11. package/dist/core/runtime/runtime_bootstrap.js.map +1 -1
  12. package/dist/core/runtime/session_prompt_composer.js +6 -4
  13. package/dist/core/runtime/session_prompt_composer.js.map +1 -1
  14. package/dist/core/session/runner.js +4 -3
  15. package/dist/core/session/runner.js.map +1 -1
  16. package/dist/core/subagents/agent_supervisor.js +64 -31
  17. package/dist/core/subagents/agent_supervisor.js.map +1 -1
  18. package/dist/core/subagents/types.js +0 -1
  19. package/dist/core/subagents/types.js.map +1 -1
  20. package/dist/core/utils/context_builder.js +11 -9
  21. package/dist/core/utils/context_builder.js.map +1 -1
  22. package/dist/core/version.js +1 -1
  23. package/dist/host/execution_runtime.js +3 -2
  24. package/dist/host/execution_runtime.js.map +1 -1
  25. package/dist/host/hosted_ephemeral_agent_session.js +3 -2
  26. package/dist/host/hosted_ephemeral_agent_session.js.map +1 -1
  27. package/dist/host/local_session_host.js +90 -32
  28. package/dist/host/local_session_host.js.map +1 -1
  29. package/dist/host/session_host.js.map +1 -1
  30. package/dist/host/session_protocol_handler.js +29 -0
  31. package/dist/host/session_protocol_handler.js.map +1 -1
  32. package/dist/protocol/index.d.ts +2 -2
  33. package/dist/protocol/index.js +1 -1
  34. package/dist/protocol/index.js.map +1 -1
  35. package/dist/protocol/session_protocol.d.ts +66 -3
  36. package/dist/protocol/session_protocol.js +297 -1
  37. package/dist/protocol/session_protocol.js.map +1 -1
  38. package/dist/sdk/index.d.ts +4 -4
  39. package/dist/sdk/index.js +1 -1
  40. package/dist/sdk/index.js.map +1 -1
  41. package/dist/sdk/session.js +72 -1
  42. package/dist/sdk/session.js.map +1 -1
  43. package/dist/sdk/types.d.ts +7 -1
  44. package/dist/transport/in_process_session_transport.js +15 -1
  45. package/dist/transport/in_process_session_transport.js.map +1 -1
  46. package/dist/transport/index.d.ts +1 -1
  47. package/dist/transport/index.js.map +1 -1
  48. package/dist/transport/session_protocol_transport_helpers.js +14 -0
  49. package/dist/transport/session_protocol_transport_helpers.js.map +1 -1
  50. package/dist/transport/session_transport.d.ts +3 -1
  51. package/dist/transport/stdio_session_transport.d.ts +3 -1
  52. package/dist/transport/stdio_session_transport.js +15 -1
  53. package/dist/transport/stdio_session_transport.js.map +1 -1
  54. package/dist/transport/websocket_session_transport.d.ts +3 -1
  55. package/dist/transport/websocket_session_transport.js +15 -1
  56. package/dist/transport/websocket_session_transport.js.map +1 -1
  57. package/dist/tui/chat_view.js.map +1 -1
  58. package/dist/tui/session_chat_controller.js +40 -12
  59. package/dist/tui/session_chat_controller.js.map +1 -1
  60. package/dist/tui/ui/subagent_panel.js +25 -48
  61. package/dist/tui/ui/subagent_panel.js.map +1 -1
  62. package/package.json +1 -1
@@ -5,12 +5,11 @@ import { assistantHistoryEntries, toolHistoryEntry, userHistoryEntry, } from "..
5
5
  import { ChatRuntime } from "../core/runtime/chat_runtime.js";
6
6
  import { formatSteeringUserMessage } from "../core/runtime/steering.js";
7
7
  import { buildGoalContinuationText, prependGoalPolicy } from "../core/session/goal.js";
8
- import { SUBAGENT_ACTIVITY_FACET_KIND } from "../core/subagents/types.js";
9
8
  import { buildToolRunPresentation, TOOL_UI_FACET_VERSION } from "../core/tools/presentation.js";
10
9
  import { appendUsageLogEntry, getUsageCostTotal, getUsageTotals, } from "../core/usage/logs.js";
11
10
  import { filterProjectPathAutocompleteEntries, loadProjectPathAutocompleteEntriesWithBackend, } from "../core/utils/project_files.js";
12
11
  import { hasGoalTurnMetadata } from "../core/utils/user_metadata.js";
13
- import { applySessionProtocolDelta, createSessionProtocolDeltaMessage, createSessionProtocolEphemeralMessage, projectSessionProtocolNoticePresentation, } from "../protocol/session_protocol.js";
12
+ import { applySessionProtocolDelta, createSessionProtocolDeltaMessage, createSessionProtocolEphemeralMessage, createSessionProtocolSubagentActivitiesMessage, projectSessionProtocolNoticePresentation, projectSessionProtocolSubagentActivity, SESSION_PROTOCOL_MAX_SUBAGENT_ACTIVITIES, } from "../protocol/session_protocol.js";
14
13
  import { LEGACY_SESSION_MODEL_CONTEXT_KEY } from "../store/session_snapshot_migrations.js";
15
14
  import { ClientToolBroker } from "./client_tool_broker.js";
16
15
  import { createExecutionEnvironmentSubagentPromptResolver } from "./execution_runtime.js";
@@ -119,18 +118,22 @@ export class LocalSessionHost {
119
118
  }
120
119
  async createLocalSessionHandleFromRuntimeContext(executionEnvironment, runtimeContext, bootstrap, catalog, committedSnapshot, createParams, forceNextSnapshotRevision = false) {
121
120
  let hostedSession;
121
+ const sessionId = committedSnapshot?.sessionId ?? randomUUID();
122
+ const createdAt = committedSnapshot?.createdAt ?? this.sessionOptions.environment.now();
122
123
  const runtime = ChatRuntime.create({
124
+ sessionId,
125
+ createdAt,
123
126
  persona: bootstrap.persona,
124
127
  backend: executionEnvironment.getToolExecutionBackend(),
125
128
  clientTools: (sessionId) => this.clientToolBroker.getToolDefinitions(sessionId),
126
129
  modelResolver: bootstrap.modelResolver,
127
130
  resolveSubagentPrompts: createExecutionEnvironmentSubagentPromptResolver({
131
+ sessionId,
128
132
  executionEnvironment,
129
133
  includeAgentContext: this.sessionOptions.includeAgentContext,
130
- now: this.sessionOptions.environment.now,
134
+ sessionStartedAt: createdAt,
131
135
  }),
132
136
  promptContext: runtimeContext.promptBootstrap.promptContext,
133
- environment: this.sessionOptions.environment,
134
137
  eventSink: async (event) => await hostedSession.enqueueRuntimeEvent(event),
135
138
  subagentEventSink: async (event) => await hostedSession.recordSubagentEvent(event),
136
139
  goalManager: {
@@ -150,7 +153,6 @@ export class LocalSessionHost {
150
153
  if (!attributes) {
151
154
  throw new Error("session attributes are required");
152
155
  }
153
- const createdAt = committedSnapshot?.createdAt ?? this.sessionOptions.environment.now();
154
156
  hostedSession = new LocalHostedSessionHandle(runtime, runtimeContext.promptBootstrap, catalog, bootstrap, this.sessionOptions.includeAgentContext, executionEnvironment, this.store, this.history, this.historyRemote, attributes, createdAt, committedSnapshot, forceNextSnapshotRevision, this.sessionOptions.recordUsage ?? appendUsageLogEntry, (session) => this.sessions.delete(session));
155
157
  const historyFailure = this.history.registerSession({
156
158
  sessionId: committedSnapshot?.sessionId ?? hostedSession.sessionId,
@@ -377,6 +379,9 @@ class LocalHostedSessionHandle {
377
379
  facets = new Map();
378
380
  deltaListeners = new Set();
379
381
  ephemeralListeners = new Set();
382
+ subagentActivitiesByAgent = new Map();
383
+ subagentActivitiesListeners = new Set();
384
+ subagentActivitiesRevision = 1;
380
385
  ephemeralAgentSessions = new Map();
381
386
  pathAutocompleteCache;
382
387
  pathAutocompleteLoad;
@@ -447,6 +452,18 @@ class LocalHostedSessionHandle {
447
452
  this.ephemeralListeners.delete(handler);
448
453
  };
449
454
  }
455
+ subagentActivities() {
456
+ return {
457
+ revision: this.subagentActivitiesRevision,
458
+ agents: structuredClone(Object.fromEntries(this.subagentActivitiesByAgent)),
459
+ };
460
+ }
461
+ onSubagentActivities(handler) {
462
+ this.subagentActivitiesListeners.add(handler);
463
+ return () => {
464
+ this.subagentActivitiesListeners.delete(handler);
465
+ };
466
+ }
450
467
  getGoal() {
451
468
  return structuredClone(this.goal);
452
469
  }
@@ -1054,6 +1071,8 @@ class LocalHostedSessionHandle {
1054
1071
  const contextId = `ephemeral-${randomUUID()}`;
1055
1072
  const session = new HostedEphemeralAgentSession({
1056
1073
  contextId,
1074
+ sessionId: this.sessionId,
1075
+ sessionStartedAt: this.createdAt,
1057
1076
  persona: this.runtime.persona,
1058
1077
  config: this.bootstrap.config ?? {},
1059
1078
  discoveredSkills: this.bootstrap.discoveredSkills,
@@ -1292,9 +1311,9 @@ class LocalHostedSessionHandle {
1292
1311
  await this.resolveCommittedLogicalSteering(committedSteering, outcome);
1293
1312
  return outcome;
1294
1313
  }
1295
- async commitSnapshot() {
1314
+ async commitSnapshot(options = {}) {
1296
1315
  this.assertNotDisposed();
1297
- this.reconcileProjections();
1316
+ this.reconcileProjections(options);
1298
1317
  const draft = this.buildSnapshotDraft();
1299
1318
  await this.switchSnapshotSession(draft.sessionId);
1300
1319
  const snapshot = {
@@ -1302,6 +1321,9 @@ class LocalHostedSessionHandle {
1302
1321
  revision: this.nextSnapshotRevision(draft),
1303
1322
  };
1304
1323
  if (this.persistedSnapshot && isDeepStrictEqual(this.persistedSnapshot, snapshot)) {
1324
+ if (options.removeMissingAgents) {
1325
+ this.removeMissingSubagentActivities();
1326
+ }
1305
1327
  return cloneSessionProtocolSnapshot(this.committedSnapshot ?? snapshot);
1306
1328
  }
1307
1329
  await this.store.commitSessionSnapshot(snapshot, {
@@ -1309,6 +1331,9 @@ class LocalHostedSessionHandle {
1309
1331
  });
1310
1332
  this.persistedSnapshot = cloneSessionProtocolSnapshot(snapshot);
1311
1333
  this.committedSnapshot = cloneSessionProtocolSnapshot(snapshot);
1334
+ if (options.removeMissingAgents) {
1335
+ this.removeMissingSubagentActivities();
1336
+ }
1312
1337
  return cloneSessionProtocolSnapshot(snapshot);
1313
1338
  }
1314
1339
  async commitProjectedSnapshot() {
@@ -1616,7 +1641,7 @@ class LocalHostedSessionHandle {
1616
1641
  return JSON.stringify(current) === JSON.stringify(next) ? revision : revision + 1;
1617
1642
  }
1618
1643
  async recordSubagentEvent(event) {
1619
- await this.enqueueMutation(() => this.recordSubagentUiEvent(event));
1644
+ await this.enqueueMutation(() => this.applySubagentEvent(event));
1620
1645
  }
1621
1646
  async enqueueRuntimeEvent(event) {
1622
1647
  await this.enqueueMutation(() => this.recordRuntimeEvent(event));
@@ -1846,8 +1871,7 @@ class LocalHostedSessionHandle {
1846
1871
  }
1847
1872
  const cutoffSequence = rewindItem.sequence - 1;
1848
1873
  this.timeline.items = this.timeline.items.filter((item) => item.sequence <= cutoffSequence);
1849
- this.reconcileProjections({ removeMissingAgents: true });
1850
- const snapshot = await this.commitSnapshot();
1874
+ const snapshot = await this.commitSnapshot({ removeMissingAgents: true });
1851
1875
  this.emitSnapshotReset({ type: "rewind", epoch: this.timeline.epoch, cutoffSequence }, snapshot);
1852
1876
  await this.recordHistoryFailure(this.history.truncateFromSources(this.sessionId, event.removedEntryIds, this.historyRemote));
1853
1877
  return;
@@ -2103,13 +2127,12 @@ class LocalHostedSessionHandle {
2103
2127
  this.operations.clear();
2104
2128
  this.facets.clear();
2105
2129
  this.draftAssistantMessage = undefined;
2106
- this.reconcileProjections({ removeMissingAgents: true });
2107
2130
  const summary = this.session.rawHistoryEntries.find((entry) => entry.id === event.result.summaryHistoryEntryId);
2108
2131
  if (!summary) {
2109
2132
  throw new Error(`missing compaction summary '${event.result.summaryHistoryEntryId}' in runtime history`);
2110
2133
  }
2111
2134
  this.appendMessageTimelineItem(summary.id, summary.message.timestamp);
2112
- const snapshot = await this.commitSnapshot();
2135
+ const snapshot = await this.commitSnapshot({ removeMissingAgents: true });
2113
2136
  this.emitSnapshotReset({
2114
2137
  type: "compaction",
2115
2138
  previousEpoch,
@@ -2170,36 +2193,71 @@ class LocalHostedSessionHandle {
2170
2193
  { type: "facet.set", facet: structuredClone(facet) },
2171
2194
  ], { persist: false });
2172
2195
  }
2173
- async recordSubagentUiEvent(event) {
2196
+ async applySubagentEvent(event) {
2174
2197
  const agent = agentRunFromSubagentEvent(event);
2175
- const previousCost = this.agentCostTotals.get(agent.id) ?? 0;
2176
- this.costTotal += Math.max(0, agent.costTotal - previousCost);
2177
- this.agentCostTotals.set(agent.id, agent.costTotal);
2178
2198
  if (!this.session.hasSubagent(agent.id)) {
2179
2199
  return;
2180
2200
  }
2201
+ if (event.type === "subagent_activity") {
2202
+ const current = this.subagentActivitiesByAgent.get(agent.id);
2203
+ if (!current || current.runRevision !== agent.run.revision) {
2204
+ throw new Error(`missing activity state for subagent run '${agent.id}'`);
2205
+ }
2206
+ current.activities.push(projectSessionProtocolSubagentActivity(event.activity));
2207
+ if (current.activities.length > SESSION_PROTOCOL_MAX_SUBAGENT_ACTIVITIES) {
2208
+ current.activities.splice(0, current.activities.length - SESSION_PROTOCOL_MAX_SUBAGENT_ACTIVITIES);
2209
+ }
2210
+ this.publishSubagentActivities([
2211
+ { type: "agent.set", agentId: agent.id, state: structuredClone(current) },
2212
+ ]);
2213
+ return;
2214
+ }
2215
+ const previousCost = this.agentCostTotals.get(agent.id) ?? 0;
2216
+ this.costTotal += Math.max(0, agent.costTotal - previousCost);
2217
+ this.agentCostTotals.set(agent.id, agent.costTotal);
2181
2218
  this.agents.set(agent.id, agent);
2182
- const changes = [
2219
+ await this.emitPatch("agent-run", [
2183
2220
  { type: "cost.set", costTotal: this.costTotal },
2184
2221
  { type: "agent.set", agent: structuredClone(agent) },
2185
- ];
2186
- const facetId = `subagent-activity-${agent.id}`;
2187
- if (event.type === "subagent_activity") {
2188
- const facet = {
2189
- id: facetId,
2190
- subject: { type: "agent", id: agent.id },
2191
- kind: SUBAGENT_ACTIVITY_FACET_KIND,
2192
- version: 1,
2193
- data: { text: event.text },
2222
+ ]);
2223
+ if (event.type === "subagent_spawned" || event.type === "subagent_run_started") {
2224
+ const state = {
2225
+ runRevision: agent.run.revision,
2226
+ activities: [],
2194
2227
  };
2195
- this.facets.set(facet.id, facet);
2196
- changes.push({ type: "facet.set", facet: structuredClone(facet) });
2228
+ this.subagentActivitiesByAgent.set(agent.id, state);
2229
+ this.publishSubagentActivities([
2230
+ { type: "agent.set", agentId: agent.id, state: structuredClone(state) },
2231
+ ]);
2197
2232
  }
2198
- else if ((event.type === "subagent_run_started" || event.type === "subagent_finished") &&
2199
- this.facets.delete(facetId)) {
2200
- changes.push({ type: "facet.remove", id: facetId });
2233
+ }
2234
+ removeMissingSubagentActivities() {
2235
+ const changes = [];
2236
+ for (const id of this.subagentActivitiesByAgent.keys()) {
2237
+ if (!this.session.hasSubagent(id)) {
2238
+ this.subagentActivitiesByAgent.delete(id);
2239
+ changes.push({ type: "agent.remove", agentId: id });
2240
+ }
2241
+ }
2242
+ if (changes.length > 0) {
2243
+ this.publishSubagentActivities(changes);
2244
+ }
2245
+ }
2246
+ publishSubagentActivities(changes) {
2247
+ this.subagentActivitiesRevision += 1;
2248
+ const message = createSessionProtocolSubagentActivitiesMessage({
2249
+ sessionId: this.sessionId,
2250
+ revision: this.subagentActivitiesRevision,
2251
+ changes,
2252
+ });
2253
+ for (const listener of [...this.subagentActivitiesListeners]) {
2254
+ try {
2255
+ listener(message);
2256
+ }
2257
+ catch {
2258
+ // Subagent activity observers must not be able to fail hosted session work.
2259
+ }
2201
2260
  }
2202
- await this.emitPatch("agent-run", changes, event.type === "subagent_activity" ? { persist: false } : {});
2203
2261
  }
2204
2262
  buildAssistantPartialChanges(previousDraft, nextDraft) {
2205
2263
  if (!previousDraft) {