@agent-native/core 0.204.1-nightly-20261008153353 → 0.205.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/a2a/caller-auth.d.ts +1 -0
- package/dist/a2a/caller-auth.js +9 -3
- package/dist/a2a/client.d.ts +1 -0
- package/dist/a2a/client.js +1 -1
- package/dist/a2a/index.d.ts +2 -1
- package/dist/a2a/index.js +2 -1
- package/dist/agent/engine/ai-sdk-engine.js +3 -8
- package/dist/agent/engine/builder-engine.d.ts +1 -1
- package/dist/agent/engine/openrouter-tool-fetch.d.ts +1 -0
- package/dist/agent/engine/openrouter-tool-fetch.js +20 -0
- package/dist/agent/engine/translate-ai-sdk.d.ts +1 -1
- package/dist/agent/engine/translate-ai-sdk.js +3 -2
- package/dist/agent/model-config.d.ts +2 -2
- package/dist/agent/model-config.js +2 -0
- package/dist/app-config/observability.js +8 -1
- package/dist/client/analytics-session.js +25 -7
- package/dist/client/chat/agentkit-protocol.js +13 -2
- package/dist/client/url-scrub.js +5 -2
- package/dist/deploy/build.js +11 -0
- package/dist/file-upload/actions/upload-image.d.ts +3 -3
- package/dist/jobs/background-automation-runner.js +13 -2
- package/dist/mcp/build-server.js +7 -4
- package/dist/mcp/connect-route.js +16 -11
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +6 -6
- package/dist/observability/sentiment.d.ts +1 -1
- package/dist/observability/sentiment.js +30 -6
- package/dist/org/index.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/secrets/routes.d.ts +11 -11
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
- package/dist/server/attribution.d.ts +4 -6
- package/dist/server/attribution.js +20 -6
- package/dist/server/better-auth-instance.d.ts +2 -1
- package/dist/server/better-auth-instance.js +5 -1
- package/dist/server/magic-link-attribution.d.ts +1 -0
- package/dist/server/magic-link-attribution.js +5 -0
- package/dist/shared/analytics-session-id.d.ts +5 -0
- package/dist/shared/analytics-session-id.js +21 -0
- package/dist/triggers/actions/manage-automation.d.ts +3 -3
- package/dist/vite/sentry-source-maps.d.ts +1 -0
- package/dist/vite/sentry-source-maps.js +48 -22
- package/docs/content/actions-access-control.mdx +67 -21
- package/package.json +4 -4
package/dist/a2a/caller-auth.js
CHANGED
|
@@ -26,14 +26,20 @@ export async function resolveA2ACallerAuth(options) {
|
|
|
26
26
|
if (userEmail &&
|
|
27
27
|
options?.audience &&
|
|
28
28
|
globalSecret &&
|
|
29
|
-
(!orgId || orgDomain?.trim())) {
|
|
30
|
-
addApiKeyAttempt(await signA2AToken(userEmail, orgDomain, undefined, {
|
|
29
|
+
(options?.userIdentityOnly || !orgId || orgDomain?.trim())) {
|
|
30
|
+
addApiKeyAttempt(await signA2AToken(userEmail, options?.userIdentityOnly ? undefined : orgDomain, undefined, {
|
|
31
31
|
expiresIn: options?.expiresIn ?? DEFAULT_A2A_CALLER_TOKEN_TTL,
|
|
32
32
|
preferGlobalSecret: true,
|
|
33
33
|
audience: options?.audience,
|
|
34
|
+
...(options?.userIdentityOnly && orgId
|
|
35
|
+
? { extraClaims: { org_id: orgId } }
|
|
36
|
+
: {}),
|
|
34
37
|
}));
|
|
35
38
|
}
|
|
36
|
-
if (
|
|
39
|
+
if (!options?.userIdentityOnly &&
|
|
40
|
+
orgDomain &&
|
|
41
|
+
options?.audience &&
|
|
42
|
+
(orgSecret || globalSecret)) {
|
|
37
43
|
addApiKeyAttempt(await signA2AOrganizationToken(orgDomain, orgSecret, undefined, {
|
|
38
44
|
expiresIn: options?.expiresIn ?? DEFAULT_A2A_CALLER_TOKEN_TTL,
|
|
39
45
|
audience: options?.audience,
|
package/dist/a2a/client.d.ts
CHANGED
|
@@ -135,6 +135,7 @@ export declare class A2AClient {
|
|
|
135
135
|
private postJson;
|
|
136
136
|
private transportHeadersFor;
|
|
137
137
|
}
|
|
138
|
+
export declare function assertCredentialedA2AUrl(url: string, credentialed: boolean): void;
|
|
138
139
|
export declare function callAgent(url: string, text: string, opts?: {
|
|
139
140
|
apiKey?: string;
|
|
140
141
|
apiKeyFallbacks?: string[];
|
package/dist/a2a/client.js
CHANGED
|
@@ -842,7 +842,7 @@ function hasA2ACredentials(apiKeys, headers) {
|
|
|
842
842
|
}
|
|
843
843
|
return Object.keys(headers ?? {}).some((name) => /^(authorization|api[-_]key|x-api[-_]key|x-api[-_]token)$/i.test(name));
|
|
844
844
|
}
|
|
845
|
-
function assertCredentialedA2AUrl(url, credentialed) {
|
|
845
|
+
export function assertCredentialedA2AUrl(url, credentialed) {
|
|
846
846
|
if (!credentialed)
|
|
847
847
|
return;
|
|
848
848
|
let parsed;
|
package/dist/a2a/index.d.ts
CHANGED
|
@@ -2,8 +2,9 @@ export { mountA2A, verifyA2AToken } from "./server.js";
|
|
|
2
2
|
export type { A2ATokenPayload } from "./server.js";
|
|
3
3
|
export { generateAgentCard } from "./agent-card.js";
|
|
4
4
|
export { A2A_AGENT_ACTIVITY_KIND, A2A_AGENT_ACTIVITY_VERSION, MAX_A2A_ACTIVITY_REASONING_CHARS, MAX_A2A_ACTIVITY_REASONING_SEGMENTS, MAX_A2A_ACTIVITY_RESPONSE_CHARS, MAX_A2A_ACTIVITY_TOOL_CALLS, MAX_A2A_ACTIVITY_TOTAL_CHARS, MAX_A2A_ACTIVITY_TOOL_ID_CHARS, MAX_A2A_ACTIVITY_TOOL_INPUT_CHARS, MAX_A2A_ACTIVITY_TOOL_NAME_CHARS, MAX_A2A_ACTIVITY_TOOL_PAYLOAD_CHARS, MAX_A2A_ACTIVITY_TOOL_RESULT_CHARS, applyA2AAgentActivityEvent, buildA2AAgentActivityPart, buildA2AAgentActivitySnapshot, createA2AAgentActivityState, parseA2AAgentActivityPart, } from "./activity.js";
|
|
5
|
-
export { A2AClient, A2AJsonRpcResponseError, A2AMissingJsonRpcResponseError, A2ANoJsonRpcInterfaceError, A2AProtocolError, callAction, callAgent, clearA2ACardCache, getGlobalA2ASecret, signA2AOrganizationToken, signA2AToken, } from "./client.js";
|
|
5
|
+
export { A2AClient, A2AJsonRpcResponseError, A2AMissingJsonRpcResponseError, A2ANoJsonRpcInterfaceError, A2AProtocolError, assertCredentialedA2AUrl, callAction, callAgent, clearA2ACardCache, getGlobalA2ASecret, signA2AOrganizationToken, signA2AToken, } from "./client.js";
|
|
6
6
|
export type { A2AProtocolErrorCode } from "./client.js";
|
|
7
|
+
export { workspacePrivateOrigins } from "./workspace-private-origins.js";
|
|
7
8
|
export { clearRemoteAgentTokenCache, RemoteAgentAuthError, RemoteAgentCredentialRejectedError, resolveRemoteAgentToken, } from "./remote-agent-auth.js";
|
|
8
9
|
export type { RemoteAgentAuthErrorCode, RemoteAgentCredentialContext, } from "./remote-agent-auth.js";
|
|
9
10
|
export { canonicalA2AAudience } from "./audience.js";
|
package/dist/a2a/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { mountA2A, verifyA2AToken } from "./server.js";
|
|
2
2
|
export { generateAgentCard } from "./agent-card.js";
|
|
3
3
|
export { A2A_AGENT_ACTIVITY_KIND, A2A_AGENT_ACTIVITY_VERSION, MAX_A2A_ACTIVITY_REASONING_CHARS, MAX_A2A_ACTIVITY_REASONING_SEGMENTS, MAX_A2A_ACTIVITY_RESPONSE_CHARS, MAX_A2A_ACTIVITY_TOOL_CALLS, MAX_A2A_ACTIVITY_TOTAL_CHARS, MAX_A2A_ACTIVITY_TOOL_ID_CHARS, MAX_A2A_ACTIVITY_TOOL_INPUT_CHARS, MAX_A2A_ACTIVITY_TOOL_NAME_CHARS, MAX_A2A_ACTIVITY_TOOL_PAYLOAD_CHARS, MAX_A2A_ACTIVITY_TOOL_RESULT_CHARS, applyA2AAgentActivityEvent, buildA2AAgentActivityPart, buildA2AAgentActivitySnapshot, createA2AAgentActivityState, parseA2AAgentActivityPart, } from "./activity.js";
|
|
4
|
-
export { A2AClient, A2AJsonRpcResponseError, A2AMissingJsonRpcResponseError, A2ANoJsonRpcInterfaceError, A2AProtocolError, callAction, callAgent, clearA2ACardCache, getGlobalA2ASecret, signA2AOrganizationToken, signA2AToken, } from "./client.js";
|
|
4
|
+
export { A2AClient, A2AJsonRpcResponseError, A2AMissingJsonRpcResponseError, A2ANoJsonRpcInterfaceError, A2AProtocolError, assertCredentialedA2AUrl, callAction, callAgent, clearA2ACardCache, getGlobalA2ASecret, signA2AOrganizationToken, signA2AToken, } from "./client.js";
|
|
5
|
+
export { workspacePrivateOrigins } from "./workspace-private-origins.js";
|
|
5
6
|
export { clearRemoteAgentTokenCache, RemoteAgentAuthError, RemoteAgentCredentialRejectedError, resolveRemoteAgentToken, } from "./remote-agent-auth.js";
|
|
6
7
|
export { canonicalA2AAudience } from "./audience.js";
|
|
7
8
|
export { resolveA2ACallerAuth } from "./caller-auth.js";
|
|
@@ -8,6 +8,7 @@ import { classifyProviderError, describeErrorWithCauses, } from "./error-detail.
|
|
|
8
8
|
import { createFirstEventAbortController } from "./first-event-timeout.js";
|
|
9
9
|
import { limitProviderTools } from "./limit-provider-tools.js";
|
|
10
10
|
import { isCustomOpenAiBaseUrl } from "./openai-compatible-endpoint.js";
|
|
11
|
+
import { createOpenRouterToolFetch } from "./openrouter-tool-fetch.js";
|
|
11
12
|
import { clampThinkingBudgetTokens, resolveMaxOutputTokensForEngine, } from "./output-tokens.js";
|
|
12
13
|
import { createProviderToolNameMap } from "./tool-name.js";
|
|
13
14
|
import { engineToolsToAISDK, engineMessagesToAISDK, aiSdkPartToEngineEvents, aiSdkStepToAssistantContent, } from "./translate-ai-sdk.js";
|
|
@@ -279,15 +280,8 @@ class AISDKEngine {
|
|
|
279
280
|
}
|
|
280
281
|
const toolNameMap = createProviderToolNameMap(opts.tools, opts.messages);
|
|
281
282
|
const providerTools = limitProviderTools(opts.tools);
|
|
282
|
-
// The Responses API treats an omitted `strict` as strict mode and rewrites
|
|
283
|
-
// every optional parameter as required, so the model must invent a value
|
|
284
|
-
// ("" or a guessed id) for each one. Action schemas use omission to mean
|
|
285
|
-
// "not this mode", so those fillers turn a valid call into a mixed one
|
|
286
|
-
// that validation rejects on every retry.
|
|
287
|
-
const usesResponsesApi = this.provider === "openai" &&
|
|
288
|
-
(this.forceResponses || !isCustomOpenAiBaseUrl(this.baseUrl));
|
|
289
283
|
const aiSdkTools = providerTools.length > 0
|
|
290
|
-
? engineToolsToAISDK(providerTools, jsonSchema, toolNameMap
|
|
284
|
+
? engineToolsToAISDK(providerTools, jsonSchema, toolNameMap)
|
|
291
285
|
: undefined;
|
|
292
286
|
const messages = engineMessagesToAISDK(opts.messages, {
|
|
293
287
|
toolResultImages: this.capabilities.vision,
|
|
@@ -510,6 +504,7 @@ class AISDKEngine {
|
|
|
510
504
|
if (this.requestFetch)
|
|
511
505
|
config.fetch = this.requestFetch;
|
|
512
506
|
if (this.provider === "openrouter") {
|
|
507
|
+
config.fetch = createOpenRouterToolFetch(this.requestFetch);
|
|
513
508
|
if (this.appName)
|
|
514
509
|
config.appName = this.appName;
|
|
515
510
|
if (this.appUrl)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type BuilderGatewayLane } from "../../server/credential-provider.js";
|
|
2
2
|
import type { AgentEngine, EngineCapabilities } from "./types.js";
|
|
3
3
|
export declare const BUILDER_CAPABILITIES: EngineCapabilities;
|
|
4
|
-
export declare const BUILDER_SUPPORTED_MODELS: readonly ["auto", "claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5-5", "gpt-5-4", "gpt-5-5", "gpt-5-4-mini", "gpt-5-1-codex-mini", "gpt-6.1-sol", "gpt-5-6-terra", "gpt-6-luna", "gemini-3-1-pro", "gemini-3-8-flash", "gemini-3-5-flash-lite", "gemini-3-1-flash-lite", "qwen3-coder", "kimi-k2-5", "deepseek-v3-1", "z-ai-glm-4-5", "z-ai-glm-5-1"];
|
|
4
|
+
export declare const BUILDER_SUPPORTED_MODELS: readonly ["auto", "claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5-5", "gpt-5-4", "gpt-5-5", "gpt-5-4-mini", "gpt-5-1-codex-mini", "gpt-6.1-sol", "gpt-5-6-terra", "gpt-6-luna", "gemini-3-1-pro", "gemini-3-8-flash", "gemini-3-5-flash-lite", "gemini-3-1-flash-lite", "qwen3-coder", "kimi-k2-5", "deepseek-v3-1", "deepseek-v4-1-flash", "z-ai-glm-4-5", "z-ai-glm-5-1", "z-ai-glm-5-3-flash"];
|
|
5
5
|
export declare const BUILDER_MODEL_UNAUTHORIZED_ERROR_CODE = "builder_model_unauthorized";
|
|
6
6
|
/**
|
|
7
7
|
* A truncated stream, not a rejected request: the client continues the partial
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createOpenRouterToolFetch(requestFetch?: typeof fetch): typeof fetch;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function createOpenRouterToolFetch(requestFetch = globalThis.fetch) {
|
|
2
|
+
return (input, init) => {
|
|
3
|
+
if (typeof init?.body !== "string")
|
|
4
|
+
return requestFetch(input, init);
|
|
5
|
+
const body = JSON.parse(init.body);
|
|
6
|
+
if (!body.tools?.length)
|
|
7
|
+
return requestFetch(input, init);
|
|
8
|
+
// Temporary adapter until OpenRouter's SDK forwards the standard tool.strict
|
|
9
|
+
// flag (still dropped in v3.1.0). Keep the wire regression when removing this.
|
|
10
|
+
return requestFetch(input, {
|
|
11
|
+
...init,
|
|
12
|
+
body: JSON.stringify({
|
|
13
|
+
...body,
|
|
14
|
+
tools: body.tools.map((tool) => tool.type === "function" && tool.function
|
|
15
|
+
? { ...tool, function: { ...tool.function, strict: false } }
|
|
16
|
+
: tool),
|
|
17
|
+
}),
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ProviderToolNameMap } from "./tool-name.js";
|
|
2
2
|
import type { EngineTool, EngineMessage, EngineContentPart, EngineEvent } from "./types.js";
|
|
3
|
-
export declare function engineToolsToAISDK(tools: EngineTool[], jsonSchema?: (schema: Record<string, unknown>) => unknown, toolNameMap?: ProviderToolNameMap
|
|
3
|
+
export declare function engineToolsToAISDK(tools: EngineTool[], jsonSchema?: (schema: Record<string, unknown>) => unknown, toolNameMap?: ProviderToolNameMap): Record<string, any>;
|
|
4
4
|
export interface EngineToAISDKOptions {
|
|
5
5
|
toolResultImages?: boolean;
|
|
6
6
|
toolNameMap?: ProviderToolNameMap;
|
|
@@ -2,7 +2,7 @@ import { classifyProviderError, describeErrorWithCauses, } from "./error-detail.
|
|
|
2
2
|
import { flattenComposedRootSchema } from "./flatten-composed-root-schema.js";
|
|
3
3
|
import { createProviderToolNameMap, toEngineToolName, toProviderToolName, } from "./tool-name.js";
|
|
4
4
|
import { backfillEngineMessagesToolResults } from "./translate-anthropic.js";
|
|
5
|
-
export function engineToolsToAISDK(tools, jsonSchema, toolNameMap = createProviderToolNameMap(tools)
|
|
5
|
+
export function engineToolsToAISDK(tools, jsonSchema, toolNameMap = createProviderToolNameMap(tools)) {
|
|
6
6
|
const result = {};
|
|
7
7
|
for (const tool of tools) {
|
|
8
8
|
const inputSchema = flattenComposedRootSchema(tool.inputSchema);
|
|
@@ -16,7 +16,8 @@ export function engineToolsToAISDK(tools, jsonSchema, toolNameMap = createProvid
|
|
|
16
16
|
result[providerName] = {
|
|
17
17
|
description: tool.description,
|
|
18
18
|
inputSchema: jsonSchema ? jsonSchema(rawSchema) : rawSchema,
|
|
19
|
-
|
|
19
|
+
// Gateways may normalize an omitted flag into required optional fields.
|
|
20
|
+
strict: false,
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
23
|
return result;
|
|
@@ -21,7 +21,7 @@ export declare const BUILDER_CLAUDE_SONNET_MODEL_LABEL = "Claude Sonnet 5";
|
|
|
21
21
|
export declare const AGENT_MODEL_CONFIG: {
|
|
22
22
|
readonly builder: {
|
|
23
23
|
readonly defaultModel: "gpt-6-luna";
|
|
24
|
-
readonly supportedModels: readonly ["auto", "claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5-5", "gpt-5-4", "gpt-5-5", "gpt-5-4-mini", "gpt-5-1-codex-mini", "gpt-6.1-sol", "gpt-5-6-terra", "gpt-6-luna", "gemini-3-1-pro", "gemini-3-8-flash", "gemini-3-5-flash-lite", "gemini-3-1-flash-lite", "qwen3-coder", "kimi-k2-5", "deepseek-v3-1", "z-ai-glm-4-5", "z-ai-glm-5-1"];
|
|
24
|
+
readonly supportedModels: readonly ["auto", "claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5-5", "gpt-5-4", "gpt-5-5", "gpt-5-4-mini", "gpt-5-1-codex-mini", "gpt-6.1-sol", "gpt-5-6-terra", "gpt-6-luna", "gemini-3-1-pro", "gemini-3-8-flash", "gemini-3-5-flash-lite", "gemini-3-1-flash-lite", "qwen3-coder", "kimi-k2-5", "deepseek-v3-1", "deepseek-v4-1-flash", "z-ai-glm-4-5", "z-ai-glm-5-1", "z-ai-glm-5-3-flash"];
|
|
25
25
|
};
|
|
26
26
|
readonly anthropic: {
|
|
27
27
|
readonly defaultModel: "claude-sonnet-5-5";
|
|
@@ -64,7 +64,7 @@ export declare const AGENT_MODEL_CONFIG: {
|
|
|
64
64
|
};
|
|
65
65
|
export declare const BUILDER_MODEL_CONFIG: {
|
|
66
66
|
readonly defaultModel: "gpt-6-luna";
|
|
67
|
-
readonly supportedModels: readonly ["auto", "claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5-5", "gpt-5-4", "gpt-5-5", "gpt-5-4-mini", "gpt-5-1-codex-mini", "gpt-6.1-sol", "gpt-5-6-terra", "gpt-6-luna", "gemini-3-1-pro", "gemini-3-8-flash", "gemini-3-5-flash-lite", "gemini-3-1-flash-lite", "qwen3-coder", "kimi-k2-5", "deepseek-v3-1", "z-ai-glm-4-5", "z-ai-glm-5-1"];
|
|
67
|
+
readonly supportedModels: readonly ["auto", "claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5-5", "gpt-5-4", "gpt-5-5", "gpt-5-4-mini", "gpt-5-1-codex-mini", "gpt-6.1-sol", "gpt-5-6-terra", "gpt-6-luna", "gemini-3-1-pro", "gemini-3-8-flash", "gemini-3-5-flash-lite", "gemini-3-1-flash-lite", "qwen3-coder", "kimi-k2-5", "deepseek-v3-1", "deepseek-v4-1-flash", "z-ai-glm-4-5", "z-ai-glm-5-1", "z-ai-glm-5-3-flash"];
|
|
68
68
|
};
|
|
69
69
|
export declare const ANTHROPIC_MODEL_CONFIG: {
|
|
70
70
|
readonly defaultModel: "claude-sonnet-5-5";
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
// Typed against the Builder catalog: the classifier runs on the gateway, so a
|
|
3
|
+
// retired id must break the build instead of every classification.
|
|
4
|
+
const DEFAULT_INFERRED_SENTIMENT_MODEL = "gpt-6-luna";
|
|
2
5
|
export const observabilityConfig = z.object({
|
|
3
6
|
release: z
|
|
4
7
|
.string()
|
|
@@ -101,7 +104,11 @@ export const observabilityConfig = z.object({
|
|
|
101
104
|
inferredSentimentSampleRate: z.number().min(0).max(1).optional().meta({
|
|
102
105
|
doc: "Deterministic fraction of eligible user messages to classify, 0 to 1.",
|
|
103
106
|
}),
|
|
104
|
-
inferredSentimentModel: z
|
|
107
|
+
inferredSentimentModel: z
|
|
108
|
+
.string()
|
|
109
|
+
.min(1)
|
|
110
|
+
.default(DEFAULT_INFERRED_SENTIMENT_MODEL)
|
|
111
|
+
.meta({
|
|
105
112
|
doc: "Model used by the managed sentiment classifier.",
|
|
106
113
|
}),
|
|
107
114
|
});
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { serializeAnalyticsAnonymousIdCookie } from "../shared/analytics-anonymous-id.js";
|
|
2
|
+
import { ANALYTICS_SESSION_ID_COOKIE_NAME, ANALYTICS_SESSION_ID_MAX_LENGTH, normalizeAnalyticsSessionId, serializeAnalyticsSessionIdCookie, } from "../shared/analytics-session-id.js";
|
|
2
3
|
const ANONYMOUS_ID_STORAGE_KEY = "agent-native.anonymous_id";
|
|
3
4
|
const SESSION_ID_STORAGE_KEY = "agent-native.session_id";
|
|
4
5
|
const SESSION_ID_PIN_STORAGE_KEY = "agent-native.session_id_pin";
|
|
5
6
|
const SESSION_LAST_ACTIVITY_STORAGE_KEY = "agent-native.session_last_activity";
|
|
6
7
|
const SESSION_IDLE_TIMEOUT_MS = 30 * 60 * 1000;
|
|
7
|
-
const MAX_SESSION_ID_LENGTH = 127;
|
|
8
|
-
const SAFE_SESSION_ID = /^[!-~]+$/;
|
|
9
8
|
function generateVisitorId() {
|
|
10
9
|
try {
|
|
11
10
|
if (typeof crypto !== "undefined" &&
|
|
@@ -56,6 +55,17 @@ function syncAnalyticsAnonymousIdCookie(id) {
|
|
|
56
55
|
// remains the browser-side source of truth in that case.
|
|
57
56
|
}
|
|
58
57
|
}
|
|
58
|
+
function syncAnalyticsSessionIdCookie(id) {
|
|
59
|
+
try {
|
|
60
|
+
const cookie = serializeAnalyticsSessionIdCookie(id);
|
|
61
|
+
if (cookie)
|
|
62
|
+
document.cookie = cookie;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// coercion-ok: cookie access is optional and cannot block analytics.
|
|
66
|
+
// Local storage remains the browser-side source of truth when cookies are unavailable.
|
|
67
|
+
}
|
|
68
|
+
}
|
|
59
69
|
let pageLoadId;
|
|
60
70
|
/** One id for this page load, shared by every pageview until it reloads. */
|
|
61
71
|
export function getAnalyticsPageLoadId() {
|
|
@@ -74,17 +84,16 @@ export function getOrCreateAnalyticsAnonymousId() {
|
|
|
74
84
|
return id;
|
|
75
85
|
}
|
|
76
86
|
export function setAnalyticsSessionId(sessionId) {
|
|
77
|
-
const trimmed =
|
|
78
|
-
if (!trimmed
|
|
79
|
-
|
|
80
|
-
!SAFE_SESSION_ID.test(trimmed)) {
|
|
81
|
-
throw new Error(`Invalid analytics session id: expected 1-${MAX_SESSION_ID_LENGTH} printable ASCII characters with no whitespace`);
|
|
87
|
+
const trimmed = normalizeAnalyticsSessionId(sessionId);
|
|
88
|
+
if (!trimmed) {
|
|
89
|
+
throw new Error(`Invalid analytics session id: expected 1-${ANALYTICS_SESSION_ID_MAX_LENGTH} printable ASCII characters with no whitespace`);
|
|
82
90
|
}
|
|
83
91
|
if (typeof window === "undefined")
|
|
84
92
|
return undefined;
|
|
85
93
|
safeStorageSet(SESSION_ID_PIN_STORAGE_KEY, trimmed);
|
|
86
94
|
safeStorageSet(SESSION_ID_STORAGE_KEY, trimmed);
|
|
87
95
|
safeStorageSet(SESSION_LAST_ACTIVITY_STORAGE_KEY, String(Date.now()));
|
|
96
|
+
syncAnalyticsSessionIdCookie(trimmed);
|
|
88
97
|
return trimmed;
|
|
89
98
|
}
|
|
90
99
|
export function clearAnalyticsSessionId() {
|
|
@@ -93,6 +102,13 @@ export function clearAnalyticsSessionId() {
|
|
|
93
102
|
safeStorageRemove(SESSION_ID_PIN_STORAGE_KEY);
|
|
94
103
|
safeStorageRemove(SESSION_ID_STORAGE_KEY);
|
|
95
104
|
safeStorageRemove(SESSION_LAST_ACTIVITY_STORAGE_KEY);
|
|
105
|
+
try {
|
|
106
|
+
document.cookie = `${ANALYTICS_SESSION_ID_COOKIE_NAME}=; path=/; max-age=0; SameSite=Lax`;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// coercion-ok: cookie access is optional and cannot block analytics.
|
|
110
|
+
// Local storage remains the browser-side source of truth when cookies are unavailable.
|
|
111
|
+
}
|
|
96
112
|
}
|
|
97
113
|
export function getOrCreateAnalyticsSessionId() {
|
|
98
114
|
if (typeof window === "undefined")
|
|
@@ -102,6 +118,7 @@ export function getOrCreateAnalyticsSessionId() {
|
|
|
102
118
|
if (pinned) {
|
|
103
119
|
safeStorageSet(SESSION_ID_STORAGE_KEY, pinned);
|
|
104
120
|
safeStorageSet(SESSION_LAST_ACTIVITY_STORAGE_KEY, String(now));
|
|
121
|
+
syncAnalyticsSessionIdCookie(pinned);
|
|
105
122
|
return pinned;
|
|
106
123
|
}
|
|
107
124
|
const lastActivityRaw = safeStorageGet(SESSION_LAST_ACTIVITY_STORAGE_KEY);
|
|
@@ -117,5 +134,6 @@ export function getOrCreateAnalyticsSessionId() {
|
|
|
117
134
|
safeStorageSet(SESSION_ID_STORAGE_KEY, id);
|
|
118
135
|
}
|
|
119
136
|
safeStorageSet(SESSION_LAST_ACTIVITY_STORAGE_KEY, String(now));
|
|
137
|
+
syncAnalyticsSessionIdCookie(id);
|
|
120
138
|
return id;
|
|
121
139
|
}
|
|
@@ -166,6 +166,15 @@ function setRuntimeRunIdMetadata(metadata, runtimeRunId) {
|
|
|
166
166
|
else
|
|
167
167
|
observability.runtimeRunId = runtimeRunId;
|
|
168
168
|
}
|
|
169
|
+
function setRuntimeTurnIdMetadata(metadata, runtimeTurnId) {
|
|
170
|
+
const observability = agentNativeMetadata(metadata)?.observability;
|
|
171
|
+
if (!observability)
|
|
172
|
+
return;
|
|
173
|
+
if (runtimeTurnId === undefined)
|
|
174
|
+
delete observability.turnId;
|
|
175
|
+
else
|
|
176
|
+
observability.turnId = runtimeTurnId;
|
|
177
|
+
}
|
|
169
178
|
function objectReference(value) {
|
|
170
179
|
const object = asRecord(value);
|
|
171
180
|
if (!object ||
|
|
@@ -1215,13 +1224,14 @@ export function createAgentKitProtocolAdapter(runtime, options = {}) {
|
|
|
1215
1224
|
...(turn.runId === undefined ? {} : { runtimeRunId: turn.runId }),
|
|
1216
1225
|
runtimeId: runtime.id,
|
|
1217
1226
|
sessionId: session.id,
|
|
1218
|
-
turnId: turn.id,
|
|
1227
|
+
...(turn.id === undefined ? {} : { turnId: turn.id }),
|
|
1219
1228
|
threadId,
|
|
1220
1229
|
...observability,
|
|
1221
1230
|
},
|
|
1222
1231
|
},
|
|
1223
1232
|
});
|
|
1224
1233
|
setRuntimeRunIdMetadata(runMetadata, turn.runId);
|
|
1234
|
+
setRuntimeTurnIdMetadata(runMetadata, turn.id);
|
|
1225
1235
|
const run = {
|
|
1226
1236
|
runId,
|
|
1227
1237
|
threadId,
|
|
@@ -3056,13 +3066,14 @@ export function createAgentKitProtocolAdapter(runtime, options = {}) {
|
|
|
3056
3066
|
: { runtimeRunId: nextTurn.runId }),
|
|
3057
3067
|
runtimeId: runtime.id,
|
|
3058
3068
|
sessionId: run.session.id,
|
|
3059
|
-
turnId: nextTurn.id,
|
|
3069
|
+
...(nextTurn.id === undefined ? {} : { turnId: nextTurn.id }),
|
|
3060
3070
|
threadId: input.threadId,
|
|
3061
3071
|
interruptedRunId: run.runId,
|
|
3062
3072
|
},
|
|
3063
3073
|
},
|
|
3064
3074
|
});
|
|
3065
3075
|
setRuntimeRunIdMetadata(replacementMetadata, nextTurn.runId);
|
|
3076
|
+
setRuntimeTurnIdMetadata(replacementMetadata, nextTurn.id);
|
|
3066
3077
|
const replacementRun = {
|
|
3067
3078
|
runId: nextRunId,
|
|
3068
3079
|
threadId: input.threadId,
|
package/dist/client/url-scrub.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { AGENT_ACCESS_PARAM } from "../shared/agent-access.js";
|
|
1
2
|
/**
|
|
2
3
|
* Query parameters that may carry sensitive values in the URL bar. Browser
|
|
3
4
|
* telemetry and feedback integrations must not copy OAuth codes, share tokens,
|
|
4
|
-
* password params, email-confirm tokens,
|
|
5
|
-
* systems. Callers may opt into additional
|
|
5
|
+
* password params, email-confirm tokens, signed agent-access links, or similar
|
|
6
|
+
* secrets into downstream systems. Callers may opt into additional
|
|
7
|
+
* app-specific query parameters.
|
|
6
8
|
*/
|
|
7
9
|
const SENSITIVE_QUERY_PARAMS = new Set([
|
|
8
10
|
"password",
|
|
@@ -13,6 +15,7 @@ const SENSITIVE_QUERY_PARAMS = new Set([
|
|
|
13
15
|
"share",
|
|
14
16
|
"share_token",
|
|
15
17
|
"bridge",
|
|
18
|
+
AGENT_ACCESS_PARAM,
|
|
16
19
|
]);
|
|
17
20
|
export function scrubUrl(url, additionalSensitiveParams = []) {
|
|
18
21
|
if (!url || typeof url !== "string")
|
package/dist/deploy/build.js
CHANGED
|
@@ -26,6 +26,7 @@ import { AGENT_NATIVE_SOCIAL_IMAGE_ALT, AGENT_NATIVE_SOCIAL_IMAGE_CACHE_BUSTER,
|
|
|
26
26
|
import { workspaceAppAudienceFromEnv, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromEnv, workspaceAppRouteAccessFromPackageJson, } from "../shared/workspace-app-audience.js";
|
|
27
27
|
import { generateActionRegistryForProject } from "../vite/action-types-plugin.js";
|
|
28
28
|
import { createAgentNativeConfigContext, loadResolvedAgentNativeConfig, readAgentNativeBuildConfigMarker, resolveFirstRunOnboardingBuildReplacement, resolveHarnessBuildReplacement, } from "../vite/agent-native-config-loader.js";
|
|
29
|
+
import { createSentryServerSourceMapUploadPlugins } from "../vite/sentry-source-maps.js";
|
|
29
30
|
import { cloneServerBundleForFunction, copyDir, pruneSsrIslandFromRewritingClone, readPackageManifest, SERVERLESS_BROWSER_RUNTIME_PACKAGES, } from "./function-bundle.js";
|
|
30
31
|
import { collectImmutableAssetPaths, IMMUTABLE_ASSET_CACHE_CONTROL, IMMUTABLE_ASSET_CACHE_HEADERS, prefixAssetPath, } from "./immutable-assets.js";
|
|
31
32
|
import { writeNetlifyStaticHeaders } from "./netlify-static-headers.js";
|
|
@@ -4240,6 +4241,7 @@ export default bundle;
|
|
|
4240
4241
|
const providedPluginsNitroPlugin = await writeProvidedPluginsNitroPlugin();
|
|
4241
4242
|
const awsLambdaStreaming = isAwsLambdaStreamingBuild(preset, nitroEnvironment);
|
|
4242
4243
|
const nitroServerCodeSplittingConfig = nitroServerCodeSplittingConfigForPreset(preset);
|
|
4244
|
+
const sentryServerSourceMapPlugins = await createSentryServerSourceMapUploadPlugins(nitroEnvironment);
|
|
4243
4245
|
const nitroVirtual = {
|
|
4244
4246
|
"virtual:agents-bundle": agentsBundleModuleSource,
|
|
4245
4247
|
};
|
|
@@ -4260,6 +4262,14 @@ export default bundle;
|
|
|
4260
4262
|
...(isAwsLambdaPreset(preset) ? { awsLambda: { streaming: false } } : {}),
|
|
4261
4263
|
baseURL: appBasePath || "/",
|
|
4262
4264
|
minify: true,
|
|
4265
|
+
...(sentryServerSourceMapPlugins.length > 0
|
|
4266
|
+
? {
|
|
4267
|
+
sourcemap: "hidden",
|
|
4268
|
+
// Nitro strips sourcesContent by default; the maps never ship, so
|
|
4269
|
+
// keep it for Sentry to show source context.
|
|
4270
|
+
experimental: { sourcemapMinify: false },
|
|
4271
|
+
}
|
|
4272
|
+
: {}),
|
|
4263
4273
|
serverDir: "./server",
|
|
4264
4274
|
ignore: NITRO_RUNTIME_IGNORE_PATTERNS,
|
|
4265
4275
|
alias: {
|
|
@@ -4286,6 +4296,7 @@ export default bundle;
|
|
|
4286
4296
|
? [createCloudflareModuleStubPlugin()]
|
|
4287
4297
|
: []),
|
|
4288
4298
|
createBrowserOnlyServerStubPlugin(),
|
|
4299
|
+
...sentryServerSourceMapPlugins,
|
|
4289
4300
|
...(enterpriseAuthAdaptersEnabled
|
|
4290
4301
|
? []
|
|
4291
4302
|
: [createEnterpriseAuthAdapterStubPlugin(false)]),
|
|
@@ -33,20 +33,20 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
33
33
|
idempotencyKey: string;
|
|
34
34
|
deleted: boolean;
|
|
35
35
|
} | {
|
|
36
|
+
id?: undefined;
|
|
36
37
|
error: string;
|
|
37
38
|
url?: undefined;
|
|
38
|
-
id?: undefined;
|
|
39
39
|
provider?: undefined;
|
|
40
40
|
configured?: undefined;
|
|
41
41
|
} | {
|
|
42
42
|
url: string;
|
|
43
43
|
id: string;
|
|
44
44
|
provider: string;
|
|
45
|
-
error?: undefined;
|
|
46
45
|
configured?: undefined;
|
|
46
|
+
error?: undefined;
|
|
47
47
|
} | {
|
|
48
|
-
url?: undefined;
|
|
49
48
|
id?: undefined;
|
|
49
|
+
url?: undefined;
|
|
50
50
|
provider?: undefined;
|
|
51
51
|
error: string;
|
|
52
52
|
configured: boolean;
|
|
@@ -6,6 +6,7 @@ import { actionsToEngineTools, filterInitialEngineTools, resolveOwnerEngineApiKe
|
|
|
6
6
|
import { runAgentLoopDirectWithSoftTimeout } from "../agent/run-loop-with-resume.js";
|
|
7
7
|
import { abortRun, resolveBackgroundAutomationSoftTimeoutMs, resolveBackgroundRunHardTimeoutMs, startRun, } from "../agent/run-manager.js";
|
|
8
8
|
import { claimBackgroundRun, insertRun } from "../agent/run-store.js";
|
|
9
|
+
import { buildCurrentTimeUserContext, buildRuntimeContextPrompt, } from "../agent/runtime-context.js";
|
|
9
10
|
import { buildAssistantMessage, buildUserMessage, extractThreadMeta, foldAssistantTurn, upsertUserMessage, } from "../agent/thread-data-builder.js";
|
|
10
11
|
import { attachToolSearch } from "../agent/tool-search.js";
|
|
11
12
|
import { lookupOwnerAccount, resolveAutomationExecutionIdentity, } from "../automations/service.js";
|
|
@@ -19,6 +20,7 @@ import { runWithRequestContext, } from "../server/request-context.js";
|
|
|
19
20
|
import { normalizeReasoningEffortForRequest } from "../shared/reasoning-effort.js";
|
|
20
21
|
import automationNoOpAction, { AUTOMATION_NO_OP_TOOL, automationNoOpSchema, } from "./actions/automation-no-op.js";
|
|
21
22
|
import { applyAutomationFailure, automationOwnerKind, classifyAutomationFailure, CONFIG_INVALID_ERROR_CODE, MISSING_TOOLS_ERROR_CODE, OWNER_MISSING_ERROR_CODE, pausedMessage, withDeliveryNote, } from "./automation-outcome.js";
|
|
23
|
+
import { effectiveTimezone } from "./cron.js";
|
|
22
24
|
import { recoveredFactoryOwnerOrgId, } from "./frontmatter.js";
|
|
23
25
|
import { attachAutomationRunThread, finishAutomationRun, startAutomationRun, } from "./run-history.js";
|
|
24
26
|
export const BACKGROUND_RUN_HARD_TIMEOUT_MS = 10 * 60_000;
|
|
@@ -645,16 +647,25 @@ async function executeBackgroundAutomation(options, deps, historyId, runIdRef) {
|
|
|
645
647
|
: Math.max(1, options.hardDeadlineAt - Date.now()));
|
|
646
648
|
await new Promise((resolve, reject) => {
|
|
647
649
|
const activeRun = startRun(runId, thread.id, async (send, signal, control) => {
|
|
650
|
+
const runtimeContext = {
|
|
651
|
+
now: new Date(),
|
|
652
|
+
timezone: effectiveTimezone(automation.meta.timezone),
|
|
653
|
+
};
|
|
648
654
|
const loopOpts = {
|
|
649
655
|
engine,
|
|
650
656
|
model,
|
|
651
|
-
systemPrompt,
|
|
657
|
+
systemPrompt: systemPrompt + buildRuntimeContextPrompt(runtimeContext),
|
|
652
658
|
tools,
|
|
653
659
|
availableTools,
|
|
654
660
|
messages: [
|
|
655
661
|
{
|
|
656
662
|
role: "user",
|
|
657
|
-
content: [
|
|
663
|
+
content: [
|
|
664
|
+
{
|
|
665
|
+
type: "text",
|
|
666
|
+
text: prompt + buildCurrentTimeUserContext(runtimeContext),
|
|
667
|
+
},
|
|
668
|
+
],
|
|
658
669
|
},
|
|
659
670
|
],
|
|
660
671
|
actions,
|
package/dist/mcp/build-server.js
CHANGED
|
@@ -2584,6 +2584,9 @@ async function verifyA2AJwtForMcp(token, resourceUrl) {
|
|
|
2584
2584
|
if (globalSecret) {
|
|
2585
2585
|
const payload = await verifyWithSecret(globalSecret);
|
|
2586
2586
|
if (payload) {
|
|
2587
|
+
const tokenScope = typeof payload.scope === "string" ? payload.scope : undefined;
|
|
2588
|
+
const firstPartyMcp = payload.agent_native_first_party_mcp === true;
|
|
2589
|
+
const locallyIssuedConnectToken = tokenScope === MCP_CONNECT_SCOPE && !firstPartyMcp;
|
|
2587
2590
|
if (orgDomain) {
|
|
2588
2591
|
let organization;
|
|
2589
2592
|
try {
|
|
@@ -2594,17 +2597,17 @@ async function verifyA2AJwtForMcp(token, resourceUrl) {
|
|
|
2594
2597
|
catch (error) {
|
|
2595
2598
|
throw new McpIdentityVerificationUnavailableError(error);
|
|
2596
2599
|
}
|
|
2597
|
-
|
|
2600
|
+
// Locally issued connect identities are admitted below only after
|
|
2601
|
+
// their active JTI row confirms the stored owner and organization.
|
|
2602
|
+
if (organization?.secret.trim() === globalSecret &&
|
|
2603
|
+
!locallyIssuedConnectToken) {
|
|
2598
2604
|
return organizationPrincipalClaims(payload, organization);
|
|
2599
2605
|
}
|
|
2600
2606
|
}
|
|
2601
|
-
const tokenScope = typeof payload.scope === "string" ? payload.scope : undefined;
|
|
2602
|
-
const firstPartyMcp = payload.agent_native_first_party_mcp === true;
|
|
2603
2607
|
const hasOrganizationClaim = Object.prototype.hasOwnProperty.call(payload, "org_id") &&
|
|
2604
2608
|
payload.org_id !== null;
|
|
2605
2609
|
const hasOrganizationDomainClaim = Object.prototype.hasOwnProperty.call(payload, "org_domain") &&
|
|
2606
2610
|
payload.org_domain !== null;
|
|
2607
|
-
const locallyIssuedConnectToken = tokenScope === MCP_CONNECT_SCOPE && !firstPartyMcp;
|
|
2608
2611
|
const unclaimedFirstPartyToken = firstPartyMcp && !hasOrganizationClaim && !hasOrganizationDomainClaim;
|
|
2609
2612
|
if (locallyIssuedConnectToken || unclaimedFirstPartyToken) {
|
|
2610
2613
|
return payload;
|
|
@@ -533,9 +533,9 @@ function renderConnectPage(params) {
|
|
|
533
533
|
.advanced { margin: 0 0 1rem; }
|
|
534
534
|
.advanced > summary {
|
|
535
535
|
list-style: none; cursor: pointer; user-select: none;
|
|
536
|
-
display: flex; align-items: center; justify-content:
|
|
536
|
+
display: flex; align-items: center; justify-content: space-between; gap: 0.35rem;
|
|
537
537
|
color: var(--subtle); font-size: 0.8rem; font-weight: 500;
|
|
538
|
-
padding: 0.
|
|
538
|
+
padding: 0.65rem 0; text-align: left;
|
|
539
539
|
}
|
|
540
540
|
.advanced > summary::-webkit-details-marker { display: none; }
|
|
541
541
|
.advanced > summary:hover { color: var(--muted); }
|
|
@@ -544,7 +544,8 @@ function renderConnectPage(params) {
|
|
|
544
544
|
.advanced > summary .chev {
|
|
545
545
|
width: 7px; height: 7px; border-right: 1.5px solid currentColor;
|
|
546
546
|
border-bottom: 1.5px solid currentColor; transform: rotate(45deg);
|
|
547
|
-
transition: transform 0.15s ease; margin
|
|
547
|
+
transition: transform 0.15s ease; margin: -3px 0.25rem 0 auto;
|
|
548
|
+
flex: 0 0 auto;
|
|
548
549
|
}
|
|
549
550
|
.advanced[open] > summary .chev { transform: rotate(225deg); margin-top: 2px; }
|
|
550
551
|
.advanced-body {
|
|
@@ -577,13 +578,13 @@ function renderConnectPage(params) {
|
|
|
577
578
|
box-shadow: 0 0 0 3px rgba(250,250,250,0.12);
|
|
578
579
|
}
|
|
579
580
|
.connections {
|
|
580
|
-
margin-top:
|
|
581
|
-
padding-top: 0.35rem;
|
|
581
|
+
margin-top: 0; border-top: 1px solid var(--border);
|
|
582
582
|
}
|
|
583
583
|
.connections > summary {
|
|
584
584
|
list-style: none; cursor: pointer; user-select: none;
|
|
585
585
|
display: flex; align-items: center; gap: 0.55rem;
|
|
586
|
-
min-height: 2.
|
|
586
|
+
min-height: 2.75rem; padding: 0.65rem 0;
|
|
587
|
+
color: var(--muted); font-size: 0.82rem;
|
|
587
588
|
}
|
|
588
589
|
.connections > summary::-webkit-details-marker { display: none; }
|
|
589
590
|
.connections > summary:focus-visible {
|
|
@@ -597,8 +598,12 @@ function renderConnectPage(params) {
|
|
|
597
598
|
.connections .chev {
|
|
598
599
|
width: 7px; height: 7px; border-right: 1.5px solid currentColor;
|
|
599
600
|
border-bottom: 1.5px solid currentColor; transform: rotate(45deg);
|
|
600
|
-
transition: transform 0.15s ease; margin: -3px 0 0
|
|
601
|
+
transition: transform 0.15s ease; margin: -3px 0 0 auto;
|
|
601
602
|
}
|
|
603
|
+
.connections > summary > .connections-state:not(.hidden) + .chev {
|
|
604
|
+
margin-left: 0.15rem;
|
|
605
|
+
}
|
|
606
|
+
.connections > summary > .chev { margin-right: 0.25rem; }
|
|
602
607
|
.connections[open] .chev { transform: rotate(225deg); margin-top: 2px; }
|
|
603
608
|
.token-list { padding-top: 0.4rem; }
|
|
604
609
|
.tok { display: flex; align-items: center; justify-content: space-between;
|
|
@@ -663,13 +668,13 @@ function renderConnectPage(params) {
|
|
|
663
668
|
}
|
|
664
669
|
.url-row .ghost { flex: 0 0 auto; }
|
|
665
670
|
.hosts {
|
|
666
|
-
margin: 0
|
|
667
|
-
border-bottom: 1px solid var(--border); padding: 0.35rem 0;
|
|
671
|
+
margin: 0; border-top: 1px solid var(--border);
|
|
668
672
|
}
|
|
669
673
|
.hosts > summary {
|
|
670
674
|
list-style: none; cursor: pointer; user-select: none;
|
|
671
675
|
display: flex; align-items: center; gap: 0.55rem;
|
|
672
|
-
min-height: 2.
|
|
676
|
+
min-height: 2.75rem; padding: 0.65rem 0;
|
|
677
|
+
color: var(--muted); font-size: 0.82rem;
|
|
673
678
|
}
|
|
674
679
|
.hosts > summary::-webkit-details-marker { display: none; }
|
|
675
680
|
.hosts > summary:focus-visible {
|
|
@@ -678,7 +683,7 @@ function renderConnectPage(params) {
|
|
|
678
683
|
.hosts > summary .chev {
|
|
679
684
|
width: 7px; height: 7px; border-right: 1.5px solid currentColor;
|
|
680
685
|
border-bottom: 1.5px solid currentColor; transform: rotate(45deg);
|
|
681
|
-
transition: transform 0.15s ease; margin: -3px 0 0 0.15rem;
|
|
686
|
+
transition: transform 0.15s ease; margin: -3px 0.25rem 0 0.15rem;
|
|
682
687
|
}
|
|
683
688
|
.hosts[open] > summary .chev { transform: rotate(225deg); margin-top: 2px; }
|
|
684
689
|
.hosts-body { padding: 0.15rem 0 0.25rem; }
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
export declare function createNotificationsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<"" | import("./types.js").Notification[] | {
|
|
2
2
|
count: number;
|
|
3
3
|
updated?: undefined;
|
|
4
|
-
error?: undefined;
|
|
5
4
|
ok?: undefined;
|
|
5
|
+
error?: undefined;
|
|
6
6
|
} | {
|
|
7
7
|
count?: undefined;
|
|
8
8
|
updated: number;
|
|
9
|
-
error?: undefined;
|
|
10
9
|
ok?: undefined;
|
|
10
|
+
error?: undefined;
|
|
11
11
|
} | {
|
|
12
12
|
count?: undefined;
|
|
13
13
|
updated?: undefined;
|