@agent-native/core 0.227.0-nightly-20261110182415 → 0.227.0
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/default-agent-engine.d.ts +1 -0
- package/dist/agent/default-agent-engine.js +6 -3
- package/dist/agent/engine/builder-engine.js +10 -6
- package/dist/agent/engine/chat-model-availability.d.ts +9 -0
- package/dist/agent/engine/chat-model-availability.js +39 -0
- package/dist/agent/optional-placeholders.d.ts +1 -0
- package/dist/agent/optional-placeholders.js +3 -0
- package/dist/cli/index.js +1 -1
- package/dist/client/chat/agentkit-protocol.js +259 -200
- package/dist/client/chat/run-outcome.d.ts +48 -0
- package/dist/client/chat/run-outcome.js +50 -0
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/framework-package-versions.json +11 -11
- package/dist/jobs/run-now.js +9 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/org/index.d.ts +1 -1
- package/dist/org/migrations.d.ts +1 -1
- package/dist/provider-api/actions/provider-api.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.js +9 -5
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/dist/templates/builder-code-starter/AGENTS.md.patch +1 -1
- package/dist/templates/chat/AGENTS.md +1 -1
- package/dist/triggers/actions/list-automations.js +7 -1
- package/docs/content/agent-web-surfaces.mdx +54 -42
- package/docs/content/create-with-an-agent.mdx +1 -1
- package/docs/content/external-agents.mdx +8 -0
- package/package.json +4 -4
- package/src/templates/builder-code-starter/AGENTS.md.patch +1 -1
- package/src/templates/chat/AGENTS.md +1 -1
|
@@ -15,6 +15,54 @@ import { type AutoContinueRefusalCode } from "../../agent/auto-continue.js";
|
|
|
15
15
|
*/
|
|
16
16
|
export declare const RUN_OUTCOMES: readonly ["running", "succeeded", "stopped", "interrupted", "failed", "unverified"];
|
|
17
17
|
export type RunOutcome = (typeof RUN_OUTCOMES)[number];
|
|
18
|
+
export type ActiveRunPhase = {
|
|
19
|
+
readonly type: "streaming";
|
|
20
|
+
} | {
|
|
21
|
+
readonly type: "holdingInterruption";
|
|
22
|
+
readonly error: AgentError;
|
|
23
|
+
} | {
|
|
24
|
+
readonly type: "followingSuccessor";
|
|
25
|
+
} | {
|
|
26
|
+
readonly type: "awaitingContinuation";
|
|
27
|
+
readonly streamClosed: boolean;
|
|
28
|
+
};
|
|
29
|
+
export type RunPhase = ActiveRunPhase | {
|
|
30
|
+
readonly type: "cancelling";
|
|
31
|
+
readonly previous: ActiveRunPhase;
|
|
32
|
+
} | {
|
|
33
|
+
readonly type: "terminal";
|
|
34
|
+
} | {
|
|
35
|
+
readonly type: "disposed";
|
|
36
|
+
};
|
|
37
|
+
export type RunPhaseEvent = {
|
|
38
|
+
readonly type: "streamEnded";
|
|
39
|
+
} | {
|
|
40
|
+
readonly type: "streamFailed";
|
|
41
|
+
} | {
|
|
42
|
+
readonly type: "interrupted";
|
|
43
|
+
readonly error: AgentError;
|
|
44
|
+
} | {
|
|
45
|
+
readonly type: "followSuccessor";
|
|
46
|
+
} | {
|
|
47
|
+
readonly type: "streamOpened";
|
|
48
|
+
} | {
|
|
49
|
+
readonly type: "continuationResumed";
|
|
50
|
+
} | {
|
|
51
|
+
readonly type: "awaitContinuation";
|
|
52
|
+
readonly streamClosed: boolean;
|
|
53
|
+
} | {
|
|
54
|
+
readonly type: "terminal";
|
|
55
|
+
} | {
|
|
56
|
+
readonly type: "cancelStarted";
|
|
57
|
+
} | {
|
|
58
|
+
readonly type: "cancelSucceeded";
|
|
59
|
+
} | {
|
|
60
|
+
readonly type: "cancelFailed";
|
|
61
|
+
} | {
|
|
62
|
+
readonly type: "dispose";
|
|
63
|
+
};
|
|
64
|
+
/** Late stream and authority results cannot revive a terminal or disposed run. */
|
|
65
|
+
export declare function transition(phase: RunPhase, event: RunPhaseEvent): RunPhase;
|
|
18
66
|
/**
|
|
19
67
|
* Codes that described "the agent stopped / is stuck" one incident at a time.
|
|
20
68
|
* They survive only as telemetry detail; the user sees their outcome. A new
|
|
@@ -24,6 +24,56 @@ export const RUN_OUTCOMES = [
|
|
|
24
24
|
"failed",
|
|
25
25
|
"unverified",
|
|
26
26
|
];
|
|
27
|
+
/** Late stream and authority results cannot revive a terminal or disposed run. */
|
|
28
|
+
export function transition(phase, event) {
|
|
29
|
+
if (event.type === "dispose")
|
|
30
|
+
return { type: "disposed" };
|
|
31
|
+
if (phase.type === "disposed")
|
|
32
|
+
return phase;
|
|
33
|
+
if (phase.type === "terminal")
|
|
34
|
+
return phase;
|
|
35
|
+
if (phase.type === "cancelling") {
|
|
36
|
+
if (event.type === "cancelFailed")
|
|
37
|
+
return phase.previous;
|
|
38
|
+
if (event.type === "cancelSucceeded")
|
|
39
|
+
return { type: "terminal" };
|
|
40
|
+
return phase;
|
|
41
|
+
}
|
|
42
|
+
switch (event.type) {
|
|
43
|
+
case "streamEnded":
|
|
44
|
+
case "streamFailed":
|
|
45
|
+
return phase.type === "streaming"
|
|
46
|
+
? { type: "followingSuccessor" }
|
|
47
|
+
: phase;
|
|
48
|
+
case "interrupted":
|
|
49
|
+
return phase.type === "streaming"
|
|
50
|
+
? { type: "holdingInterruption", error: event.error }
|
|
51
|
+
: phase;
|
|
52
|
+
case "followSuccessor":
|
|
53
|
+
return phase.type === "holdingInterruption"
|
|
54
|
+
? { type: "followingSuccessor" }
|
|
55
|
+
: phase;
|
|
56
|
+
case "streamOpened":
|
|
57
|
+
return phase.type === "followingSuccessor"
|
|
58
|
+
? { type: "streaming" }
|
|
59
|
+
: phase;
|
|
60
|
+
case "continuationResumed":
|
|
61
|
+
return phase.type === "awaitingContinuation"
|
|
62
|
+
? { type: "streaming" }
|
|
63
|
+
: phase;
|
|
64
|
+
case "awaitContinuation":
|
|
65
|
+
return phase.type === "streaming"
|
|
66
|
+
? { type: "awaitingContinuation", streamClosed: event.streamClosed }
|
|
67
|
+
: phase;
|
|
68
|
+
case "terminal":
|
|
69
|
+
return { type: "terminal" };
|
|
70
|
+
case "cancelStarted":
|
|
71
|
+
return { type: "cancelling", previous: phase };
|
|
72
|
+
case "cancelSucceeded":
|
|
73
|
+
case "cancelFailed":
|
|
74
|
+
return phase;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
27
77
|
/**
|
|
28
78
|
* Codes that described "the agent stopped / is stuck" one incident at a time.
|
|
29
79
|
* They survive only as telemetry detail; the user sees their outcome. A new
|
package/dist/collab/routes.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import
|
|
|
26
26
|
ok: boolean;
|
|
27
27
|
}>>;
|
|
28
28
|
export declare const postCollabText: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
29
|
-
ok?: undefined;
|
|
30
29
|
text?: undefined;
|
|
30
|
+
ok?: undefined;
|
|
31
31
|
error: string;
|
|
32
32
|
} | {
|
|
33
33
|
error?: undefined;
|
|
@@ -13,9 +13,9 @@ export declare const postCollabPatch: import("h3").EventHandlerWithFetch<import(
|
|
|
13
13
|
ok: boolean;
|
|
14
14
|
}>>;
|
|
15
15
|
export declare const getCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
16
|
-
data?: undefined;
|
|
17
16
|
error: string;
|
|
18
17
|
docId?: undefined;
|
|
18
|
+
data?: undefined;
|
|
19
19
|
} | {
|
|
20
20
|
error?: undefined;
|
|
21
21
|
docId: string;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
|
-
"@agent-native/agentkit": "0.227.0
|
|
2
|
+
"@agent-native/agentkit": "0.227.0",
|
|
3
3
|
"@agent-native/code-agents-ui": "0.1.75",
|
|
4
|
-
"@agent-native/core": "0.227.0
|
|
5
|
-
"@agent-native/core-corpus": "0.227.0
|
|
6
|
-
"@agent-native/creative-context": "0.8.69
|
|
7
|
-
"@agent-native/dispatch": "0.42.4
|
|
4
|
+
"@agent-native/core": "0.227.0",
|
|
5
|
+
"@agent-native/core-corpus": "0.227.0",
|
|
6
|
+
"@agent-native/creative-context": "0.8.69",
|
|
7
|
+
"@agent-native/dispatch": "0.42.4",
|
|
8
8
|
"@agent-native/embedding": "0.2.0",
|
|
9
9
|
"@agent-native/migrate": "0.0.7",
|
|
10
|
-
"@agent-native/otel": "0.1.
|
|
11
|
-
"@agent-native/pinpoint": "0.1.
|
|
12
|
-
"@agent-native/recap-cli": "0.5.
|
|
13
|
-
"@agent-native/scheduling": "0.2.56
|
|
10
|
+
"@agent-native/otel": "0.1.36",
|
|
11
|
+
"@agent-native/pinpoint": "0.1.112",
|
|
12
|
+
"@agent-native/recap-cli": "0.5.100",
|
|
13
|
+
"@agent-native/scheduling": "0.2.56",
|
|
14
14
|
"@agent-native/shared-app-config": "0.1.2",
|
|
15
|
-
"@agent-native/skills": "0.4.4
|
|
16
|
-
"@agent-native/toolkit": "0.227.0
|
|
15
|
+
"@agent-native/skills": "0.4.4",
|
|
16
|
+
"@agent-native/toolkit": "0.227.0"
|
|
17
17
|
}
|
package/dist/jobs/run-now.js
CHANGED
|
@@ -4,7 +4,7 @@ import { canQueueAutomationRunNow, } from "../automations/service.js";
|
|
|
4
4
|
import { isLocalDatabase } from "../db/client.js";
|
|
5
5
|
import { organizationResourceOwner, resourceGetByPath, } from "../resources/store.js";
|
|
6
6
|
import { fireInternalDispatch } from "../server/self-dispatch.js";
|
|
7
|
-
import { parseJobResource } from "./frontmatter.js";
|
|
7
|
+
import { isRecoveredFactoryJob, jobBelongsToApp, parseJobResource, } from "./frontmatter.js";
|
|
8
8
|
import { automationRunOwnership } from "./run-history-ownership.js";
|
|
9
9
|
import { listUnclaimedAutomationRuns, startAutomationRun, } from "./run-history.js";
|
|
10
10
|
async function dispatchAutomationRun(historyId, requestHeaders) {
|
|
@@ -113,6 +113,14 @@ export async function authorizeAutomationRunNow(input) {
|
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
115
|
if (!(await canQueueAutomationRunNow(input, access.resource, access.scope, input.additionalJobAppIds))) {
|
|
116
|
+
const { meta } = parseJobResource(access.resource.content);
|
|
117
|
+
if (!jobBelongsToApp(meta, input.appId, input.additionalJobAppIds) &&
|
|
118
|
+
!isRecoveredFactoryJob(meta, access.resource.path, input.appId, access.resource.owner)) {
|
|
119
|
+
const ownerAppId = meta.appId?.trim();
|
|
120
|
+
throw Object.assign(new Error(ownerAppId
|
|
121
|
+
? `This automation belongs to the "${ownerAppId}" app. Run it from that app.`
|
|
122
|
+
: "This automation has no app owner and cannot be run."), { statusCode: 403 });
|
|
123
|
+
}
|
|
116
124
|
throw Object.assign(new Error("Collaborate access is required to run this automation."), { statusCode: 403 });
|
|
117
125
|
}
|
|
118
126
|
return access;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export declare function createNotificationsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<"" | import("./types.js").Notification[] | {
|
|
2
|
-
error?: undefined;
|
|
3
2
|
count: number;
|
|
4
3
|
updated?: undefined;
|
|
4
|
+
error?: undefined;
|
|
5
5
|
ok?: undefined;
|
|
6
6
|
} | {
|
|
7
|
-
error?: undefined;
|
|
8
7
|
count?: undefined;
|
|
9
8
|
updated: number;
|
|
9
|
+
error?: undefined;
|
|
10
10
|
ok?: undefined;
|
|
11
11
|
} | {
|
|
12
12
|
count?: undefined;
|
|
@@ -14,8 +14,8 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
|
|
|
14
14
|
error: string;
|
|
15
15
|
ok?: undefined;
|
|
16
16
|
} | {
|
|
17
|
-
error?: undefined;
|
|
18
17
|
count?: undefined;
|
|
19
18
|
updated?: undefined;
|
|
19
|
+
error?: undefined;
|
|
20
20
|
ok: boolean;
|
|
21
21
|
}>>;
|
package/dist/org/index.d.ts
CHANGED
|
@@ -180,9 +180,9 @@ export declare const getMyOrgHandler: import("h3").EventHandlerWithFetch<import(
|
|
|
180
180
|
soloDeploymentAdmin: boolean | undefined;
|
|
181
181
|
}>>;
|
|
182
182
|
export declare const createOrgHandler: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
183
|
-
id?: undefined;
|
|
184
183
|
name?: undefined;
|
|
185
184
|
success: boolean;
|
|
185
|
+
id?: undefined;
|
|
186
186
|
role?: undefined;
|
|
187
187
|
} | {
|
|
188
188
|
success?: undefined;
|
package/dist/org/migrations.d.ts
CHANGED
|
@@ -316,8 +316,8 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
316
316
|
notes?: string | undefined;
|
|
317
317
|
scope?: "org" | "user" | undefined;
|
|
318
318
|
}, {
|
|
319
|
-
provider?: undefined;
|
|
320
319
|
id?: undefined;
|
|
320
|
+
provider?: undefined;
|
|
321
321
|
message?: undefined;
|
|
322
322
|
providers: {
|
|
323
323
|
id: string;
|
|
@@ -49,7 +49,6 @@ export declare function handleUploadResource(event: any): Promise<import("./stor
|
|
|
49
49
|
error: string;
|
|
50
50
|
storageSetupRequired?: undefined;
|
|
51
51
|
} | {
|
|
52
|
-
error?: undefined;
|
|
53
52
|
id: string;
|
|
54
53
|
path: string;
|
|
55
54
|
owner: string;
|
|
@@ -64,6 +63,7 @@ export declare function handleUploadResource(event: any): Promise<import("./stor
|
|
|
64
63
|
runId: string | null;
|
|
65
64
|
expiresAt: number | null;
|
|
66
65
|
metadata: string | null;
|
|
66
|
+
error?: undefined;
|
|
67
67
|
url: string;
|
|
68
68
|
provider: string;
|
|
69
69
|
storageSetupRequired?: undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getAgentAppModelDefaultForCurrentRequest } from "../../agent/app-model-defaults.js";
|
|
2
2
|
import { CHATGPT_SUBSCRIPTION_ENGINE_NAME } from "../../agent/chatgpt-subscription-contract.js";
|
|
3
|
-
import { readDefaultAgentEngineSettingDetailed, resolveDefaultAgentEngineAuthority, } from "../../agent/default-agent-engine.js";
|
|
3
|
+
import { isDefaultAgentEngineScopeResolved, readDefaultAgentEngineSettingDetailed, resolveDefaultAgentEngineAuthority, } from "../../agent/default-agent-engine.js";
|
|
4
4
|
import { listChatGPTSubscriptionModels } from "../../agent/engine/chatgpt-subscription-engine.js";
|
|
5
5
|
import { listAgentEngines, registerBuiltinEngines, detectEngineFromEnv, detectEngineFromUserSecrets, getAgentEngineEntry, isAgentEnginePackageInstalled, isStoredEngineUsableForRequest, normalizeModelForEngine, resolveEngineAcceptsCustomModels, resolveEnginePreservesCustomModels, } from "../../agent/engine/index.js";
|
|
6
6
|
import { applyProviderModelSelection, providerForEngineName, resolveEffectiveProviderModelSelection, } from "../../agent/provider-model-selection.js";
|
|
@@ -101,10 +101,14 @@ export async function run(args = {}) {
|
|
|
101
101
|
}
|
|
102
102
|
return pending;
|
|
103
103
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
// An unresolved scope cannot say which default applies. Listing engines
|
|
105
|
+
// must still work, so the read is skipped and reported as "unresolved"
|
|
106
|
+
// instead of "none", which would claim no default is saved.
|
|
107
|
+
const defaultAuthority = await resolveDefaultAgentEngineAuthority();
|
|
108
|
+
const scopeUnresolved = !isDefaultAgentEngineScopeResolved();
|
|
109
|
+
const defaultSetting = scopeUnresolved
|
|
110
|
+
? { value: null, source: "unresolved" }
|
|
111
|
+
: await readDefaultAgentEngineSettingDetailed();
|
|
108
112
|
const current = defaultSetting.value
|
|
109
113
|
? defaultSetting.value
|
|
110
114
|
: null;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export { callerHasThreadAccess } from "../agent/run-ownership.js";
|
|
|
41
41
|
export { abortTurnByRefDurably, getActiveRunForThreadAsync, } from "../agent/run-manager.js";
|
|
42
42
|
export { mountRealtimeVoiceRoutes, realtimeVoiceSafetyIdentifier, REALTIME_VOICE_MAX_SDP_BYTES, REALTIME_VOICE_MAX_TOOL_BODY_BYTES, REALTIME_VOICE_MAX_TOOL_OUTPUT_CHARS, REALTIME_VOICE_SESSION_PATH, REALTIME_VOICE_TOOL_PATH, type MountRealtimeVoiceRoutesOptions, type RealtimeVoiceIntelligence, type RealtimeVoiceRequestContext, type RealtimeVoiceToolExecutionRequest, type RealtimeVoiceToolExecutionResult, } from "./realtime-voice.js";
|
|
43
43
|
export { getStoredModelForEngine, resolveEngine, } from "../agent/engine/index.js";
|
|
44
|
+
export { resolveChatModelAvailability, type ChatModelAvailability, } from "../agent/engine/chat-model-availability.js";
|
|
44
45
|
export { completeText, type CompleteTextMessage, type CompleteTextOptions, type CompleteTextResult, type CompleteTextUsage, } from "./complete-text.js";
|
|
45
46
|
export { createDevScriptRegistry } from "../scripts/dev/index.js";
|
|
46
47
|
export { createPollHandler, recordChange, prepareTransactionalChange, getVersion, getChangesSince, getCurrentPollBaseline, getPollEmitter, canSeeChangeForUser, POLL_CHANGE_EVENT, type TransactionalChange, } from "./poll.js";
|
package/dist/server/index.js
CHANGED
|
@@ -39,6 +39,7 @@ export { callerHasThreadAccess } from "../agent/run-ownership.js";
|
|
|
39
39
|
export { abortTurnByRefDurably, getActiveRunForThreadAsync, } from "../agent/run-manager.js";
|
|
40
40
|
export { mountRealtimeVoiceRoutes, realtimeVoiceSafetyIdentifier, REALTIME_VOICE_MAX_SDP_BYTES, REALTIME_VOICE_MAX_TOOL_BODY_BYTES, REALTIME_VOICE_MAX_TOOL_OUTPUT_CHARS, REALTIME_VOICE_SESSION_PATH, REALTIME_VOICE_TOOL_PATH, } from "./realtime-voice.js";
|
|
41
41
|
export { getStoredModelForEngine, resolveEngine, } from "../agent/engine/index.js";
|
|
42
|
+
export { resolveChatModelAvailability, } from "../agent/engine/chat-model-availability.js";
|
|
42
43
|
export { completeText, } from "./complete-text.js";
|
|
43
44
|
export { createDevScriptRegistry } from "../scripts/dev/index.js";
|
|
44
45
|
export { createPollHandler, recordChange, prepareTransactionalChange, getVersion, getChangesSince, getCurrentPollBaseline, getPollEmitter, canSeeChangeForUser, POLL_CHANGE_EVENT, } from "./poll.js";
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
-Choose the primary workflow and route before editing. Add a domain route under `app/routes/` and set `app.homePath` in `server/plugins/agent-native-email-branding.ts` with `defineAppConfig`. The default Get started page lives at `/home`, and Chat stays at `/chat`; edit `app/routes/home.tsx` when replacing that page with a domain-specific home. Add a static link in `app/components/layout/Sidebar.tsx` before `ChatThreadsSection`; `Header.tsx` uses `APP_TITLE` elsewhere. Shared sidebar and AgentInspector remain.
|
|
42
42
|
+Choose the primary workflow and route before editing. Build on the blank canvas in `app/routes/_index.tsx` or add domain routes under `app/routes/`. This starter has no Chat route, sidebar, header, or agent rail; add only the navigation the product needs. Set `app.homePath` in the existing `defineAppConfig` in `server/plugins/config.ts` as `DEVELOPING.md` describes.
|
|
43
43
|
|
|
44
|
-
-Use `adding-a-feature` for functional parity and `frontend-design` for a user-facing screen. Keep feature guidance here; do not rewrite `README.md` or `DESIGN.md`. After all edits, run one typecheck, one doctor check, and one browser smoke of the primary workflow
|
|
44
|
+
-Use `adding-a-feature` for functional parity and `frontend-design` for a user-facing screen. Keep feature guidance here; do not rewrite `README.md` or `DESIGN.md`. After all edits, run one typecheck, one doctor check, and one browser smoke of the primary workflow and its authenticated landing. Skip production build and extra test suites.
|
|
45
45
|
+Use `adding-a-feature` for functional parity and `frontend-design` for a user-facing screen. Keep feature guidance here and update `README.md` as `DEVELOPING.md` describes. After all edits, run one typecheck, one doctor check, and one browser smoke of the primary workflow and its authenticated landing. Skip production build and extra test suites.
|
|
46
46
|
|
|
47
47
|
Before building common workspace or agent UI, read `agent-native-toolkit`; for supported customization, read `customizing-agent-native`.
|
|
@@ -26,6 +26,6 @@ For custom branding, keep `server/plugins/agent-native-email-branding.ts` aligne
|
|
|
26
26
|
|
|
27
27
|
Choose the primary workflow and route before editing. Add a domain route under `app/routes/` and set `app.homePath` in `server/plugins/agent-native-email-branding.ts` with `defineAppConfig`. The default Get started page lives at `/home`, and Chat stays at `/chat`; edit `app/routes/home.tsx` when replacing that page with a domain-specific home. Add a static link in `app/components/layout/Sidebar.tsx` before `ChatThreadsSection`; `Header.tsx` uses `APP_TITLE` elsewhere. Shared sidebar and AgentInspector remain.
|
|
28
28
|
|
|
29
|
-
Use `adding-a-feature` for functional parity and `frontend-design` for a user-facing screen. Keep feature guidance here; do not rewrite `README.md` or `DESIGN.md`. After all edits, run one typecheck, one doctor check, and one browser smoke of the primary workflow
|
|
29
|
+
Use `adding-a-feature` for functional parity and `frontend-design` for a user-facing screen. Keep feature guidance here; do not rewrite `README.md` or `DESIGN.md`. After all edits, run one typecheck, one doctor check, and one browser smoke of the primary workflow and its authenticated landing. Skip production build and extra test suites.
|
|
30
30
|
|
|
31
31
|
Before building common workspace or agent UI, read `agent-native-toolkit`; for supported customization, read `customizing-agent-native`.
|
|
@@ -3,6 +3,7 @@ import { defineAction } from "../../action.js";
|
|
|
3
3
|
import { listAccessibleAutomationDefinitions, } from "../../automations/service.js";
|
|
4
4
|
import { hasStalePause, isPausedByFramework, } from "../../jobs/automation-outcome.js";
|
|
5
5
|
import { describeCron, effectiveTimezone, isValidCron, nextOccurrence, } from "../../jobs/cron.js";
|
|
6
|
+
import { isRecoveredFactoryJob, jobBelongsToApp, } from "../../jobs/frontmatter.js";
|
|
6
7
|
import { listLatestAutomationRuns } from "../../jobs/run-history.js";
|
|
7
8
|
function nextRun(meta) {
|
|
8
9
|
if (!meta.enabled)
|
|
@@ -111,7 +112,12 @@ export default defineAction({
|
|
|
111
112
|
deliveryTenantId: meta.deliveryTenantId ?? null,
|
|
112
113
|
canUpdate,
|
|
113
114
|
effectiveRole,
|
|
114
|
-
capabilities
|
|
115
|
+
capabilities: {
|
|
116
|
+
...capabilities,
|
|
117
|
+
canOperate: capabilities.canOperate &&
|
|
118
|
+
(jobBelongsToApp(meta, ctx.appId) ||
|
|
119
|
+
isRecoveredFactoryJob(meta, resource.path, ctx.appId, resource.owner)),
|
|
120
|
+
},
|
|
115
121
|
sharing,
|
|
116
122
|
creator,
|
|
117
123
|
};
|
|
@@ -17,7 +17,7 @@ The docs site is the reference implementation. Today it ships:
|
|
|
17
17
|
- JSON-LD for base organization, website, and page metadata.
|
|
18
18
|
- An audit CLI (`npx @agent-native/core@latest audit-agent-web`) that checks all of the above.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Publishing these files never exposes an action. An action reaches external agents only through its own `publicAgent` opt-in; see [Expose to public agents](/docs/actions-access-control#public-agent).
|
|
21
21
|
|
|
22
22
|
<Diagram id="doc-block-1guzidr" title="What a public route publishes" summary={"A public route fans out into agent-friendly representations. Reading the route is separate from calling tools — tool access stays opt-in."}>
|
|
23
23
|
|
|
@@ -25,7 +25,7 @@ Setting `publicMcp: true` additionally exposes opted-in actions as a public MCP
|
|
|
25
25
|
<div class="diagram-web">
|
|
26
26
|
<div class="diagram-box" data-rough>
|
|
27
27
|
Public route<br /><small class="diagram-muted"
|
|
28
|
-
>
|
|
28
|
+
>from the page list you pass</small
|
|
29
29
|
>
|
|
30
30
|
</div>
|
|
31
31
|
<div class="diagram-arrow diagram-muted" aria-hidden="true">→</div>
|
|
@@ -40,9 +40,7 @@ Setting `publicMcp: true` additionally exposes opted-in actions as a public MCP
|
|
|
40
40
|
<div class="diagram-arrow diagram-muted" aria-hidden="true">→</div>
|
|
41
41
|
<div class="diagram-col gate">
|
|
42
42
|
<span class="diagram-pill warn">Tools stay private</span
|
|
43
|
-
><small class="diagram-muted"
|
|
44
|
-
>publicMcp + publicAgent.expose required</small
|
|
45
|
-
>
|
|
43
|
+
><small class="diagram-muted">publicAgent.expose required</small>
|
|
46
44
|
</div>
|
|
47
45
|
</div>
|
|
48
46
|
```
|
|
@@ -75,45 +73,57 @@ Setting `publicMcp: true` additionally exposes opted-in actions as a public MCP
|
|
|
75
73
|
|
|
76
74
|
## Configuration {#config}
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
}
|
|
76
|
+
`createAgentWebVitePlugin` from `@agent-native/core/vite` writes these files during a production build. Add it to your Vite config with the pages agents should read:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
// vite.config.ts
|
|
80
|
+
import { defineConfig } from "vite";
|
|
81
|
+
import { createAgentWebVitePlugin } from "@agent-native/core/vite";
|
|
82
|
+
|
|
83
|
+
export default defineConfig({
|
|
84
|
+
plugins: [
|
|
85
|
+
// ...your existing plugins
|
|
86
|
+
createAgentWebVitePlugin({
|
|
87
|
+
siteName: "My Agent-Native App",
|
|
88
|
+
siteUrl: "https://example.com",
|
|
89
|
+
pages: [
|
|
90
|
+
{
|
|
91
|
+
path: "/pricing",
|
|
92
|
+
title: "Pricing",
|
|
93
|
+
description: "Plans and limits.",
|
|
94
|
+
markdown: "Plans and limits.\n",
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
agentWeb: { crawlerPolicy: "discoverable-no-training" },
|
|
98
|
+
}),
|
|
99
|
+
],
|
|
100
|
+
});
|
|
105
101
|
```
|
|
106
102
|
|
|
107
|
-
|
|
103
|
+
The plugin publishes the pages you list and nothing else. It doesn't read your route access settings, and it doesn't read `agentWeb` from `package.json` unless you pass it in. To keep the settings in `package.json` under `agent-native.workspaceApp.agentWeb`, pass `agentWeb: agentWebConfigFromPackageJson(pkg)`, imported from `@agent-native/core/agent-web`.
|
|
104
|
+
|
|
105
|
+
| Option | Default | What it does |
|
|
106
|
+
| --------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
107
|
+
| `discoverable` | On when `pages` isn't empty | `false` writes no files. |
|
|
108
|
+
| `llmsTxt` | `true` | Writes `/llms.txt` and `/llms-full.txt`. |
|
|
109
|
+
| `markdownTwins` | `true` | Writes a `.md` copy of each page that has `markdown`. |
|
|
110
|
+
| `crawlerPolicy` | `"discoverable-no-training"` | Sets the `robots.txt` rules: `"discoverable-no-training"`, `"allow-all"`, or `"disallow-all"`. |
|
|
111
|
+
| `crawlers` | None | Overrides individual crawler categories: `training`, `search`, `userTriggered`, `codingAgents`, or `autonomousAgents`, each `"allow"` or `"disallow"`. |
|
|
112
|
+
|
|
113
|
+
The default crawler policy is "discoverable, not trainable": search, user-triggered retrieval, coding agents, and autonomous browsing agents are allowed; training crawlers are disallowed.
|
|
114
|
+
|
|
115
|
+
`jsonLd`, `publicAgentCard`, and `publicMcp` are accepted, but nothing reads them yet. For JSON-LD, render `buildBaseJsonLd` and `buildPageJsonLd` from `@agent-native/core/agent-web` into your pages yourself.
|
|
108
116
|
|
|
109
117
|
## Route source of truth {#route-source}
|
|
110
118
|
|
|
111
|
-
|
|
119
|
+
The page list is the source of truth: agents get the pages you pass, and only those. Build it from pages that are already public:
|
|
120
|
+
|
|
121
|
+
- In a public app, every route except `protectedPaths`.
|
|
122
|
+
- In an internal app, only `publicPaths`.
|
|
123
|
+
- Public share and form pages that agents should be able to read.
|
|
124
|
+
- Never submitted private data, authenticated dashboards, or user or org state, even when a nearby page is public.
|
|
112
125
|
|
|
113
|
-
-
|
|
114
|
-
- Internal apps expose only `publicPaths`.
|
|
115
|
-
- Public share and form pages can be readable by agents.
|
|
116
|
-
- Submitted private data, authenticated dashboards, and user/org state are never included just because a nearby page is public.
|
|
126
|
+
To start from your access settings, `deriveAgentWebPublicRoutes` from `@agent-native/core/agent-web` takes your app's `audience`, `publicPaths`, `protectedPaths`, and `routes`, and returns the routes those settings make public. Each page still needs its own title and Markdown.
|
|
117
127
|
|
|
118
128
|
This keeps mixed apps natural. A forms app can expose a public form page and keep submissions private. A content app can expose published posts and keep the editor private. A docs site can expose everything except admin tools.
|
|
119
129
|
|
|
@@ -123,7 +133,7 @@ Public page access and public tool access are separate. A route being public onl
|
|
|
123
133
|
|
|
124
134
|
<Callout id="doc-block-s50w8y" tone="warning">
|
|
125
135
|
|
|
126
|
-
**A public page is not a public tool.** Making a route crawlable never exposes an action. Tool access requires an explicit `publicAgent.expose` opt-in on the action
|
|
136
|
+
**A public page is not a public tool.** Making a route crawlable never exposes an action. Tool access requires an explicit `publicAgent.expose` opt-in on the action.
|
|
127
137
|
|
|
128
138
|
</Callout>
|
|
129
139
|
|
|
@@ -151,7 +161,7 @@ To expose an action through a public agent protocol, the action must opt in:
|
|
|
151
161
|
]}
|
|
152
162
|
/>
|
|
153
163
|
|
|
154
|
-
`agentWeb
|
|
164
|
+
No `agentWeb` setting exposes an action, and `publicMcp` has no effect today. See [Expose to public agents](/docs/actions-access-control#public-agent) for what `publicAgent` opts an action into and the checks that still apply.
|
|
155
165
|
|
|
156
166
|
## Build-time files {#build-time}
|
|
157
167
|
|
|
@@ -186,7 +196,9 @@ const files = buildAgentWebStaticFiles({
|
|
|
186
196
|
});
|
|
187
197
|
```
|
|
188
198
|
|
|
189
|
-
|
|
199
|
+
`createAgentWebVitePlugin` calls `buildAgentWebStaticFiles` for you and writes the files into whichever of `public`, `dist`, `dist/client`, `dist/server/public`, and `build/client` exist. With another build tool, call the utilities directly.
|
|
200
|
+
|
|
201
|
+
Neither one answers `Accept: text/markdown` on a page's own URL: the Markdown copy is only at its `.md` URL. To answer that header, add a server route that returns the page's Markdown with the headers from `buildMarkdownResponseHeaders`, as the docs site does. Without that route, the audit below fails its `Accept: text/markdown` check.
|
|
190
202
|
|
|
191
203
|
Pass `sitemapGroup` to `buildAgentWebStaticFiles` or `createAgentWebVitePlugin` to split a large sitemap. It maps each page to a group key, such as its locale, and `sitemap.xml` becomes a sitemap index with one `sitemap-<group>.xml` per group.
|
|
192
204
|
|
|
@@ -215,5 +227,5 @@ The audit exits non-zero if a required public surface is missing.
|
|
|
215
227
|
## What's next
|
|
216
228
|
|
|
217
229
|
- [**Actions**](/docs/actions-overview) — how to opt actions into the public agent protocol
|
|
218
|
-
- [**MCP Protocol**](/docs/mcp-protocol) — the MCP
|
|
230
|
+
- [**MCP Protocol**](/docs/mcp-protocol) — the MCP server external agents connect to
|
|
219
231
|
- [**Deployment**](/docs/deployment) — where these static files are written during builds
|
|
@@ -34,7 +34,7 @@ it. Use that name wherever a step below says APP_NAME.
|
|
|
34
34
|
--standalone --template chat
|
|
35
35
|
3. In the new APP_NAME folder, run `pnpm install`.
|
|
36
36
|
4. Read APP_NAME/AGENTS.md so you know how the app is laid out.
|
|
37
|
-
5. Start the app with `pnpm dev` and keep it running in the background.
|
|
37
|
+
5. Start the app with `pnpm dev --no-open` and keep it running in the background.
|
|
38
38
|
6. Read the local URL that `pnpm dev` prints. Check that it responds,
|
|
39
39
|
for example with `curl -I <url>`. Do not open a browser and do not
|
|
40
40
|
use headless browser tools. I will open the app myself.
|
|
@@ -166,6 +166,14 @@ invalid document ID. Verify the link and connected account's access before
|
|
|
166
166
|
changing permissions. Reinstalling the connector or changing the public share
|
|
167
167
|
link does not resolve a confirmed account permission denial.
|
|
168
168
|
|
|
169
|
+
Images uploaded into a private document are stored in its body as
|
|
170
|
+
`/api/private-media/<id>` links, which load only with a Content sign-in.
|
|
171
|
+
When an agent reads the document over MCP, `get-document`, and `pull-document`
|
|
172
|
+
in Markdown, also return `privateMediaLinks`: each stored link paired with a
|
|
173
|
+
URL that opens that one image without signing in, for one hour. One read links
|
|
174
|
+
at most 200 images; `omitted` counts the rest. Read the document again for
|
|
175
|
+
fresh links. Keep the stored links when editing the body.
|
|
176
|
+
|
|
169
177
|
<a id="access-tab"></a>
|
|
170
178
|
|
|
171
179
|
### The in-app MCP setting {#mcp-settings}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.227.0
|
|
3
|
+
"version": "0.227.0",
|
|
4
4
|
"description": "The agentic application framework for building autonomous agents with intuitive UIs",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -769,8 +769,8 @@
|
|
|
769
769
|
"yaml": "^2.9.0",
|
|
770
770
|
"yjs": "^13.6.33",
|
|
771
771
|
"zod": "^4.3.6",
|
|
772
|
-
"@agent-native/agentkit": "^0.227.0
|
|
773
|
-
"@agent-native/recap-cli": "^0.5.
|
|
772
|
+
"@agent-native/agentkit": "^0.227.0",
|
|
773
|
+
"@agent-native/recap-cli": "^0.5.100"
|
|
774
774
|
},
|
|
775
775
|
"devDependencies": {
|
|
776
776
|
"@ai-sdk/anthropic": "^3.0.71",
|
|
@@ -843,7 +843,7 @@
|
|
|
843
843
|
"xlsx": "^0.18.5"
|
|
844
844
|
},
|
|
845
845
|
"peerDependencies": {
|
|
846
|
-
"@agent-native/core-corpus": "0.
|
|
846
|
+
"@agent-native/core-corpus": ">=0.196.0",
|
|
847
847
|
"@ai-sdk/anthropic": ">=3",
|
|
848
848
|
"@ai-sdk/cohere": ">=3",
|
|
849
849
|
"@ai-sdk/google": ">=3",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
-Choose the primary workflow and route before editing. Add a domain route under `app/routes/` and set `app.homePath` in `server/plugins/agent-native-email-branding.ts` with `defineAppConfig`. The default Get started page lives at `/home`, and Chat stays at `/chat`; edit `app/routes/home.tsx` when replacing that page with a domain-specific home. Add a static link in `app/components/layout/Sidebar.tsx` before `ChatThreadsSection`; `Header.tsx` uses `APP_TITLE` elsewhere. Shared sidebar and AgentInspector remain.
|
|
42
42
|
+Choose the primary workflow and route before editing. Build on the blank canvas in `app/routes/_index.tsx` or add domain routes under `app/routes/`. This starter has no Chat route, sidebar, header, or agent rail; add only the navigation the product needs. Set `app.homePath` in the existing `defineAppConfig` in `server/plugins/config.ts` as `DEVELOPING.md` describes.
|
|
43
43
|
|
|
44
|
-
-Use `adding-a-feature` for functional parity and `frontend-design` for a user-facing screen. Keep feature guidance here; do not rewrite `README.md` or `DESIGN.md`. After all edits, run one typecheck, one doctor check, and one browser smoke of the primary workflow
|
|
44
|
+
-Use `adding-a-feature` for functional parity and `frontend-design` for a user-facing screen. Keep feature guidance here; do not rewrite `README.md` or `DESIGN.md`. After all edits, run one typecheck, one doctor check, and one browser smoke of the primary workflow and its authenticated landing. Skip production build and extra test suites.
|
|
45
45
|
+Use `adding-a-feature` for functional parity and `frontend-design` for a user-facing screen. Keep feature guidance here and update `README.md` as `DEVELOPING.md` describes. After all edits, run one typecheck, one doctor check, and one browser smoke of the primary workflow and its authenticated landing. Skip production build and extra test suites.
|
|
46
46
|
|
|
47
47
|
Before building common workspace or agent UI, read `agent-native-toolkit`; for supported customization, read `customizing-agent-native`.
|
|
@@ -26,6 +26,6 @@ For custom branding, keep `server/plugins/agent-native-email-branding.ts` aligne
|
|
|
26
26
|
|
|
27
27
|
Choose the primary workflow and route before editing. Add a domain route under `app/routes/` and set `app.homePath` in `server/plugins/agent-native-email-branding.ts` with `defineAppConfig`. The default Get started page lives at `/home`, and Chat stays at `/chat`; edit `app/routes/home.tsx` when replacing that page with a domain-specific home. Add a static link in `app/components/layout/Sidebar.tsx` before `ChatThreadsSection`; `Header.tsx` uses `APP_TITLE` elsewhere. Shared sidebar and AgentInspector remain.
|
|
28
28
|
|
|
29
|
-
Use `adding-a-feature` for functional parity and `frontend-design` for a user-facing screen. Keep feature guidance here; do not rewrite `README.md` or `DESIGN.md`. After all edits, run one typecheck, one doctor check, and one browser smoke of the primary workflow
|
|
29
|
+
Use `adding-a-feature` for functional parity and `frontend-design` for a user-facing screen. Keep feature guidance here; do not rewrite `README.md` or `DESIGN.md`. After all edits, run one typecheck, one doctor check, and one browser smoke of the primary workflow and its authenticated landing. Skip production build and extra test suites.
|
|
30
30
|
|
|
31
31
|
Before building common workspace or agent UI, read `agent-native-toolkit`; for supported customization, read `customizing-agent-native`.
|