@agent-native/core 0.212.0-nightly-20261021064625 → 0.212.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/app-profile.d.ts +4 -0
- package/dist/a2a/app-profile.js +95 -0
- package/dist/a2a/server.d.ts +1 -0
- package/dist/a2a/server.js +45 -6
- package/dist/a2a/types.d.ts +6 -0
- package/dist/agent/jev-tool-prefetch.d.ts +6 -0
- package/dist/agent/jev-tool-prefetch.js +18 -0
- package/dist/agent/production-agent.js +30 -1
- package/dist/automation/index.d.ts +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/index.d.ts +1 -1
- package/dist/collab/index.js +0 -1
- package/dist/deploy/workspace-deploy.js +33 -1
- package/dist/extensions/url-safety.js +3 -5
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/adapters/slack.js +142 -14
- package/dist/integrations/webhook-handler.js +42 -1
- package/dist/jobs/background-automation-runner.d.ts +7 -0
- package/dist/jobs/background-automation-runner.js +13 -1
- package/dist/mcp/org-directory.d.ts +9 -4
- package/dist/mcp/org-directory.js +117 -29
- package/dist/notifications/routes.d.ts +5 -5
- package/dist/observability/routes.d.ts +9 -9
- package/dist/org/context.d.ts +1 -0
- package/dist/org/context.js +11 -0
- package/dist/org/handlers.js +62 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +4 -4
- package/dist/resources/metadata.d.ts +2 -0
- package/dist/resources/metadata.js +27 -1
- package/dist/scripts/call-agent.js +44 -3
- package/dist/scripts/describe-workspace-apps.js +36 -4
- package/dist/secrets/routes.d.ts +4 -4
- package/dist/server/agent-chat/action-filters-a2a.d.ts +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +1 -0
- package/dist/server/agent-chat/prompt-resources.d.ts +16 -0
- package/dist/server/agent-chat/prompt-resources.js +290 -54
- package/dist/server/agent-chat-plugin.d.ts +2 -0
- package/dist/server/agent-chat-plugin.js +51 -7
- package/dist/server/agent-discovery.d.ts +36 -3
- package/dist/server/agent-discovery.js +397 -39
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-default-model-route.d.ts +2 -2
- package/dist/server/request-context.d.ts +9 -0
- package/dist/server/workspace-app-selection.d.ts +19 -0
- package/dist/server/workspace-app-selection.js +141 -0
- package/dist/shared/agent-profile.d.ts +25 -0
- package/dist/shared/agent-profile.js +73 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -0
- package/dist/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +4 -2
- package/dist/templates/factory/.agents/skills/review-prs/SKILL.md +5 -2
- package/migration-manifest.json +0 -6
- package/package.json +5 -4
- package/src/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +4 -2
- package/src/templates/factory/.agents/skills/review-prs/SKILL.md +5 -2
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AgentProfileMetadata } from "../shared/agent-profile.js";
|
|
2
|
+
import type { AgentSkill } from "./types.js";
|
|
3
|
+
/** Add app examples only to the one skill whose own wording clearly matches. */
|
|
4
|
+
export declare function addAgentProfileExamples<T extends AgentSkill>(skills: T[], profile: AgentProfileMetadata | null): T[];
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
const PROFILE_EXAMPLE_STOP_WORDS = new Set([
|
|
2
|
+
"a",
|
|
3
|
+
"an",
|
|
4
|
+
"and",
|
|
5
|
+
"for",
|
|
6
|
+
"from",
|
|
7
|
+
"in",
|
|
8
|
+
"into",
|
|
9
|
+
"me",
|
|
10
|
+
"my",
|
|
11
|
+
"of",
|
|
12
|
+
"on",
|
|
13
|
+
"or",
|
|
14
|
+
"the",
|
|
15
|
+
"this",
|
|
16
|
+
"to",
|
|
17
|
+
"with",
|
|
18
|
+
]);
|
|
19
|
+
const PROFILE_WORD_ALIASES = {
|
|
20
|
+
build: "generate",
|
|
21
|
+
create: "generate",
|
|
22
|
+
link: "url",
|
|
23
|
+
make: "generate",
|
|
24
|
+
};
|
|
25
|
+
const manifestExamples = new WeakMap();
|
|
26
|
+
function profileWords(value) {
|
|
27
|
+
return new Set(value
|
|
28
|
+
.toLowerCase()
|
|
29
|
+
.split(/[^a-z0-9]+/)
|
|
30
|
+
.filter((word) => word && !PROFILE_EXAMPLE_STOP_WORDS.has(word))
|
|
31
|
+
.map((word) => PROFILE_WORD_ALIASES[word] ?? word));
|
|
32
|
+
}
|
|
33
|
+
/** Add app examples only to the one skill whose own wording clearly matches. */
|
|
34
|
+
export function addAgentProfileExamples(skills, profile) {
|
|
35
|
+
if (!skills.length)
|
|
36
|
+
return skills;
|
|
37
|
+
const manifestSkills = skills.map((skill) => {
|
|
38
|
+
const examples = manifestExamples.get(skill);
|
|
39
|
+
if (examples === undefined && !manifestExamples.has(skill))
|
|
40
|
+
return skill;
|
|
41
|
+
const { examples: _derivedExamples, ...rest } = skill;
|
|
42
|
+
return {
|
|
43
|
+
...rest,
|
|
44
|
+
...(examples ? { examples } : {}),
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
if (!profile?.whenToUse?.length)
|
|
48
|
+
return manifestSkills;
|
|
49
|
+
const examplesBySkill = new Map();
|
|
50
|
+
for (const example of profile.whenToUse) {
|
|
51
|
+
const words = profileWords(example);
|
|
52
|
+
let bestSkill;
|
|
53
|
+
let bestScore = 0;
|
|
54
|
+
let runnerUpScore = 0;
|
|
55
|
+
let tied = false;
|
|
56
|
+
for (const skill of manifestSkills) {
|
|
57
|
+
const skillWords = profileWords(`${skill.id} ${skill.name} ${skill.description}`);
|
|
58
|
+
let score = 0;
|
|
59
|
+
for (const word of words)
|
|
60
|
+
if (skillWords.has(word))
|
|
61
|
+
score += 1;
|
|
62
|
+
if (score > bestScore) {
|
|
63
|
+
runnerUpScore = bestScore;
|
|
64
|
+
bestSkill = skill;
|
|
65
|
+
bestScore = score;
|
|
66
|
+
tied = false;
|
|
67
|
+
}
|
|
68
|
+
else if (score === bestScore && score > 1) {
|
|
69
|
+
tied = true;
|
|
70
|
+
}
|
|
71
|
+
else if (score > runnerUpScore) {
|
|
72
|
+
runnerUpScore = score;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (!bestSkill || tied || bestScore - runnerUpScore < 2)
|
|
76
|
+
continue;
|
|
77
|
+
const examples = examplesBySkill.get(bestSkill.id) ?? [];
|
|
78
|
+
examples.push(example);
|
|
79
|
+
examplesBySkill.set(bestSkill.id, examples);
|
|
80
|
+
}
|
|
81
|
+
return manifestSkills.map((skill) => {
|
|
82
|
+
const examples = examplesBySkill.get(skill.id);
|
|
83
|
+
if (!examples?.length)
|
|
84
|
+
return skill;
|
|
85
|
+
const updated = {
|
|
86
|
+
...skill,
|
|
87
|
+
examples: [
|
|
88
|
+
...(skill.examples ?? []),
|
|
89
|
+
...examples.filter((example) => !skill.examples?.includes(example)),
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
manifestExamples.set(updated, skill.examples);
|
|
93
|
+
return updated;
|
|
94
|
+
});
|
|
95
|
+
}
|
package/dist/a2a/server.d.ts
CHANGED
|
@@ -47,6 +47,7 @@ export declare function verifyA2AToken(token: string, event?: any, audienceOptio
|
|
|
47
47
|
globalSecretOnly?: boolean;
|
|
48
48
|
/** Only use this explicitly configured credential; never fall back. */
|
|
49
49
|
verificationSecret?: string;
|
|
50
|
+
requireAudience?: boolean;
|
|
50
51
|
}): Promise<A2ATokenPayload>;
|
|
51
52
|
export type A2ATokenFailureCause = "malformed" | "secret-missing" | "audience-unresolvable" | "audience" | "issuer" | "expired" | "signature" | "invalid-claims" | "mcp-credential" | "missing-subject" | "org-binding" | "org-lookup-failed" | "undetermined";
|
|
52
53
|
/**
|
package/dist/a2a/server.js
CHANGED
|
@@ -15,6 +15,7 @@ import { publicFrameworkPath } from "../server/framework-route-prefix.js";
|
|
|
15
15
|
import { readBody } from "../server/h3-helpers.js";
|
|
16
16
|
import { isSameOriginRequest } from "../server/request-origin.js";
|
|
17
17
|
import { generateAgentCard } from "./agent-card.js";
|
|
18
|
+
import { addAgentProfileExamples } from "./app-profile.js";
|
|
18
19
|
import { canonicalA2AAudience } from "./audience.js";
|
|
19
20
|
import { hasConfiguredA2ASecret, isA2AProductionRuntime, } from "./auth-policy.js";
|
|
20
21
|
import { handleJsonRpcH3, processA2ATaskFromQueue } from "./handlers.js";
|
|
@@ -301,8 +302,12 @@ async function verifyA2ATokenInternal(token, event, audienceOptions) {
|
|
|
301
302
|
// it was minted from", which `jose.jwtVerify` validates exactly when
|
|
302
303
|
// `issuer` is supplied as a string. Backward-compat: when the token
|
|
303
304
|
// has no `iss`, we skip the check.
|
|
305
|
+
const hasAudience = unverifiedPayload && typeof unverifiedPayload.aud !== "undefined";
|
|
306
|
+
if (audienceOptions?.requireAudience && !hasAudience) {
|
|
307
|
+
return { payload: { email: null, orgDomain: null } };
|
|
308
|
+
}
|
|
304
309
|
const verifyOptions = {};
|
|
305
|
-
if (
|
|
310
|
+
if (hasAudience) {
|
|
306
311
|
// Fail closed: the token was minted for a specific audience, but this
|
|
307
312
|
// receiver can't derive its own expected audience (no APP_URL/URL and no
|
|
308
313
|
// usable request host). Accepting here would let a correctly-signed token
|
|
@@ -416,12 +421,17 @@ export function mountA2A(nitroApp, config, routePrefix = "/_agent-native") {
|
|
|
416
421
|
setResponseStatus(event, 405);
|
|
417
422
|
return { error: "Method not allowed" };
|
|
418
423
|
}
|
|
424
|
+
setResponseHeader(event, "cache-control", "private, no-store");
|
|
419
425
|
const protocol = getRequestHeader(event, "x-forwarded-proto") ||
|
|
420
426
|
(event.url?.protocol?.replace(":", "") ?? "http");
|
|
421
427
|
const host = getRequestHeader(event, "host") ?? "localhost";
|
|
422
428
|
const baseUrl = `${protocol}://${host}`;
|
|
423
429
|
let skills = filterPublicAgentCardSkills(config);
|
|
424
|
-
|
|
430
|
+
let description = config.description;
|
|
431
|
+
let profileResolved = false;
|
|
432
|
+
if (config.authenticatedSkills?.length ||
|
|
433
|
+
config.resolveAuthenticatedProfile ||
|
|
434
|
+
config.resolvePublicProfile) {
|
|
425
435
|
const bearer = extractBearerToken(getRequestHeader(event, "authorization"));
|
|
426
436
|
if (bearer) {
|
|
427
437
|
try {
|
|
@@ -430,9 +440,26 @@ export function mountA2A(nitroApp, config, routePrefix = "/_agent-native") {
|
|
|
430
440
|
allowBaseAudience: true,
|
|
431
441
|
});
|
|
432
442
|
if (payload.email) {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
443
|
+
if (config.authenticatedSkills?.length) {
|
|
444
|
+
skills = tokenHasAudienceClaim(bearer)
|
|
445
|
+
? config.authenticatedSkills
|
|
446
|
+
: config.authenticatedSkills.filter((skill) => !isDirectReadSkill(skill));
|
|
447
|
+
}
|
|
448
|
+
let profile;
|
|
449
|
+
try {
|
|
450
|
+
profile = await config.resolveAuthenticatedProfile?.({
|
|
451
|
+
userEmail: payload.email,
|
|
452
|
+
...(payload.orgId ? { orgId: payload.orgId } : {}),
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
catch {
|
|
456
|
+
console.warn("[a2a] authenticated profile resolution failed");
|
|
457
|
+
}
|
|
458
|
+
if (profile) {
|
|
459
|
+
description = profile.description ?? description;
|
|
460
|
+
skills = addAgentProfileExamples(skills, profile);
|
|
461
|
+
profileResolved = true;
|
|
462
|
+
}
|
|
436
463
|
}
|
|
437
464
|
}
|
|
438
465
|
catch (error) {
|
|
@@ -446,7 +473,19 @@ export function mountA2A(nitroApp, config, routePrefix = "/_agent-native") {
|
|
|
446
473
|
}
|
|
447
474
|
}
|
|
448
475
|
}
|
|
449
|
-
|
|
476
|
+
if (!profileResolved) {
|
|
477
|
+
try {
|
|
478
|
+
const profile = await config.resolvePublicProfile?.();
|
|
479
|
+
if (profile) {
|
|
480
|
+
description = profile.description ?? description;
|
|
481
|
+
skills = addAgentProfileExamples(skills, profile);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
catch {
|
|
485
|
+
console.warn("[a2a] public profile resolution failed");
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return generateAgentCard({ ...config, description, skills }, baseUrl, publicFrameworkPath(`${routePrefix}/a2a`));
|
|
450
489
|
}));
|
|
451
490
|
// Human-only continuation for consequential A2A tool calls. The opaque id
|
|
452
491
|
// is a lookup handle, not authorization: every read and mutation also
|
package/dist/a2a/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PublicAgentActionConfig } from "../action.js";
|
|
2
|
+
import type { AgentProfileMetadata } from "../shared/agent-profile.js";
|
|
2
3
|
export type { A2AAgentActivityPhase, A2AAgentActivitySnapshot, A2AAgentActivityState, A2AAgentActivityToolCall, A2AAgentActivityToolStatus, } from "./activity.js";
|
|
3
4
|
export interface TextPart {
|
|
4
5
|
type: "text";
|
|
@@ -191,6 +192,11 @@ export interface A2AConfig {
|
|
|
191
192
|
version?: string;
|
|
192
193
|
skills: AgentSkill[];
|
|
193
194
|
authenticatedSkills?: AgentSkill[];
|
|
195
|
+
resolvePublicProfile?: () => Promise<AgentProfileMetadata>;
|
|
196
|
+
resolveAuthenticatedProfile?: (identity: {
|
|
197
|
+
userEmail: string;
|
|
198
|
+
orgId?: string;
|
|
199
|
+
}) => Promise<AgentProfileMetadata>;
|
|
194
200
|
publicSkillsOnly?: boolean;
|
|
195
201
|
handler?: A2AHandler;
|
|
196
202
|
apiKeyEnv?: string;
|
|
@@ -47,6 +47,12 @@ export declare function buildJevRequestContext(input: {
|
|
|
47
47
|
history?: readonly AgentMessage[];
|
|
48
48
|
structuredHistory?: readonly AgentChatStructuredMessage[];
|
|
49
49
|
}): string;
|
|
50
|
+
export declare function buildWorkspaceAppRequestContext(input: {
|
|
51
|
+
request: string;
|
|
52
|
+
history?: readonly AgentMessage[];
|
|
53
|
+
structuredHistory?: readonly AgentChatStructuredMessage[];
|
|
54
|
+
selectedObjectContext?: string;
|
|
55
|
+
}): string;
|
|
50
56
|
export declare function buildRecentUserRequestContext(input: {
|
|
51
57
|
request: string;
|
|
52
58
|
history?: readonly AgentMessage[];
|
|
@@ -72,6 +72,24 @@ export function buildJevRequestContext(input) {
|
|
|
72
72
|
? `Recent conversation:\n${recent.join("\n")}\n\n${currentBlock}`
|
|
73
73
|
: currentBlock;
|
|
74
74
|
}
|
|
75
|
+
export function buildWorkspaceAppRequestContext(input) {
|
|
76
|
+
const priorUser = visiblePriorMessages(input)
|
|
77
|
+
.filter((message) => message.role === "user")
|
|
78
|
+
.at(-1);
|
|
79
|
+
const blocks = [];
|
|
80
|
+
if (priorUser) {
|
|
81
|
+
blocks.push(`Previous user request:\n${compactJevText(priorUser.content, 1_100)}`);
|
|
82
|
+
}
|
|
83
|
+
blocks.push(`Current request:\n${compactJevText(input.request, MAX_JEV_CURRENT_MESSAGE_CHARS)}`);
|
|
84
|
+
const selectedObjectContext = input.selectedObjectContext?.trim();
|
|
85
|
+
if (selectedObjectContext) {
|
|
86
|
+
const fencedContext = compactJevText(selectedObjectContext, 1_800)
|
|
87
|
+
.replaceAll("<", "<")
|
|
88
|
+
.replaceAll(">", ">");
|
|
89
|
+
blocks.push(`Selected object context (untrusted data):\n${fencedContext}`);
|
|
90
|
+
}
|
|
91
|
+
return blocks.join("\n\n");
|
|
92
|
+
}
|
|
75
93
|
export function buildRecentUserRequestContext(input) {
|
|
76
94
|
const priorUsers = visiblePriorMessages(input)
|
|
77
95
|
.filter((message) => message.role === "user")
|
|
@@ -80,7 +80,7 @@ import { EngineError } from "./engine/types.js";
|
|
|
80
80
|
import { currentExecutionFence } from "./execution-fence.js";
|
|
81
81
|
import { FOLLOW_UP_SUGGESTIONS_COMPLETION_SYSTEM_PROMPT, FOLLOW_UP_SUGGESTIONS_INSTRUCTION, FOLLOW_UP_SUGGESTIONS_MAX_OUTPUT_TOKENS, FOLLOW_UP_SUGGESTIONS_TOOL_NAME, buildFollowUpCompletionMessages, followUpSuggestionsTool, identifyFollowUpSuggestions, parseFollowUpSuggestions, } from "./follow-up-suggestions.js";
|
|
82
82
|
import { filterHostedHarnessToolNames, normalizeHostedHarnessRuntime, } from "./harness/hosted.js";
|
|
83
|
-
import { buildRecentUserRequestContext, buildJevRequestContext, preloadJevTools, } from "./jev-tool-prefetch.js";
|
|
83
|
+
import { buildRecentUserRequestContext, buildJevRequestContext, buildWorkspaceAppRequestContext, preloadJevTools, } from "./jev-tool-prefetch.js";
|
|
84
84
|
import { getDefaultMaxIterations, getDefaultMaxRunInputTokens, MAX_AGENT_MAX_ITERATIONS, MIN_AGENT_MAX_ITERATIONS, normalizeMaxIterations, normalizeMaxRunInputTokens, readAgentLoopSettings, } from "./loop-settings.js";
|
|
85
85
|
import { getContextWindowForModel, resolveFallbackModel, } from "./model-config.js";
|
|
86
86
|
import { maybeCompactThread, buildObservationalContext, hasObservationalMemory, serializeObservationalMemoryBlock, } from "./observational-memory/index.js";
|
|
@@ -9693,6 +9693,9 @@ export function createProductionAgentHandler(options) {
|
|
|
9693
9693
|
userEmail: ownerEmail ?? getRequestUserEmail() ?? null,
|
|
9694
9694
|
orgId: getRequestOrgId() ?? null,
|
|
9695
9695
|
}).catch(() => readAgentLoopSettings({}));
|
|
9696
|
+
const promptRunContext = ensureRequestRunContext();
|
|
9697
|
+
if (promptRunContext)
|
|
9698
|
+
promptRunContext.appDiscoveryQuery = requestMessage;
|
|
9696
9699
|
let systemPromptError = null;
|
|
9697
9700
|
const systemPromptThunk = () => (async () => {
|
|
9698
9701
|
const sysPromptStart = Date.now();
|
|
@@ -10016,6 +10019,12 @@ export function createProductionAgentHandler(options) {
|
|
|
10016
10019
|
withoutUnavailableNote(screenBlock) +
|
|
10017
10020
|
withoutUnavailableNote(urlBlock) +
|
|
10018
10021
|
withoutUnavailableNote(selectionBlock);
|
|
10022
|
+
const workspaceAppRequest = buildWorkspaceAppRequestContext({
|
|
10023
|
+
request: requestMessage,
|
|
10024
|
+
history: requestHistory,
|
|
10025
|
+
structuredHistory: requestStructuredHistory,
|
|
10026
|
+
selectedObjectContext: withoutUnavailableNote(selectionBlock),
|
|
10027
|
+
});
|
|
10019
10028
|
const screenStatus = worstContextStatus(...Object.values(screenStatuses));
|
|
10020
10029
|
const surfacedActionRegistry = requestMode === "plan"
|
|
10021
10030
|
? createPlanModeActionRegistry(surfacedRequestActions)
|
|
@@ -10056,7 +10065,10 @@ export function createProductionAgentHandler(options) {
|
|
|
10056
10065
|
}),
|
|
10057
10066
|
preloadJevContextWithStatus({
|
|
10058
10067
|
request: jevRequestContext,
|
|
10068
|
+
appRequest: workspaceAppRequest,
|
|
10059
10069
|
appId: options.appId,
|
|
10070
|
+
selfAppId: options.appId,
|
|
10071
|
+
workspaceAppsEnabled: Boolean(requestActions["call-agent"]),
|
|
10060
10072
|
owner: ownerEmail ?? undefined,
|
|
10061
10073
|
orgId: getRequestOrgId() ?? null,
|
|
10062
10074
|
apiKey: jevContextCredentials.apiKey,
|
|
@@ -10074,6 +10086,12 @@ export function createProductionAgentHandler(options) {
|
|
|
10074
10086
|
const jevContext = jevPreload.context;
|
|
10075
10087
|
if (jevContext)
|
|
10076
10088
|
systemPrompt = `${systemPrompt}\n\n${jevContext}`;
|
|
10089
|
+
if (jevPreload.relevantAppsContext) {
|
|
10090
|
+
systemPrompt = `${systemPrompt}\n\n${jevPreload.relevantAppsContext}`;
|
|
10091
|
+
}
|
|
10092
|
+
if (runContext && jevPreload.appSelection) {
|
|
10093
|
+
runContext.appDiscoverySelection = jevPreload.appSelection;
|
|
10094
|
+
}
|
|
10077
10095
|
const prefetchStatus = worstContextStatus(jevPreload.status, preparedReferenceStatus);
|
|
10078
10096
|
if (runContext) {
|
|
10079
10097
|
runContext.contextStatus = {
|
|
@@ -10101,6 +10119,17 @@ export function createProductionAgentHandler(options) {
|
|
|
10101
10119
|
},
|
|
10102
10120
|
])
|
|
10103
10121
|
: []),
|
|
10122
|
+
...(jevPreload.relevantAppsContext
|
|
10123
|
+
? await buildSystemManifestSections([
|
|
10124
|
+
{
|
|
10125
|
+
label: "Relevant workspace apps",
|
|
10126
|
+
provenance: "runtime-context",
|
|
10127
|
+
governance: "inherited",
|
|
10128
|
+
content: jevPreload.relevantAppsContext,
|
|
10129
|
+
sourceRef: { scope: "workspace-apps" },
|
|
10130
|
+
},
|
|
10131
|
+
])
|
|
10132
|
+
: []),
|
|
10104
10133
|
...(requestTools.length > 0
|
|
10105
10134
|
? await buildSystemManifestSections([
|
|
10106
10135
|
{
|
|
@@ -139,8 +139,8 @@ export declare function createAutomationCallbackHandler(runtime: AutomationRunti
|
|
|
139
139
|
duplicate?: undefined;
|
|
140
140
|
eventId?: undefined;
|
|
141
141
|
} | {
|
|
142
|
-
error?: undefined;
|
|
143
142
|
accepted: boolean;
|
|
144
143
|
duplicate: boolean;
|
|
145
144
|
eventId: string;
|
|
145
|
+
error?: undefined;
|
|
146
146
|
}>;
|
|
@@ -38,19 +38,19 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
|
|
|
38
38
|
error: string;
|
|
39
39
|
states?: undefined;
|
|
40
40
|
} | {
|
|
41
|
+
error?: undefined;
|
|
41
42
|
states: {
|
|
42
43
|
clientId: number;
|
|
43
44
|
state: string;
|
|
44
45
|
}[];
|
|
45
|
-
error?: undefined;
|
|
46
46
|
}>>;
|
|
47
47
|
export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
48
48
|
error: string;
|
|
49
49
|
users?: undefined;
|
|
50
50
|
} | {
|
|
51
|
+
error?: undefined;
|
|
51
52
|
users: {
|
|
52
53
|
clientId: number;
|
|
53
54
|
lastSeen: number;
|
|
54
55
|
}[];
|
|
55
|
-
error?: undefined;
|
|
56
56
|
}>>;
|
package/dist/collab/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { loadYDocState, loadYDocVersion, hasCollabState, deleteCollabState, uint8ArrayToBase64, base64ToUint8Array, strictBase64ToUint8Array, CollabStateMalformedError, type CollabStateMalformedReason, } from "./storage.js";
|
|
2
2
|
export { createBoundedTaskRunner, measureBoundedPayload, BoundedTaskError, BOUNDED_TASK_GLOBAL, type BoundedTaskErrorCode, type BoundedTaskRunner, type BoundedTaskRunnerOptions, type BoundedTaskRunnerStats, type BoundedTaskSource, } from "./bounded-tasks.js";
|
|
3
|
-
export {
|
|
3
|
+
export type { BundleBoundedTaskSourceOptions, BundledBoundedTaskSource, } from "./bounded-task-bundle.js";
|
|
4
4
|
export { defineLiveCopy, releaseLiveCopy, LiveCopyError, LIVE_COPY_DEFAULT_FIELD, type LiveCopyBinding, type LiveCopyCommit, type LiveCopyErrorCode, type LiveCopyOptions, type LiveCopyOutcome, type LiveCopyPersistOutcome, } from "./live-copy.js";
|
|
5
5
|
export { CollabBaseVersionConflictError, getDoc, saveYDocState, withPreparedYDocMutation, applyUpdate, seedXmlFragmentIfEmpty, applyText, getText, getState, getIncUpdate, seedFromText, releaseDoc, searchAndReplace, applyJson, applyPatchOps, getJson, seedFromJson, readLiveCopy, mutateLiveCopy, seedLiveCopy, type PreparedYDocMutationLease, type LiveCopyRead, type MutateLiveCopyOptions, type LiveCopyCallChange, type LiveCopyMutationResult, type SeedLiveCopyOptions, type LiveCopySeedResult, } from "./ydoc-manager.js";
|
|
6
6
|
export { searchAndReplaceInYXml, extractTextFromYXml } from "./xml-ops.js";
|
package/dist/collab/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export { loadYDocState, loadYDocVersion, hasCollabState, deleteCollabState, uint8ArrayToBase64, base64ToUint8Array, strictBase64ToUint8Array, CollabStateMalformedError, } from "./storage.js";
|
|
2
2
|
export { createBoundedTaskRunner, measureBoundedPayload, BoundedTaskError, BOUNDED_TASK_GLOBAL, } from "./bounded-tasks.js";
|
|
3
|
-
export { bundleBoundedTaskSource, } from "./bounded-task-bundle.js";
|
|
4
3
|
export { defineLiveCopy, releaseLiveCopy, LiveCopyError, LIVE_COPY_DEFAULT_FIELD, } from "./live-copy.js";
|
|
5
4
|
export { CollabBaseVersionConflictError, getDoc, saveYDocState, withPreparedYDocMutation, applyUpdate, seedXmlFragmentIfEmpty, applyText, getText, getState, getIncUpdate, seedFromText, releaseDoc, searchAndReplace, applyJson, applyPatchOps, getJson, seedFromJson, readLiveCopy, mutateLiveCopy, seedLiveCopy, } from "./ydoc-manager.js";
|
|
6
5
|
export { searchAndReplaceInYXml, extractTextFromYXml } from "./xml-ops.js";
|
|
@@ -8,6 +8,7 @@ import { INTEGRATION_RECOVERY_RUNTIME_MARKER, INTEGRATION_RETRY_SWEEP_PATH, INTE
|
|
|
8
8
|
import { RECURRING_JOBS_SWEEP_PATH, RECURRING_JOBS_SWEEP_TOKEN_SUBJECT, } from "../jobs/scheduler-dispatch.js";
|
|
9
9
|
import { findWorkspaceRoot } from "../scripts/utils.js";
|
|
10
10
|
import { BUILTIN_AGENTS_ENV_KEY, workspaceBuiltinAgentsJson, } from "../server/builtin-agents.js";
|
|
11
|
+
import { parseAgentProfileMetadataFields } from "../shared/agent-profile.js";
|
|
11
12
|
import { normalizeFrameworkRoutePrefix } from "../shared/framework-route-prefix.js";
|
|
12
13
|
import { DEFAULT_WORKSPACE_APP_AUDIENCE, normalizeWorkspaceAppHomePath, normalizeWorkspaceAppAudience, normalizeWorkspaceAppPathList, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromPackageJson, } from "../shared/workspace-app-audience.js";
|
|
13
14
|
import { DISPATCH_WORKSPACE_ROOT_REDIRECTS, isValidWorkspaceAppIdFormat, } from "../shared/workspace-app-id.js";
|
|
@@ -1412,10 +1413,41 @@ async function readWorkspaceAppManifest(workspaceRoot, apps, appsDir) {
|
|
|
1412
1413
|
const packageRouteAccess = workspaceAppRouteAccessFromPackageJson(pkg);
|
|
1413
1414
|
const publicPaths = packageRouteAccess.publicPaths ?? explicit?.publicPaths ?? [];
|
|
1414
1415
|
const protectedPaths = packageRouteAccess.protectedPaths ?? explicit?.protectedPaths ?? [];
|
|
1416
|
+
const agentNative = pkg?.["agent-native"];
|
|
1417
|
+
const profile = parseAgentProfileMetadataFields({
|
|
1418
|
+
description: pkg?.description,
|
|
1419
|
+
...(agentNative &&
|
|
1420
|
+
typeof agentNative === "object" &&
|
|
1421
|
+
("whenToUse" in agentNative || "aliases" in agentNative)
|
|
1422
|
+
? {
|
|
1423
|
+
...("whenToUse" in agentNative
|
|
1424
|
+
? { whenToUse: agentNative.whenToUse }
|
|
1425
|
+
: {}),
|
|
1426
|
+
...("aliases" in agentNative
|
|
1427
|
+
? { aliases: agentNative.aliases }
|
|
1428
|
+
: {}),
|
|
1429
|
+
}
|
|
1430
|
+
: {}),
|
|
1431
|
+
});
|
|
1432
|
+
if (profile.invalidFields.length) {
|
|
1433
|
+
console.warn(`[workspace] Ignoring invalid agent profile metadata in ${app}: ${profile.invalidFields.join(", ")}`);
|
|
1434
|
+
}
|
|
1415
1435
|
entries.push({
|
|
1416
1436
|
id: app,
|
|
1417
1437
|
name: pkg?.displayName || titleCase(app),
|
|
1418
|
-
description:
|
|
1438
|
+
description: profile.metadata.description ?? "",
|
|
1439
|
+
...(profile.metadata.whenToUse || profile.metadata.aliases
|
|
1440
|
+
? {
|
|
1441
|
+
"agent-native": {
|
|
1442
|
+
...(profile.metadata.whenToUse
|
|
1443
|
+
? { whenToUse: profile.metadata.whenToUse }
|
|
1444
|
+
: {}),
|
|
1445
|
+
...(profile.metadata.aliases
|
|
1446
|
+
? { aliases: profile.metadata.aliases }
|
|
1447
|
+
: {}),
|
|
1448
|
+
},
|
|
1449
|
+
}
|
|
1450
|
+
: {}),
|
|
1419
1451
|
path: appPath,
|
|
1420
1452
|
homePath: normalizeWorkspaceAppHomePath(explicit?.homePath ??
|
|
1421
1453
|
configuredHomePath ??
|
|
@@ -26,12 +26,10 @@ function isPrivateIpv4(a, b, c = 0, d = 0) {
|
|
|
26
26
|
return true;
|
|
27
27
|
if (a === 100 && b >= 64 && b <= 127)
|
|
28
28
|
return true;
|
|
29
|
-
if (a === 192 && b === 0)
|
|
29
|
+
if (a === 192 && b === 0 && (c === 0 || c === 2))
|
|
30
30
|
return true;
|
|
31
31
|
if (a === 198 && (b === 18 || b === 19))
|
|
32
32
|
return true;
|
|
33
|
-
if (a === 192 && b === 0 && c === 2)
|
|
34
|
-
return true;
|
|
35
33
|
if (a === 198 && b === 51 && c === 100)
|
|
36
34
|
return true;
|
|
37
35
|
if (a === 203 && b === 0 && c === 113)
|
|
@@ -64,9 +62,9 @@ function isPrivateHost(hostname) {
|
|
|
64
62
|
}
|
|
65
63
|
if (METADATA_HOSTS.includes(host))
|
|
66
64
|
return true;
|
|
67
|
-
if (/^f[cd]/.test(host) || /^fe[89ab]/.test(host))
|
|
65
|
+
if (host.includes(":") && (/^f[cd]/.test(host) || /^fe[89ab]/.test(host)))
|
|
68
66
|
return true;
|
|
69
|
-
if (/^ff/i.test(host))
|
|
67
|
+
if (host.includes(":") && /^ff/i.test(host))
|
|
70
68
|
return true;
|
|
71
69
|
const v4mappedDotted = host.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
|
|
72
70
|
if (v4mappedDotted) {
|