@agent-native/core 0.157.6 → 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 (96) 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/lib/meeting-content.ts +28 -0
  14. package/corpus/templates/clips/actions/list-meetings.ts +33 -11
  15. package/corpus/templates/clips/app/i18n/en-US.ts +1 -0
  16. package/corpus/templates/clips/app/lib/meeting-history-query.ts +11 -0
  17. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +47 -21
  18. package/corpus/templates/clips/netlify.toml +4 -0
  19. package/corpus/templates/content/netlify.toml +3 -0
  20. package/corpus/templates/design/app/i18n-data.ts +2 -0
  21. package/corpus/templates/design/netlify.toml +3 -0
  22. package/corpus/templates/dispatch/netlify.toml +3 -0
  23. package/corpus/templates/factory/netlify.toml +3 -0
  24. package/corpus/templates/forms/netlify.toml +3 -0
  25. package/corpus/templates/macros/netlify.toml +3 -0
  26. package/corpus/templates/mail/agent-native.config.ts +5 -0
  27. package/corpus/templates/mail/netlify.toml +3 -0
  28. package/corpus/templates/plan/netlify.toml +3 -0
  29. package/corpus/templates/slides/netlify.toml +3 -0
  30. package/dist/agent/harness/acp-adapter.js +17 -2
  31. package/dist/agent/harness/ai-sdk-adapter.js +14 -3
  32. package/dist/agent/harness/background.js +10 -5
  33. package/dist/agent/harness/hosted.d.ts +20 -0
  34. package/dist/agent/harness/hosted.js +100 -0
  35. package/dist/agent/harness/runner.js +100 -77
  36. package/dist/agent/observational-memory/observer.js +12 -0
  37. package/dist/agent/production-agent.d.ts +3 -0
  38. package/dist/agent/production-agent.js +74 -4
  39. package/dist/agent/thread-data-builder.d.ts +12 -0
  40. package/dist/agent/thread-data-builder.js +23 -0
  41. package/dist/agent/types.d.ts +6 -0
  42. package/dist/client/AgentPanel.d.ts +5 -1
  43. package/dist/client/AgentPanel.js +113 -17
  44. package/dist/client/AgentTaskCard.d.ts +2 -2
  45. package/dist/client/AgentTaskCard.js +8 -22
  46. package/dist/client/AssistantChat.d.ts +8 -0
  47. package/dist/client/AssistantChat.js +106 -59
  48. package/dist/client/MultiTabAssistantChat.js +50 -6
  49. package/dist/client/NewWorkspaceAppFlow.js +7 -1
  50. package/dist/client/agent-chat-adapter.d.ts +6 -0
  51. package/dist/client/agent-chat-adapter.js +36 -8
  52. package/dist/client/app-chat-sidebar.d.ts +5 -0
  53. package/dist/client/app-chat-sidebar.js +53 -9
  54. package/dist/client/chat/composer-draft.d.ts +4 -0
  55. package/dist/client/chat/composer-draft.js +63 -0
  56. package/dist/client/chat-first/apps-rail.js +10 -1
  57. package/dist/client/chat-first/primary-nav.js +10 -5
  58. package/dist/client/frame-protocol.d.ts +1 -0
  59. package/dist/client/hooks/index.d.ts +1 -1
  60. package/dist/client/hooks/index.js +1 -1
  61. package/dist/client/i18n.js +5 -2
  62. package/dist/client/progress/RunsTray.js +129 -16
  63. package/dist/client/settings/SettingsRow.js +1 -1
  64. package/dist/client/use-chat-threads.js +11 -6
  65. package/dist/config.d.ts +11 -0
  66. package/dist/config.js +52 -0
  67. package/dist/extensions/actions.js +22 -1
  68. package/dist/hosted-harness/actions/get-hosted-harness-config.d.ts +2 -0
  69. package/dist/hosted-harness/actions/get-hosted-harness-config.js +13 -0
  70. package/dist/hosted-harness/actions/set-hosted-harness-enabled.d.ts +4 -0
  71. package/dist/hosted-harness/actions/set-hosted-harness-enabled.js +32 -0
  72. package/dist/localization/default-messages.d.ts +4 -1
  73. package/dist/localization/default-messages.js +5 -2
  74. package/dist/notifications/routes.d.ts +1 -1
  75. package/dist/observability/routes.d.ts +5 -5
  76. package/dist/provider-api/actions/custom-provider-registration.d.ts +6 -6
  77. package/dist/provider-api/actions/provider-api.d.ts +4 -4
  78. package/dist/resources/handlers.d.ts +1 -1
  79. package/dist/secrets/routes.d.ts +9 -9
  80. package/dist/server/action-discovery.js +12 -0
  81. package/dist/server/agent-chat-plugin.js +24 -4
  82. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  83. package/dist/server/agent-teams.d.ts +20 -12
  84. package/dist/server/agent-teams.js +69 -35
  85. package/dist/server/hosted-harness-policy.d.ts +17 -0
  86. package/dist/server/hosted-harness-policy.js +38 -0
  87. package/dist/server/realtime-token.d.ts +1 -1
  88. package/dist/server/request-context.d.ts +4 -0
  89. package/dist/server/transcribe-voice.d.ts +1 -1
  90. package/dist/styles/agent-native.css +39 -0
  91. package/dist/templates/chat/agent-native.config.ts +5 -0
  92. package/dist/templates/chat/netlify.toml +3 -0
  93. package/dist/vite/action-types-plugin.js +8 -0
  94. package/package.json +5 -3
  95. package/src/templates/chat/agent-native.config.ts +5 -0
  96. package/src/templates/chat/netlify.toml +3 -0
@@ -1242,6 +1242,27 @@ async function summarizeExtensionForAgentRead(row, hiddenIds, includeContent, fo
1242
1242
  const fingerprint = contentFingerprint(row.content);
1243
1243
  if (contentQuery) {
1244
1244
  const summary = await summarizeExtension(row, hiddenIds, false);
1245
+ // The whole-body read below is deduped per run, but this branch returned
1246
+ // above it, so a repeated excerpt request re-sent bytes already in context.
1247
+ // One production turn spent 48 of 110 reads re-fetching the same spans.
1248
+ const excerptCtx = getRequestRunContext();
1249
+ const excerpts = excerptCtx
1250
+ ? (excerptCtx.extensionExcerptReads ??= {})
1251
+ : undefined;
1252
+ const excerptKey = `${row.id}:${fingerprint}:${contentContextChars}:${contentQuery}`;
1253
+ if (excerpts?.[excerptKey]) {
1254
+ return {
1255
+ ...summary,
1256
+ contentOmitted: {
1257
+ reason: "identical-excerpt-already-returned-this-run",
1258
+ contentHash: fingerprint,
1259
+ contentLength: row.content.length,
1260
+ next: 'These exact excerpts were already returned earlier in this run and the body has not changed. Use them to call update-extension with operation="edit"; use a different contentQuery only for a source area you have not read yet.',
1261
+ },
1262
+ };
1263
+ }
1264
+ if (excerpts)
1265
+ excerpts[excerptKey] = true;
1245
1266
  return {
1246
1267
  ...summary,
1247
1268
  contentMatches: findExtensionContentMatches(row.content, contentQuery, contentContextChars),
@@ -1266,7 +1287,7 @@ async function summarizeExtensionForAgentRead(row, hiddenIds, includeContent, fo
1266
1287
  contentHash: fingerprint,
1267
1288
  contentLength: row.content.length,
1268
1289
  inlineContentLimit: LARGE_EXTENSION_INLINE_CONTENT_MAX_CHARS,
1269
- next: "Call get-extension again with contentQuery set to the relevant function, variable, section marker, or literal text. Use forceContent=true only for a broad rewrite that truly needs the entire body.",
1290
+ next: `Call get-extension again with contentQuery set to the relevant function, variable, section marker, or literal text. If you expect to read more than about three separate areas of this ${row.content.length}-char body, call get-extension once with forceContent=true instead — repeated excerpt reads of the same file cost more context than one whole read.`,
1270
1291
  },
1271
1292
  };
1272
1293
  }
@@ -0,0 +1,2 @@
1
+ declare const _default: import("../../action.js").ActionDefinition<Record<string, never>, import("../../server/hosted-harness-policy.js").HostedHarnessPolicy>;
2
+ export default _default;
@@ -0,0 +1,13 @@
1
+ import { z } from "zod";
2
+ import { defineAction } from "../../action.js";
3
+ import { hostedHarnessStatusForClient, resolveHostedHarnessPolicy, } from "../../server/hosted-harness-policy.js";
4
+ export default defineAction({
5
+ description: "Return whether this app's hosted tools-only harness is enabled for the current organization and which runtimes are available.",
6
+ schema: z.object({}),
7
+ http: { method: "GET" },
8
+ agentTool: false,
9
+ run: async (_args, context) => hostedHarnessStatusForClient(await resolveHostedHarnessPolicy({
10
+ orgId: context?.orgId,
11
+ userEmail: context?.userEmail,
12
+ })),
13
+ });
@@ -0,0 +1,4 @@
1
+ declare const _default: import("../../action.js").ActionDefinition<{
2
+ enabled: boolean;
3
+ }, import("../../server/hosted-harness-policy.js").HostedHarnessPolicy>;
4
+ export default _default;
@@ -0,0 +1,32 @@
1
+ import { z } from "zod";
2
+ import { defineAction } from "../../action.js";
3
+ import { HOSTED_HARNESS_ORG_SETTING_KEY } from "../../agent/harness/hosted.js";
4
+ import { getOrgRoleForEmail } from "../../mcp/actions/service-token-access.js";
5
+ import { canManageOrg } from "../../org/permissions.js";
6
+ import { hostedHarnessStatusForClient, resolveHostedHarnessPolicy, } from "../../server/hosted-harness-policy.js";
7
+ import { putOrgSetting } from "../../settings/org-settings.js";
8
+ export default defineAction({
9
+ description: "Enable or disable the hosted tools-only harness for the current organization. Organization owners and admins only.",
10
+ schema: z.object({ enabled: z.boolean() }),
11
+ http: { method: "POST" },
12
+ agentTool: false,
13
+ run: async (args, context) => {
14
+ const email = context?.userEmail?.trim().toLowerCase();
15
+ const orgId = context?.orgId?.trim();
16
+ if (!email)
17
+ throw new Error("Sign in to manage hosted harnesses.");
18
+ if (!orgId)
19
+ throw new Error("Select an organization to manage harnesses.");
20
+ const role = await getOrgRoleForEmail(orgId, email);
21
+ if (!canManageOrg(role)) {
22
+ throw new Error("Only organization owners and admins can manage hosted harnesses.");
23
+ }
24
+ await putOrgSetting(orgId, HOSTED_HARNESS_ORG_SETTING_KEY, {
25
+ enabled: args.enabled,
26
+ });
27
+ return hostedHarnessStatusForClient(await resolveHostedHarnessPolicy({
28
+ orgId,
29
+ userEmail: email,
30
+ }));
31
+ },
32
+ });
@@ -733,6 +733,9 @@ declare const messages: {
733
733
  statusDone: string;
734
734
  statusFailed: string;
735
735
  statusStopped: string;
736
+ statusNeedsApproval: string;
737
+ statusNeedsInput: string;
738
+ statusPaused: string;
736
739
  updatedJustNow: string;
737
740
  finishedJustNow: string;
738
741
  updatedMinutes: string;
@@ -743,7 +746,7 @@ declare const messages: {
743
746
  finishedDate: string;
744
747
  };
745
748
  agentTask: {
746
- backgroundTask: string;
749
+ spawnedAgent: string;
747
750
  stop: string;
748
751
  openThread: string;
749
752
  };
@@ -739,6 +739,9 @@ const messages = {
739
739
  statusDone: "Done",
740
740
  statusFailed: "Failed",
741
741
  statusStopped: "Stopped",
742
+ statusNeedsApproval: "Needs approval",
743
+ statusNeedsInput: "Needs input",
744
+ statusPaused: "Paused",
742
745
  updatedJustNow: "Updated just now",
743
746
  finishedJustNow: "Finished just now",
744
747
  updatedMinutes: "Updated {{count}}m ago",
@@ -749,8 +752,8 @@ const messages = {
749
752
  finishedDate: "Finished {{date}}",
750
753
  },
751
754
  agentTask: {
752
- backgroundTask: "Background task",
753
- stop: "Stop background task",
755
+ spawnedAgent: "Spawned agent",
756
+ stop: "Stop spawned agent",
754
757
  openThread: "Open task thread",
755
758
  },
756
759
  codeRequired: {
@@ -28,6 +28,6 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
28
28
  } | {
29
29
  count?: undefined;
30
30
  updated?: undefined;
31
- ok: boolean;
32
31
  error?: undefined;
32
+ ok: boolean;
33
33
  }>>;
@@ -41,27 +41,27 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
41
41
  thumbsUpRate: number;
42
42
  avgEvalScore: number;
43
43
  } | {
44
+ error?: undefined;
45
+ ok?: undefined;
44
46
  summary: import("./types.js").TraceSummary;
45
47
  spans: import("./types.js").TraceSpan[];
46
48
  id?: undefined;
49
+ } | {
47
50
  error?: undefined;
48
51
  ok?: undefined;
49
- } | {
50
52
  summary?: undefined;
51
53
  spans?: undefined;
52
54
  id: string;
53
- error?: undefined;
54
- ok?: undefined;
55
55
  } | {
56
+ ok?: undefined;
56
57
  summary?: undefined;
57
58
  spans?: undefined;
58
59
  id?: undefined;
59
60
  error: any;
60
- ok?: undefined;
61
61
  } | {
62
+ error?: undefined;
62
63
  summary?: undefined;
63
64
  spans?: undefined;
64
65
  id?: undefined;
65
- error?: undefined;
66
66
  ok: boolean;
67
67
  }>>;
@@ -75,8 +75,9 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
75
75
  user: "user";
76
76
  }>>;
77
77
  }, z.core.$strip>>, {
78
- id?: undefined;
79
78
  message?: undefined;
79
+ id?: undefined;
80
+ provider?: undefined;
80
81
  deleted?: undefined;
81
82
  providers: {
82
83
  id: string;
@@ -88,14 +89,13 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
88
89
  updatedAt: number;
89
90
  }[];
90
91
  count: number;
91
- provider?: undefined;
92
92
  found?: undefined;
93
93
  registered?: undefined;
94
94
  label?: undefined;
95
95
  } | {
96
- id?: undefined;
97
96
  message?: undefined;
98
97
  count?: undefined;
98
+ id?: undefined;
99
99
  deleted?: undefined;
100
100
  providers?: undefined;
101
101
  found: boolean;
@@ -105,9 +105,9 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
105
105
  } | {
106
106
  message?: undefined;
107
107
  count?: undefined;
108
+ provider?: undefined;
108
109
  deleted?: undefined;
109
110
  providers?: undefined;
110
- provider?: undefined;
111
111
  found: boolean;
112
112
  id: string;
113
113
  registered?: undefined;
@@ -115,8 +115,8 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
115
115
  } | {
116
116
  message?: undefined;
117
117
  count?: undefined;
118
- providers?: undefined;
119
118
  provider?: undefined;
119
+ providers?: undefined;
120
120
  found?: undefined;
121
121
  deleted: boolean;
122
122
  id: string;
@@ -124,9 +124,9 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
124
124
  label?: undefined;
125
125
  } | {
126
126
  count?: undefined;
127
+ provider?: undefined;
127
128
  deleted?: undefined;
128
129
  providers?: undefined;
129
- provider?: undefined;
130
130
  found?: undefined;
131
131
  registered: boolean;
132
132
  id: string;
@@ -313,7 +313,6 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
313
313
  }, {
314
314
  deleted?: undefined;
315
315
  id?: undefined;
316
- provider?: undefined;
317
316
  providers: {
318
317
  id: string;
319
318
  label: string;
@@ -324,6 +323,7 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
324
323
  updatedAt: number;
325
324
  }[];
326
325
  count: number;
326
+ provider?: undefined;
327
327
  found?: undefined;
328
328
  registered?: undefined;
329
329
  label?: undefined;
@@ -340,18 +340,18 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
340
340
  message?: undefined;
341
341
  } | {
342
342
  deleted?: undefined;
343
- provider?: undefined;
344
343
  providers?: undefined;
345
344
  count?: undefined;
345
+ provider?: undefined;
346
346
  found: boolean;
347
347
  id: string;
348
348
  registered?: undefined;
349
349
  label?: undefined;
350
350
  message?: undefined;
351
351
  } | {
352
- provider?: undefined;
353
352
  providers?: undefined;
354
353
  count?: undefined;
354
+ provider?: undefined;
355
355
  found?: undefined;
356
356
  deleted: boolean;
357
357
  id: string;
@@ -360,9 +360,9 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
360
360
  message?: undefined;
361
361
  } | {
362
362
  deleted?: undefined;
363
- provider?: undefined;
364
363
  providers?: undefined;
365
364
  count?: undefined;
365
+ provider?: undefined;
366
366
  found?: undefined;
367
367
  registered: boolean;
368
368
  id: string;
@@ -48,8 +48,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
48
48
  }>;
49
49
  /** DELETE /_agent-native/resources/:id — delete a resource */
50
50
  export declare function handleDeleteResource(event: any): Promise<{
51
- ok?: undefined;
52
51
  error: string;
52
+ ok?: undefined;
53
53
  } | {
54
54
  error?: undefined;
55
55
  ok: boolean;
@@ -34,37 +34,37 @@ export declare function createListSecretsHandler(): import("h3").EventHandlerWit
34
34
  /** POST /_agent-native/secrets/:key — write a secret. */
35
35
  export declare function createWriteSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
36
36
  error: string;
37
- status?: undefined;
38
37
  ok?: undefined;
38
+ status?: undefined;
39
39
  } | {
40
+ error?: undefined;
40
41
  ok: boolean;
41
42
  status: string;
42
- error?: undefined;
43
43
  } | {
44
+ ok?: undefined;
44
45
  error: string;
45
46
  removed?: undefined;
46
- ok?: undefined;
47
47
  } | {
48
+ error?: undefined;
48
49
  ok: boolean;
49
50
  removed: boolean;
50
- error?: undefined;
51
51
  }>>;
52
52
  /**
53
53
  * POST /_agent-native/secrets/:key/test — validate an optional candidate value
54
54
  * or the current stored value without changing anything.
55
55
  */
56
56
  export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
57
+ ok?: undefined;
57
58
  error: string;
58
59
  note?: undefined;
59
- ok?: undefined;
60
60
  } | {
61
+ error?: undefined;
61
62
  ok: boolean;
62
63
  note?: undefined;
63
- error?: undefined;
64
64
  } | {
65
+ error?: undefined;
65
66
  ok: boolean;
66
67
  note: string;
67
- error?: undefined;
68
68
  } | {
69
69
  note?: undefined;
70
70
  ok: boolean;
@@ -95,11 +95,11 @@ export interface AdHocSecretPayload {
95
95
  export declare function createAdHocSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<AdHocSecretPayload[] | {
96
96
  error: string;
97
97
  } | {
98
+ error?: undefined;
98
99
  ok: boolean;
99
100
  key: string;
100
- error?: undefined;
101
101
  } | {
102
+ error?: undefined;
102
103
  ok: boolean;
103
104
  removed: boolean;
104
- error?: undefined;
105
105
  }>>;
@@ -529,6 +529,10 @@ export const ALWAYS_ON_CORE_ACTIONS = new Set([
529
529
  "revoke-org-service-token",
530
530
  "list-mcp-tools",
531
531
  "call-mcp-tool",
532
+ // Hosted harness capability/policy routes are UI-facing and deliberately
533
+ // never enter the model's action surface (`agentTool: false`).
534
+ "get-hosted-harness-config",
535
+ "set-hosted-harness-enabled",
532
536
  ]);
533
537
  export async function mergeCoreSharingActions(registry) {
534
538
  const entries = [
@@ -592,6 +596,14 @@ export async function mergeCoreSharingActions(registry) {
592
596
  "get-feature-flags",
593
597
  () => import("../feature-flags/actions/get-feature-flags.js"),
594
598
  ],
599
+ [
600
+ "get-hosted-harness-config",
601
+ () => import("../hosted-harness/actions/get-hosted-harness-config.js"),
602
+ ],
603
+ [
604
+ "set-hosted-harness-enabled",
605
+ () => import("../hosted-harness/actions/set-hosted-harness-enabled.js"),
606
+ ],
595
607
  [
596
608
  "list-feature-flags",
597
609
  () => import("../feature-flags/actions/list-feature-flags.js"),
@@ -12,6 +12,7 @@ import { AGENT_CHAT_BACKGROUND_RUN_FIELD, AGENT_CHAT_PROCESS_RUN_PATH, backgroun
12
12
  import { resolveEngine, createAnthropicEngine, getStoredModelForEngine, normalizeModelForEngine, resolveDelegatedRunModel, getAgentEngineEntry, isAgentEnginePackageInstalled, isStoredEngineUsableForRequest, listAgentEngines, registerBuiltinEngines, } from "../agent/engine/index.js";
13
13
  import { SYSTEM_PROMPT_CACHE_SPLIT } from "../agent/engine/prompt-cache.js";
14
14
  import { PROVIDER_TO_ENV } from "../agent/engine/provider-env-vars.js";
15
+ import { hostedHarnessSystemPrompt } from "../agent/harness/hosted.js";
15
16
  import { createProductionAgentHandler, actionsToEngineTools, executeAgentToolCall, filterActionsByAllowedNames, readPersistedActionSurface, toolCallCacheKey, getActiveRunForThreadAsync, abortRunDurably, abortTurnDurably, subscribeToRun, } from "../agent/production-agent.js";
16
17
  import { callerHasRunAccess, callerHasThreadAccess, } from "../agent/run-ownership.js";
17
18
  import { markTurnAborted, readBackgroundRunClaim } from "../agent/run-store.js";
@@ -44,6 +45,7 @@ import { captureError } from "./capture-error.js";
44
45
  import { getH3App, markDefaultPluginProvided, trackPluginInit, } from "./framework-request-handler.js";
45
46
  import { getOrigin } from "./google-oauth.js";
46
47
  import { readBody } from "./h3-helpers.js";
48
+ import { loadHostedHarnessConfig } from "./hosted-harness-policy.js";
47
49
  import { startIntervalJob } from "./interval-job.js";
48
50
  import { getModelFamilyOverlay } from "./prompts/index.js";
49
51
  import { mountRealtimeVoiceRoutes } from "./realtime-voice.js";
@@ -309,6 +311,7 @@ export function createAgentChatPlugin(options) {
309
311
  // `/runs/active` reaps the requested run on demand, and the periodic
310
312
  // recovery sweep below handles abandoned runs with no connected client.
311
313
  const env = process.env.NODE_ENV;
314
+ const hostedHarnessConfig = await loadHostedHarnessConfig();
312
315
  // AGENT_MODE=production forces production agent constraints even in dev
313
316
  const canToggle = (env === "development" || env === "test") &&
314
317
  process.env.AGENT_MODE !== "production";
@@ -2694,6 +2697,13 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
2694
2697
  const codeEditingSurfaceRestriction = shouldBlockInProductCodeEditing(event)
2695
2698
  ? APP_RENDERED_CHAT_NO_DIRECT_CODE_PROMPT
2696
2699
  : "";
2700
+ const hostedHarnessRuntime = getRequestRunContext()?.hostedHarnessRuntime;
2701
+ const hostedHarnessPromptNote = hostedHarnessRuntime
2702
+ ? hostedHarnessSystemPrompt(hostedHarnessRuntime)
2703
+ : "";
2704
+ const requestProdCodeExecPromptNote = hostedHarnessRuntime
2705
+ ? ""
2706
+ : prodCodeExecPromptNote;
2697
2707
  // Per-model overlay: nudge GPT/Gemini engines toward our behavioral norms.
2698
2708
  const modelOverlay = resolveModelOverlay();
2699
2709
  // Stable-first ordering: base prompt / schema / extra come before
@@ -2705,7 +2715,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
2705
2715
  // `SYSTEM_PROMPT_CACHE_SPLIT` marks where the cacheable prefix ends,
2706
2716
  // so everything after it can change without a cache write.
2707
2717
  if (leanPrompt) {
2708
- const leanRunPolicyPrompt = buildLeanRunPolicyPrompt(codeEditingSurfaceRestriction, prodCodeExecPromptNote);
2718
+ const leanRunPolicyPrompt = buildLeanRunPolicyPrompt(codeEditingSurfaceRestriction, `${requestProdCodeExecPromptNote}${hostedHarnessPromptNote ? `\n\n${hostedHarnessPromptNote}` : ""}`);
2709
2719
  const resources = await loadResourcesForPrompt(owner, true, options?.appId, undefined, { disabledFrameworkGroups });
2710
2720
  await emitContextXraySystemSections(event, {
2711
2721
  frameworkPrompt: requestLeanPrompt.slice(0, Math.max(0, requestLeanPrompt.length - requestLeanActionsPrompt.length)),
@@ -2740,20 +2750,26 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
2740
2750
  extra,
2741
2751
  modelOverlay,
2742
2752
  runtimeContext,
2743
- additionalFramework: codeEditingSurfaceRestriction + prodCodeExecPromptNote,
2753
+ additionalFramework: codeEditingSurfaceRestriction +
2754
+ requestProdCodeExecPromptNote +
2755
+ (hostedHarnessPromptNote ? `\n\n${hostedHarnessPromptNote}` : ""),
2744
2756
  });
2745
2757
  return setSystemPromptOnContext(requestBasePrompt +
2746
2758
  SYSTEM_PROMPT_CACHE_SPLIT +
2747
2759
  resources +
2748
2760
  schemaBlock +
2749
2761
  codeEditingSurfaceRestriction +
2750
- prodCodeExecPromptNote +
2762
+ requestProdCodeExecPromptNote +
2763
+ (hostedHarnessPromptNote
2764
+ ? `\n\n${hostedHarnessPromptNote}`
2765
+ : "") +
2751
2766
  extra +
2752
2767
  modelOverlay +
2753
2768
  runtimeContext);
2754
2769
  },
2755
2770
  model: options?.model,
2756
2771
  appId: options?.appId,
2772
+ hostedHarnessConfig,
2757
2773
  apiKey: options?.apiKey,
2758
2774
  ...resolveInteractiveAgentRunOptions(options),
2759
2775
  finalResponseGuard: options?.finalResponseGuard,
@@ -4692,9 +4708,13 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
4692
4708
  // `prodHandler.systemPrompt` then steers source changes to a
4693
4709
  // separate agent surface such as Builder or the dev frame.
4694
4710
  const blockInProductCodeEditing = shouldBlockInProductCodeEditing(event);
4711
+ const hostedHarnessRequest = getHeader(event, "x-agent-native-hosted-harness") === "1";
4695
4712
  const handler = ownerContext.anonymous && anonymousHandler
4696
4713
  ? anonymousHandler
4697
- : !blockInProductCodeEditing && currentDevMode && devHandler
4714
+ : !hostedHarnessRequest &&
4715
+ !blockInProductCodeEditing &&
4716
+ currentDevMode &&
4717
+ devHandler
4698
4718
  ? devHandler
4699
4719
  : prodHandler;
4700
4720
  return handler(event);
@@ -27,10 +27,10 @@ export declare function resolveAgentEngineApiKeyWriteTarget(event: H3Event, scop
27
27
  export declare function createAgentEngineApiKeyHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
28
28
  error: any;
29
29
  } | {
30
+ error?: undefined;
30
31
  ok: boolean;
31
32
  key: string;
32
33
  baseUrlKey?: string;
33
34
  scope: AgentEngineApiKeyScope;
34
- error?: undefined;
35
35
  }>>;
36
36
  export {};
@@ -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: {