@agent-native/core 0.157.5 → 0.157.7

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 (109) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/agent-native.config.ts +5 -0
  3. package/corpus/templates/analytics/netlify.toml +1 -0
  4. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +23 -5
  5. package/corpus/templates/analytics/server/plugins/agent-chat.ts +4 -0
  6. package/corpus/templates/assets/netlify.toml +3 -0
  7. package/corpus/templates/brain/netlify.toml +3 -0
  8. package/corpus/templates/calendar/agent-native.config.ts +5 -0
  9. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +4 -1
  10. package/corpus/templates/calendar/netlify.toml +3 -0
  11. package/corpus/templates/chat/agent-native.config.ts +5 -0
  12. package/corpus/templates/chat/netlify.toml +3 -0
  13. package/corpus/templates/clips/actions/create-meeting.ts +19 -1
  14. package/corpus/templates/clips/actions/lib/meeting-content.ts +28 -0
  15. package/corpus/templates/clips/actions/list-meetings.ts +33 -11
  16. package/corpus/templates/clips/app/components/meetings/bullet-link.tsx +48 -25
  17. package/corpus/templates/clips/app/components/meetings/canvas-editor.tsx +7 -6
  18. package/corpus/templates/clips/app/components/meetings/transcript-bubbles.tsx +388 -178
  19. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +7 -13
  20. package/corpus/templates/clips/app/components/transcript/transcript-segment-row.tsx +98 -0
  21. package/corpus/templates/clips/app/i18n/en-US.ts +5 -0
  22. package/corpus/templates/clips/app/lib/meeting-history-query.ts +11 -0
  23. package/corpus/templates/clips/app/lib/public-meeting.ts +4 -0
  24. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +49 -31
  25. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +47 -21
  26. package/corpus/templates/clips/app/routes/share.meeting.$meetingId.tsx +15 -1
  27. package/corpus/templates/clips/netlify.toml +8 -4
  28. package/corpus/templates/clips/server/routes/api/public-meeting.get.ts +10 -0
  29. package/corpus/templates/clips/shared/transcript-segments.ts +20 -2
  30. package/corpus/templates/content/netlify.toml +3 -0
  31. package/corpus/templates/design/app/i18n-data.ts +2 -0
  32. package/corpus/templates/design/netlify.toml +3 -0
  33. package/corpus/templates/dispatch/netlify.toml +3 -0
  34. package/corpus/templates/factory/netlify.toml +3 -0
  35. package/corpus/templates/forms/netlify.toml +3 -0
  36. package/corpus/templates/macros/netlify.toml +3 -0
  37. package/corpus/templates/mail/agent-native.config.ts +5 -0
  38. package/corpus/templates/mail/netlify.toml +3 -0
  39. package/corpus/templates/plan/netlify.toml +3 -0
  40. package/corpus/templates/slides/netlify.toml +3 -0
  41. package/dist/agent/harness/acp-adapter.js +17 -2
  42. package/dist/agent/harness/ai-sdk-adapter.js +14 -3
  43. package/dist/agent/harness/background.js +10 -5
  44. package/dist/agent/harness/hosted.d.ts +20 -0
  45. package/dist/agent/harness/hosted.js +100 -0
  46. package/dist/agent/harness/runner.js +100 -77
  47. package/dist/agent/observational-memory/observer.js +12 -0
  48. package/dist/agent/production-agent.d.ts +3 -0
  49. package/dist/agent/production-agent.js +74 -4
  50. package/dist/agent/thread-data-builder.d.ts +12 -0
  51. package/dist/agent/thread-data-builder.js +23 -0
  52. package/dist/agent/types.d.ts +6 -0
  53. package/dist/client/AgentPanel.d.ts +5 -1
  54. package/dist/client/AgentPanel.js +113 -17
  55. package/dist/client/AgentTaskCard.d.ts +2 -2
  56. package/dist/client/AgentTaskCard.js +8 -22
  57. package/dist/client/AssistantChat.d.ts +8 -0
  58. package/dist/client/AssistantChat.js +106 -59
  59. package/dist/client/MultiTabAssistantChat.js +50 -6
  60. package/dist/client/NewWorkspaceAppFlow.js +7 -1
  61. package/dist/client/agent-chat-adapter.d.ts +6 -0
  62. package/dist/client/agent-chat-adapter.js +36 -8
  63. package/dist/client/app-chat-sidebar.d.ts +5 -0
  64. package/dist/client/app-chat-sidebar.js +53 -9
  65. package/dist/client/chat/composer-draft.d.ts +4 -0
  66. package/dist/client/chat/composer-draft.js +63 -0
  67. package/dist/client/chat-first/apps-rail.js +10 -1
  68. package/dist/client/chat-first/primary-nav.js +10 -5
  69. package/dist/client/frame-protocol.d.ts +1 -0
  70. package/dist/client/hooks/index.d.ts +1 -1
  71. package/dist/client/hooks/index.js +1 -1
  72. package/dist/client/i18n.js +5 -2
  73. package/dist/client/progress/RunsTray.js +129 -16
  74. package/dist/client/settings/SettingsRow.js +1 -1
  75. package/dist/client/use-chat-threads.js +11 -6
  76. package/dist/collab/routes.d.ts +1 -1
  77. package/dist/collab/struct-routes.d.ts +1 -1
  78. package/dist/config.d.ts +11 -0
  79. package/dist/config.js +52 -0
  80. package/dist/deploy/build.js +28 -11
  81. package/dist/extensions/actions.js +22 -1
  82. package/dist/hosted-harness/actions/get-hosted-harness-config.d.ts +2 -0
  83. package/dist/hosted-harness/actions/get-hosted-harness-config.js +13 -0
  84. package/dist/hosted-harness/actions/set-hosted-harness-enabled.d.ts +4 -0
  85. package/dist/hosted-harness/actions/set-hosted-harness-enabled.js +32 -0
  86. package/dist/localization/default-messages.d.ts +4 -1
  87. package/dist/localization/default-messages.js +5 -2
  88. package/dist/observability/routes.d.ts +5 -5
  89. package/dist/provider-api/actions/custom-provider-registration.d.ts +6 -6
  90. package/dist/provider-api/actions/provider-api.d.ts +4 -4
  91. package/dist/resources/handlers.d.ts +1 -1
  92. package/dist/secrets/routes.d.ts +9 -9
  93. package/dist/server/action-discovery.js +12 -0
  94. package/dist/server/agent-chat-plugin.js +24 -4
  95. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  96. package/dist/server/agent-teams.d.ts +20 -12
  97. package/dist/server/agent-teams.js +69 -35
  98. package/dist/server/hosted-harness-policy.d.ts +17 -0
  99. package/dist/server/hosted-harness-policy.js +38 -0
  100. package/dist/server/realtime-token.d.ts +1 -1
  101. package/dist/server/request-context.d.ts +4 -0
  102. package/dist/server/transcribe-voice.d.ts +1 -1
  103. package/dist/styles/agent-native.css +39 -0
  104. package/dist/templates/chat/agent-native.config.ts +5 -0
  105. package/dist/templates/chat/netlify.toml +3 -0
  106. package/dist/vite/action-types-plugin.js +8 -0
  107. package/package.json +4 -2
  108. package/src/templates/chat/agent-native.config.ts +5 -0
  109. package/src/templates/chat/netlify.toml +3 -0
@@ -66,6 +66,10 @@ export interface AgentTask {
66
66
  taskId: string;
67
67
  threadId: string;
68
68
  parentThreadId?: string;
69
+ /** Request owner used to scope every browser-visible task read and control. */
70
+ ownerEmail?: string | null;
71
+ /** Organization scope captured when the task was spawned. */
72
+ orgId?: string | null;
69
73
  name?: string;
70
74
  description: string;
71
75
  status: "running" | "completed" | "errored";
@@ -85,6 +89,10 @@ export interface AgentTask {
85
89
  */
86
90
  delegationDepth?: number;
87
91
  }
92
+ export interface AgentTeamOwnerScope {
93
+ ownerEmail: string | null;
94
+ orgId?: string | null;
95
+ }
88
96
  export type AgentTeamBackgroundRun = Omit<BackgroundAgentRun, "kind" | "source" | "sourceRecord" | "status" | "cwd" | "goalId" | "transcriptPath" | "artifactRoot"> & {
89
97
  kind: "agent-team";
90
98
  source: "hosted-agent-team";
@@ -272,25 +280,25 @@ export declare function processAgentTeamRun(opts: ProcessAgentTeamRunOptions): P
272
280
  ok: boolean;
273
281
  skipped?: string;
274
282
  }>;
275
- /** Get task by ID */
276
- export declare function getTask(taskId: string): Promise<AgentTask | undefined>;
277
- /** Get task by thread ID */
278
- export declare function getTaskByThread(threadId: string): Promise<AgentTask | undefined>;
279
- /** List all tasks (most recent first) */
280
- export declare function listTasks(): Promise<AgentTask[]>;
281
- export declare function listAgentTeamBackgroundRuns(): Promise<AgentTeamBackgroundRun[]>;
282
- export declare function getAgentTeamBackgroundRun(runId: string): Promise<AgentTeamBackgroundRun | null>;
283
- export declare function listAgentTeamBackgroundTranscriptEvents(runId: string): Promise<AgentTeamBackgroundTranscriptEvent[]>;
283
+ /** Get task by ID, optionally constrained to the current request scope. */
284
+ export declare function getTask(taskId: string, scope?: AgentTeamOwnerScope): Promise<AgentTask | undefined>;
285
+ /** Get task by thread ID, optionally constrained to the current request scope. */
286
+ export declare function getTaskByThread(threadId: string, scope?: AgentTeamOwnerScope): Promise<AgentTask | undefined>;
287
+ /** List tasks in the current owner/org scope (most recent first). */
288
+ export declare function listTasks(scope?: AgentTeamOwnerScope): Promise<AgentTask[]>;
289
+ export declare function listAgentTeamBackgroundRuns(scope?: AgentTeamOwnerScope): Promise<AgentTeamBackgroundRun[]>;
290
+ export declare function getAgentTeamBackgroundRun(runId: string, scope?: AgentTeamOwnerScope): Promise<AgentTeamBackgroundRun | null>;
291
+ export declare function listAgentTeamBackgroundTranscriptEvents(runId: string, scope?: AgentTeamOwnerScope): Promise<AgentTeamBackgroundTranscriptEvent[]>;
284
292
  export declare function subscribeToAgentTeamBackgroundRun(runId: string, fromSeq?: number): ReadableStream<Uint8Array> | null;
285
293
  /** Send a message/update to a running sub-agent via application state */
286
- export declare function sendToTask(taskId: string, message: string): Promise<{
294
+ export declare function sendToTask(taskId: string, message: string, scope?: AgentTeamOwnerScope): Promise<{
287
295
  ok: boolean;
288
296
  error?: string;
289
297
  messageId?: string;
290
298
  queuedCount?: number;
291
299
  }>;
292
- export declare function sendToAgentTeamBackgroundRun(runId: string, message: string): Promise<SendToAgentTeamBackgroundRunResult>;
293
- export declare function stopAgentTeamBackgroundRun(runId: string, reason?: string): Promise<ControlAgentTeamBackgroundRunResult>;
300
+ export declare function sendToAgentTeamBackgroundRun(runId: string, message: string, scope?: AgentTeamOwnerScope): Promise<SendToAgentTeamBackgroundRunResult>;
301
+ export declare function stopAgentTeamBackgroundRun(runId: string, reason?: string, scope?: AgentTeamOwnerScope): Promise<ControlAgentTeamBackgroundRunResult>;
294
302
  /** Mark a task as errored */
295
303
  export declare function markTaskErrored(taskId: string, error: string): Promise<void>;
296
304
  export declare const _agentTeamsQueueForTests: {
@@ -936,10 +936,24 @@ export async function spawnTask(opts) {
936
936
  }
937
937
  const runId = taskRunId(taskId);
938
938
  const createdAt = Date.now();
939
+ let orgId;
940
+ if (hasRequestContext()) {
941
+ orgId = getRequestOrgId() ?? null;
942
+ }
943
+ else {
944
+ try {
945
+ orgId = await resolveOrgIdForEmail(opts.ownerEmail);
946
+ }
947
+ catch {
948
+ orgId = null;
949
+ }
950
+ }
939
951
  const task = {
940
952
  taskId,
941
953
  threadId: thread.id,
942
954
  ...(opts.parentThreadId ? { parentThreadId: opts.parentThreadId } : {}),
955
+ ownerEmail: opts.ownerEmail,
956
+ orgId,
943
957
  ...(opts.name ? { name: opts.name } : {}),
944
958
  description: opts.description,
945
959
  status: "running",
@@ -972,18 +986,6 @@ export async function spawnTask(opts) {
972
986
  // (integrations/webhook-handler.ts). Execution happens in `processAgentTeamRun`,
973
987
  // invoked by the `/_agent-native/agent-teams/_process-run` route mounted
974
988
  // inside the agent-chat plugin (where the action/prompt/engine closures live).
975
- let orgId;
976
- if (hasRequestContext()) {
977
- orgId = getRequestOrgId() ?? null;
978
- }
979
- else {
980
- try {
981
- orgId = await resolveOrgIdForEmail(opts.ownerEmail);
982
- }
983
- catch {
984
- orgId = null;
985
- }
986
- }
987
989
  const payload = {
988
990
  description: opts.description,
989
991
  instructions: opts.instructions,
@@ -1505,35 +1507,45 @@ export async function processAgentTeamRun(opts) {
1505
1507
  return { ok: true };
1506
1508
  });
1507
1509
  }
1508
- /** Get task by ID */
1509
- export async function getTask(taskId) {
1510
+ /** Get task by ID, optionally constrained to the current request scope. */
1511
+ export async function getTask(taskId, scope) {
1510
1512
  const task = await loadTask(taskId);
1511
- return task ? await reconcileTaskWithRun(task) : undefined;
1513
+ if (!task || !taskMatchesOwnerScope(task, resolveOwnerScope(scope))) {
1514
+ return undefined;
1515
+ }
1516
+ return await reconcileTaskWithRun(task);
1512
1517
  }
1513
- /** Get task by thread ID */
1514
- export async function getTaskByThread(threadId) {
1518
+ /** Get task by thread ID, optionally constrained to the current request scope. */
1519
+ export async function getTaskByThread(threadId, scope) {
1515
1520
  const task = await loadTaskByThread(threadId);
1516
- return task ? await reconcileTaskWithRun(task) : undefined;
1521
+ if (!task || !taskMatchesOwnerScope(task, resolveOwnerScope(scope))) {
1522
+ return undefined;
1523
+ }
1524
+ return await reconcileTaskWithRun(task);
1517
1525
  }
1518
- /** List all tasks (most recent first) */
1519
- export async function listTasks() {
1526
+ /** List tasks in the current owner/org scope (most recent first). */
1527
+ export async function listTasks(scope) {
1528
+ const ownerScope = resolveOwnerScope(scope);
1520
1529
  const entries = await listAppState(TASK_PREFIX);
1521
- const tasks = entries.map((e) => e.value);
1530
+ const tasks = entries
1531
+ .map((e) => e.value)
1532
+ .filter((task) => taskMatchesOwnerScope(task, ownerScope));
1522
1533
  const reconciled = await Promise.all(tasks.map(reconcileTaskWithRun));
1523
1534
  return reconciled.sort((a, b) => (b.updatedAt ?? b.completedAt ?? b.createdAt) -
1524
1535
  (a.updatedAt ?? a.completedAt ?? a.createdAt));
1525
1536
  }
1526
- export async function listAgentTeamBackgroundRuns() {
1527
- return (await listTasks()).map(toAgentTaskBackgroundRun);
1537
+ export async function listAgentTeamBackgroundRuns(scope) {
1538
+ return (await listTasks(scope)).map(toAgentTaskBackgroundRun);
1528
1539
  }
1529
- export async function getAgentTeamBackgroundRun(runId) {
1530
- const task = await loadTask(taskIdFromBackgroundRunId(runId));
1531
- return task
1532
- ? toAgentTaskBackgroundRun(await reconcileTaskWithRun(task))
1533
- : null;
1540
+ export async function getAgentTeamBackgroundRun(runId, scope) {
1541
+ const task = await getTask(taskIdFromBackgroundRunId(runId), scope);
1542
+ return task ? toAgentTaskBackgroundRun(task) : null;
1534
1543
  }
1535
- export async function listAgentTeamBackgroundTranscriptEvents(runId) {
1544
+ export async function listAgentTeamBackgroundTranscriptEvents(runId, scope) {
1536
1545
  const taskId = taskIdFromBackgroundRunId(runId);
1546
+ const ownerScope = resolveOwnerScope(scope);
1547
+ if (ownerScope && !(await getTask(taskId, ownerScope)))
1548
+ return [];
1537
1549
  const normalizedRunId = taskRunId(taskId);
1538
1550
  const runIds = await transcriptRunIdsForTask(taskId);
1539
1551
  const output = [];
@@ -1589,10 +1601,11 @@ async function getPersistedRunEvents(runId) {
1589
1601
  .filter((event) => Boolean(event));
1590
1602
  }
1591
1603
  /** Send a message/update to a running sub-agent via application state */
1592
- export async function sendToTask(taskId, message) {
1604
+ export async function sendToTask(taskId, message, scope) {
1593
1605
  const task = await loadTask(taskId);
1594
- if (!task)
1606
+ if (!task || !taskMatchesOwnerScope(task, resolveOwnerScope(scope))) {
1595
1607
  return { ok: false, error: "Task not found" };
1608
+ }
1596
1609
  if (task.status !== "running")
1597
1610
  return { ok: false, error: "Task is not running" };
1598
1611
  if (message.trim().length === 0)
@@ -1612,8 +1625,8 @@ export async function sendToTask(taskId, message) {
1612
1625
  return { ok: false, error: "Unable to queue message" };
1613
1626
  }
1614
1627
  }
1615
- export async function sendToAgentTeamBackgroundRun(runId, message) {
1616
- return sendToTask(taskIdFromBackgroundRunId(runId), message);
1628
+ export async function sendToAgentTeamBackgroundRun(runId, message, scope) {
1629
+ return sendToTask(taskIdFromBackgroundRunId(runId), message, scope);
1617
1630
  }
1618
1631
  async function sendAgentTeamBackgroundAgentFollowUp(input) {
1619
1632
  const prompt = input.prompt.trim();
@@ -1655,11 +1668,12 @@ async function controlAgentTeamBackgroundAgentRun(input) {
1655
1668
  error: result.error,
1656
1669
  };
1657
1670
  }
1658
- export async function stopAgentTeamBackgroundRun(runId, reason = "user") {
1671
+ export async function stopAgentTeamBackgroundRun(runId, reason = "user", scope) {
1659
1672
  const taskId = taskIdFromBackgroundRunId(runId);
1660
1673
  const task = await loadTask(taskId);
1661
- if (!task)
1674
+ if (!task || !taskMatchesOwnerScope(task, resolveOwnerScope(scope))) {
1662
1675
  return { ok: false, error: "Task not found" };
1676
+ }
1663
1677
  if (task.status !== "running") {
1664
1678
  return { ok: false, error: "Task is not running" };
1665
1679
  }
@@ -1678,6 +1692,26 @@ export async function stopAgentTeamBackgroundRun(runId, reason = "user") {
1678
1692
  await completeAgentTeamRun(task.taskId, "failed");
1679
1693
  return { ok: true };
1680
1694
  }
1695
+ function resolveOwnerScope(scope) {
1696
+ if (scope)
1697
+ return scope;
1698
+ const ownerEmail = getRequestUserEmail();
1699
+ if (ownerEmail === undefined)
1700
+ return undefined;
1701
+ return {
1702
+ ownerEmail,
1703
+ // A few non-HTTP test/CLI hosts only provide the user scope. Keep that
1704
+ // owner check active without requiring every lightweight request-context
1705
+ // adapter to implement organization lookup.
1706
+ orgId: typeof getRequestOrgId === "function" ? getRequestOrgId() : undefined,
1707
+ };
1708
+ }
1709
+ function taskMatchesOwnerScope(task, scope) {
1710
+ if (!scope)
1711
+ return true;
1712
+ return ((task.ownerEmail ?? null) === scope.ownerEmail &&
1713
+ (scope.orgId === undefined || (task.orgId ?? null) === scope.orgId));
1714
+ }
1681
1715
  /** Mark a task as errored */
1682
1716
  export async function markTaskErrored(taskId, error) {
1683
1717
  const task = await loadTask(taskId);
@@ -0,0 +1,17 @@
1
+ import { type HostedHarnessRuntime } from "../agent/harness/hosted.js";
2
+ import type { AgentNativeHarnessSetting } from "../config.js";
3
+ export interface HostedHarnessPolicy {
4
+ enabled: boolean;
5
+ configEnabled: boolean;
6
+ envEnabled: boolean;
7
+ organizationEnabled: boolean;
8
+ runtimes: HostedHarnessRuntime[];
9
+ }
10
+ export declare function isHostedHarnessEnvEnabled(env?: Record<string, string | undefined>): boolean;
11
+ export declare function loadHostedHarnessConfig(cwd?: string): Promise<AgentNativeHarnessSetting | undefined>;
12
+ export declare function resolveHostedHarnessPolicy(options: {
13
+ config?: AgentNativeHarnessSetting;
14
+ orgId?: string | null;
15
+ userEmail?: string | null;
16
+ }): Promise<HostedHarnessPolicy>;
17
+ export declare function hostedHarnessStatusForClient(policy: HostedHarnessPolicy): HostedHarnessPolicy;
@@ -0,0 +1,38 @@
1
+ import { HOSTED_HARNESS_ENV_KEY, HOSTED_HARNESS_ORG_SETTING_KEY, isHostedHarnessConfigured, normalizeHostedHarnessRuntimes, } from "../agent/harness/hosted.js";
2
+ import { getOrgSetting } from "../settings/org-settings.js";
3
+ import { createAgentNativeConfigContext, loadResolvedAgentNativeConfig, } from "../vite/agent-native-config-loader.js";
4
+ export function isHostedHarnessEnvEnabled(env = process.env) {
5
+ const value = env[HOSTED_HARNESS_ENV_KEY]?.trim().toLowerCase();
6
+ return value === "1" || value === "true" || value === "yes" || value === "on";
7
+ }
8
+ export async function loadHostedHarnessConfig(cwd = process.cwd()) {
9
+ const production = process.env.NODE_ENV === "production";
10
+ const config = await loadResolvedAgentNativeConfig(cwd, createAgentNativeConfigContext(production ? "build" : "serve", production ? "production" : "development"));
11
+ return config.harness;
12
+ }
13
+ export async function resolveHostedHarnessPolicy(options) {
14
+ const config = options.config ?? (await loadHostedHarnessConfig());
15
+ const organizationSetting = options.orgId
16
+ ? await getOrgSetting(options.orgId, HOSTED_HARNESS_ORG_SETTING_KEY)
17
+ : null;
18
+ const envEnabled = isHostedHarnessEnvEnabled();
19
+ // The deployment flag is the fleet-level default. An org setting is only
20
+ // needed when a deployment has not enabled the hosted harness globally.
21
+ const organizationEnabled = envEnabled || organizationSetting?.enabled === true;
22
+ const configEnabled = isHostedHarnessConfigured(config);
23
+ return {
24
+ enabled: configEnabled && (envEnabled || organizationEnabled),
25
+ configEnabled,
26
+ envEnabled,
27
+ organizationEnabled,
28
+ runtimes: normalizeHostedHarnessRuntimes(typeof config === "object" && config !== null
29
+ ? config.runtimes
30
+ : undefined),
31
+ };
32
+ }
33
+ export function hostedHarnessStatusForClient(policy) {
34
+ return {
35
+ ...policy,
36
+ runtimes: [...policy.runtimes],
37
+ };
38
+ }
@@ -26,8 +26,8 @@ export declare function createRealtimeTokenHandler(): import("h3").EventHandlerW
26
26
  expiresAt?: undefined;
27
27
  ttlSeconds?: undefined;
28
28
  } | {
29
- error?: undefined;
30
29
  token: string;
31
30
  expiresAt: string;
32
31
  ttlSeconds: number;
32
+ error?: undefined;
33
33
  }>>;
@@ -61,6 +61,8 @@ export interface RequestRunContext {
61
61
  model?: string;
62
62
  /** Request-authorized action names exposed to this agent run. */
63
63
  allowedActionNames?: readonly string[];
64
+ /** Hosted tools-only harness selected for this agent run. */
65
+ hostedHarnessRuntime?: "claude-code" | "codex" | "pi" | "opencode";
64
66
  /**
65
67
  * True when this run is executing inside the durable background-function
66
68
  * worker (the `_process-run` self-dispatch), not the synchronous foreground
@@ -82,6 +84,8 @@ export interface RequestRunContext {
82
84
  }>;
83
85
  /** Per-run fingerprints for large extension bodies already sent to the LLM. */
84
86
  extensionContentReads?: Record<string, string>;
87
+ /** Per-run keys for extension excerpt reads already sent to the LLM. */
88
+ extensionExcerptReads?: Record<string, true>;
85
89
  /** Per-run fingerprints for repeated tool-search calls already sent to the LLM. */
86
90
  toolSearchReads?: Record<string, {
87
91
  totalTools: number;
@@ -20,6 +20,6 @@ export declare function createTranscribeVoiceHandler(): import("h3").EventHandle
20
20
  error: string;
21
21
  text?: undefined;
22
22
  } | {
23
- error?: undefined;
24
23
  text: string;
24
+ error?: undefined;
25
25
  }>>;
@@ -230,6 +230,23 @@
230
230
  container: agent-native-main / inline-size;
231
231
  }
232
232
 
233
+ /* Dispatch and Electron own the chat drawer when an app is embedded. Keep
234
+ the standard app's navigation beside its content, on the opposite edge.
235
+ Custom shells opt out with data-agent-native-shell-variant="custom". */
236
+ @media (min-width: 768px) {
237
+ .agent-layout-shell:not([data-agent-native-shell-variant="custom"]):has(
238
+ > .agent-sidebar-shell[data-agent-native-hosted-chat="true"]
239
+ )
240
+ > .agent-layout-left-drawer,
241
+ .agent-sidebar-shell[data-agent-native-hosted-chat="true"]
242
+ .agent-layout-shell:not([data-agent-native-shell-variant="custom"])
243
+ > .agent-layout-left-drawer {
244
+ order: 2;
245
+ border-inline-end: 0 !important;
246
+ border-inline-start: 1px solid hsl(var(--sidebar-border)) !important;
247
+ }
248
+ }
249
+
233
250
  @media (min-width: 768px) {
234
251
  .agent-layout-shell
235
252
  :where(.agent-layout-main-surface, .agent-sidebar-main-surface)
@@ -727,6 +744,28 @@
727
744
  line-height: 1.4rem;
728
745
  }
729
746
 
747
+ /* Settings rows size themselves from the available content column. The full
748
+ Settings page can be narrow even on a desktop viewport when its navigation
749
+ rail and agent sidebar are both open, so viewport breakpoints are not a
750
+ reliable signal for keeping copy and controls side by side. */
751
+ .agent-native-settings-row {
752
+ container-type: inline-size;
753
+ container-name: settings-row;
754
+ }
755
+
756
+ @container settings-row (min-width: 36rem) {
757
+ .agent-native-settings-row__layout {
758
+ align-items: center;
759
+ flex-direction: row;
760
+ justify-content: space-between;
761
+ }
762
+
763
+ .agent-native-settings-row__control {
764
+ margin-inline-start: 1rem;
765
+ text-align: end;
766
+ }
767
+ }
768
+
730
769
  /* Composer toolbar: keep the model name + version readable on narrow
731
770
  chatfields. The bordered composer box is a size container; below 370px
732
771
  wide (e.g. a narrow agent sidebar) we drop the reasoning-level suffix
@@ -0,0 +1,5 @@
1
+ import { defineAgentNativeConfig } from "@agent-native/core/config";
2
+
3
+ export default defineAgentNativeConfig({
4
+ harness: true,
5
+ });
@@ -9,3 +9,6 @@ GA_MEASUREMENT_ID = "G-ESF7FYXGN9"
9
9
  GTM_CONTAINER_ID = "GTM-N3WSTXZ"
10
10
  NITRO_PRESET = "netlify"
11
11
  NPM_CONFIG_PRODUCTION = "false"
12
+
13
+ [context.production.environment]
14
+ AGENT_NATIVE_HOSTED_HARNESS = "true"
@@ -53,6 +53,14 @@ const CORE_SHARING_ACTIONS = [
53
53
  name: "set-feature-flag",
54
54
  specifier: "@agent-native/core/feature-flags/actions/set-feature-flag",
55
55
  },
56
+ {
57
+ name: "get-hosted-harness-config",
58
+ specifier: "@agent-native/core/hosted-harness/actions/get-hosted-harness-config",
59
+ },
60
+ {
61
+ name: "set-hosted-harness-enabled",
62
+ specifier: "@agent-native/core/hosted-harness/actions/set-hosted-harness-enabled",
63
+ },
56
64
  {
57
65
  name: "share-resource",
58
66
  specifier: "@agent-native/core/sharing/actions/share-resource",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.157.5",
3
+ "version": "0.157.7",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -185,6 +185,8 @@
185
185
  "./feature-flags/actions/get-feature-flags": "./dist/feature-flags/actions/get-feature-flags.js",
186
186
  "./feature-flags/actions/list-feature-flags": "./dist/feature-flags/actions/list-feature-flags.js",
187
187
  "./feature-flags/actions/set-feature-flag": "./dist/feature-flags/actions/set-feature-flag.js",
188
+ "./hosted-harness/actions/get-hosted-harness-config": "./dist/hosted-harness/actions/get-hosted-harness-config.js",
189
+ "./hosted-harness/actions/set-hosted-harness-enabled": "./dist/hosted-harness/actions/set-hosted-harness-enabled.js",
188
190
  "./localization": "./dist/localization/index.js",
189
191
  "./localization/actions/get-localization-preference": "./dist/localization/actions/get-localization-preference.js",
190
192
  "./localization/actions/set-localization-preference": "./dist/localization/actions/set-localization-preference.js",
@@ -424,7 +426,7 @@
424
426
  "yjs": "^13.6.31",
425
427
  "zod": "^4.3.6",
426
428
  "@agent-native/recap-cli": "0.5.4",
427
- "@agent-native/toolkit": "^0.16.0"
429
+ "@agent-native/toolkit": "^0.16.1"
428
430
  },
429
431
  "devDependencies": {
430
432
  "@ai-sdk/anthropic": "^3.0.71",
@@ -0,0 +1,5 @@
1
+ import { defineAgentNativeConfig } from "@agent-native/core/config";
2
+
3
+ export default defineAgentNativeConfig({
4
+ harness: true,
5
+ });
@@ -9,3 +9,6 @@ GA_MEASUREMENT_ID = "G-ESF7FYXGN9"
9
9
  GTM_CONTAINER_ID = "GTM-N3WSTXZ"
10
10
  NITRO_PRESET = "netlify"
11
11
  NPM_CONFIG_PRODUCTION = "false"
12
+
13
+ [context.production.environment]
14
+ AGENT_NATIVE_HOSTED_HARNESS = "true"