@agent-native/core 0.203.0 → 0.203.1-nightly-20261007183952
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/action.d.ts +34 -0
- package/dist/agent/clip-text.d.ts +4 -0
- package/dist/agent/clip-text.js +17 -0
- package/dist/agent/follow-up-suggestions.d.ts +16 -2
- package/dist/agent/follow-up-suggestions.js +69 -1
- package/dist/agent/production-agent.d.ts +20 -2
- package/dist/agent/production-agent.js +322 -132
- package/dist/agent/provider-model-selection.d.ts +21 -2
- package/dist/agent/provider-model-selection.js +19 -2
- package/dist/agent/run-loop-with-resume.js +2 -16
- package/dist/agent/tool-search.d.ts +31 -1
- package/dist/agent/tool-search.js +196 -15
- package/dist/agent/write-receipts.d.ts +27 -0
- package/dist/agent/write-receipts.js +181 -0
- package/dist/automation/index.d.ts +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/observability/routes.d.ts +6 -6
- package/dist/observability/trace-error.d.ts +5 -3
- package/dist/observability/trace-error.js +29 -4
- package/dist/observability/traces.js +6 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/provider-api.d.ts +2 -2
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +11 -11
- package/dist/server/action-routes.js +3 -0
- package/dist/server/agent-chat/prompt-resources.d.ts +13 -0
- package/dist/server/agent-chat/prompt-resources.js +21 -12
- package/dist/server/agent-chat-plugin.js +25 -9
- 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/email-auth-links.js +98 -2
- package/dist/server/embed-route.js +2 -1
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.js +3 -3
- package/dist/server/realtime-voice.js +2 -4
- package/dist/shared/embed-auth.d.ts +1 -0
- package/dist/shared/embed-auth.js +1 -0
- package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
- package/dist/templates/chat/.agents/skills/actions/SKILL.md +25 -0
- package/dist/templates/default/.agents/skills/actions/SKILL.md +25 -0
- package/dist/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +26 -39
- package/dist/templates/headless/.agents/skills/actions/SKILL.md +25 -0
- package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +25 -0
- package/package.json +3 -3
- package/src/templates/chat/.agents/skills/actions/SKILL.md +25 -0
- package/src/templates/default/.agents/skills/actions/SKILL.md +25 -0
- package/src/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +26 -39
- package/src/templates/headless/.agents/skills/actions/SKILL.md +25 -0
- package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +25 -0
package/dist/action.d.ts
CHANGED
|
@@ -36,6 +36,8 @@ export interface ActionRunContext {
|
|
|
36
36
|
attachments?: AgentChatAttachment[];
|
|
37
37
|
signal?: AbortSignal;
|
|
38
38
|
actionName?: string;
|
|
39
|
+
/** Present only on frontend GETs authorized by a scoped directory-widget read capability. */
|
|
40
|
+
mcpDirectoryWidgetReadOnly?: true;
|
|
39
41
|
threadId?: string;
|
|
40
42
|
runId?: string;
|
|
41
43
|
turnId?: string;
|
|
@@ -67,6 +69,38 @@ export interface FailOptions {
|
|
|
67
69
|
details?: Record<string, unknown>;
|
|
68
70
|
}
|
|
69
71
|
export declare function fail(message: string, options?: FailOptions): never;
|
|
72
|
+
/**
|
|
73
|
+
* What a write action verified about its own effect. An action opts in by
|
|
74
|
+
* returning a plain-object result with a reserved `_receipt: WriteReceipt`.
|
|
75
|
+
* The agent loop reads it before the result is stringified and truncated, so
|
|
76
|
+
* the final answer is reconciled with what the write did instead of with the
|
|
77
|
+
* model's reading of a JSON string.
|
|
78
|
+
*
|
|
79
|
+
* - `changed: false`: nothing was written (a no-op); not a completed side effect.
|
|
80
|
+
* - `verified: true`: the effect was observed. `false`: it was checked and did
|
|
81
|
+
* not hold. `"unverified"`: it could not be checked.
|
|
82
|
+
* - `subject`: the stable target of the write, such as a dashboard id. Later
|
|
83
|
+
* receipts from the same action with the same subject that are `changed` and
|
|
84
|
+
* `verified: true` supersede this one, so a no-op that was then fixed does
|
|
85
|
+
* not flag the answer. A receipt with failing checks is superseded only when
|
|
86
|
+
* those later receipts carry an `ok` check with the same `id` for every
|
|
87
|
+
* check that failed here, because a verified write speaks only for what it
|
|
88
|
+
* checked. Without a subject a receipt is never superseded.
|
|
89
|
+
* - Bounds, enforced by the loop: summary and subject 200 chars, 8 checks, 5
|
|
90
|
+
* warnings.
|
|
91
|
+
*/
|
|
92
|
+
export interface WriteReceipt {
|
|
93
|
+
changed: boolean;
|
|
94
|
+
verified: true | false | "unverified";
|
|
95
|
+
summary: string;
|
|
96
|
+
subject?: string;
|
|
97
|
+
checks?: Array<{
|
|
98
|
+
id: string;
|
|
99
|
+
ok: boolean;
|
|
100
|
+
detail?: string;
|
|
101
|
+
}>;
|
|
102
|
+
warnings?: string[];
|
|
103
|
+
}
|
|
70
104
|
export declare class AgentActionStopError extends Error {
|
|
71
105
|
readonly agentNativeStop = true;
|
|
72
106
|
readonly errorCode?: string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** At most the first `max` UTF-16 units of `text`, never ending inside a surrogate pair. */
|
|
2
|
+
export declare function clipHead(text: string, max: number): string;
|
|
3
|
+
/** At most the last `max` UTF-16 units of `text`, never starting inside a surrogate pair. */
|
|
4
|
+
export declare function clipTail(text: string, max: number): string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Provider APIs reject a request whose JSON holds half a surrogate pair, so a
|
|
2
|
+
// clip that lands inside an emoji must drop the half instead of keeping it.
|
|
3
|
+
const isHighSurrogate = (unit) => unit >= 0xd800 && unit <= 0xdbff;
|
|
4
|
+
const isLowSurrogate = (unit) => unit >= 0xdc00 && unit <= 0xdfff;
|
|
5
|
+
/** At most the first `max` UTF-16 units of `text`, never ending inside a surrogate pair. */
|
|
6
|
+
export function clipHead(text, max) {
|
|
7
|
+
if (text.length <= max)
|
|
8
|
+
return text;
|
|
9
|
+
return text.slice(0, isHighSurrogate(text.charCodeAt(max - 1)) ? max - 1 : max);
|
|
10
|
+
}
|
|
11
|
+
/** At most the last `max` UTF-16 units of `text`, never starting inside a surrogate pair. */
|
|
12
|
+
export function clipTail(text, max) {
|
|
13
|
+
if (text.length <= max)
|
|
14
|
+
return text;
|
|
15
|
+
const start = text.length - max;
|
|
16
|
+
return text.slice(isLowSurrogate(text.charCodeAt(start)) ? start + 1 : start);
|
|
17
|
+
}
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import type { AgentSuggestion } from "@agent-native/agentkit/protocol";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import type { EngineTool } from "./engine/types.js";
|
|
3
|
+
import type { EngineMessage, EngineTool } from "./engine/types.js";
|
|
4
4
|
export declare const FOLLOW_UP_SUGGESTIONS_TOOL_NAME = "suggest-follow-ups";
|
|
5
5
|
export declare const FOLLOW_UP_SUGGESTIONS_MAX_OUTPUT_TOKENS = 1024;
|
|
6
6
|
export declare const FOLLOW_UP_SUGGESTIONS_INSTRUCTION: string;
|
|
7
|
+
export declare const FOLLOW_UP_SUGGESTIONS_COMPLETION_SYSTEM_PROMPT = "You write follow-up suggestions for a conversation between a user and an AI agent inside an app. You only record them by calling suggest-follow-ups.";
|
|
7
8
|
export declare const FOLLOW_UP_SUGGESTIONS_COMPLETION_INSTRUCTION: string;
|
|
8
|
-
|
|
9
|
+
/**
|
|
10
|
+
* The completion call sends a different tools array than the turn did, so it
|
|
11
|
+
* can never read the turn's prompt cache. It carries a bounded digest of the
|
|
12
|
+
* turn instead of re-prefilling the whole conversation at full price. The
|
|
13
|
+
* digest keeps the shape of a finished turn (request, reply, then the
|
|
14
|
+
* instruction as the last user message) so role alternation is valid for every
|
|
15
|
+
* provider and the instruction stays the message a prefix match finds.
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildFollowUpCompletionMessages(input: {
|
|
18
|
+
requestText?: string;
|
|
19
|
+
replyText: string;
|
|
20
|
+
toolNames: readonly string[];
|
|
21
|
+
}): EngineMessage[];
|
|
22
|
+
export type FollowUpSuggestionsFailure = "budget_exhausted" | "iteration_limit" | "interrupted" | "processor_error" | "provider_error" | "invalid_or_missing";
|
|
9
23
|
declare const followUpSuggestionsSchema: z.ZodObject<{
|
|
10
24
|
suggestions: z.ZodArray<z.ZodObject<{
|
|
11
25
|
label: z.ZodString;
|
|
@@ -1,10 +1,78 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { clipHead, clipTail } from "./clip-text.js";
|
|
2
3
|
export const FOLLOW_UP_SUGGESTIONS_TOOL_NAME = "suggest-follow-ups";
|
|
3
4
|
export const FOLLOW_UP_SUGGESTIONS_MAX_OUTPUT_TOKENS = 1024;
|
|
4
5
|
export const FOLLOW_UP_SUGGESTIONS_INSTRUCTION = "Before finishing this turn, evaluate useful next actions grounded in the user's request, conversation, app workflow/current context, and observed results. " +
|
|
5
6
|
"Record your decision with suggest-follow-ups: zero to three meaningful next intents, or an empty list when none is warranted. Do not fill a quota or repeat completed work.";
|
|
6
|
-
export const
|
|
7
|
+
export const FOLLOW_UP_SUGGESTIONS_COMPLETION_SYSTEM_PROMPT = "You write follow-up suggestions for a conversation between a user and an AI agent inside an app. You only record them by calling suggest-follow-ups.";
|
|
8
|
+
export const FOLLOW_UP_SUGGESTIONS_COMPLETION_INSTRUCTION = "The final reply above has already been delivered. Complete only its missing follow-up metadata by calling suggest-follow-ups once, using the request, reply, and tools used above. " +
|
|
7
9
|
"An empty list is valid when no useful next action exists. Do not repeat the reply, perform more work, or call other tools.";
|
|
10
|
+
// The ask sits at the end of a long pasted document and a long reply's
|
|
11
|
+
// conclusions sit at the end, so a clip keeps the tail.
|
|
12
|
+
const COMPLETION_REQUEST_HEAD_CHARS = 500;
|
|
13
|
+
const COMPLETION_REQUEST_TAIL_CHARS = 1_500;
|
|
14
|
+
const COMPLETION_REPLY_TAIL_CHARS = 4_000;
|
|
15
|
+
const MAX_COMPLETION_TOOL_NAMES = 30;
|
|
16
|
+
function clipMiddle(text, head, tail) {
|
|
17
|
+
return text.length > head + tail
|
|
18
|
+
? `${clipHead(text, head)}\n…\n${clipTail(text, tail)}`
|
|
19
|
+
: text;
|
|
20
|
+
}
|
|
21
|
+
// Providers reject an empty first user message or an empty assistant text, so a
|
|
22
|
+
// turn with no request text or no reply text still sends a stated absence.
|
|
23
|
+
const NO_REQUEST_TEXT = "(No request text was recorded for this turn.)";
|
|
24
|
+
const NO_REPLY_TEXT = "(The reply had no text.)";
|
|
25
|
+
/**
|
|
26
|
+
* The completion call sends a different tools array than the turn did, so it
|
|
27
|
+
* can never read the turn's prompt cache. It carries a bounded digest of the
|
|
28
|
+
* turn instead of re-prefilling the whole conversation at full price. The
|
|
29
|
+
* digest keeps the shape of a finished turn (request, reply, then the
|
|
30
|
+
* instruction as the last user message) so role alternation is valid for every
|
|
31
|
+
* provider and the instruction stays the message a prefix match finds.
|
|
32
|
+
*/
|
|
33
|
+
export function buildFollowUpCompletionMessages(input) {
|
|
34
|
+
const requestText = input.requestText?.trim();
|
|
35
|
+
const replyText = input.replyText.trim();
|
|
36
|
+
const toolNames = [...new Set(input.toolNames)]
|
|
37
|
+
.filter((name) => name !== FOLLOW_UP_SUGGESTIONS_TOOL_NAME)
|
|
38
|
+
.slice(0, MAX_COMPLETION_TOOL_NAMES);
|
|
39
|
+
const request = [
|
|
40
|
+
requestText
|
|
41
|
+
? `<user-request>\n${clipMiddle(requestText, COMPLETION_REQUEST_HEAD_CHARS, COMPLETION_REQUEST_TAIL_CHARS)}\n</user-request>`
|
|
42
|
+
: "",
|
|
43
|
+
toolNames.length > 0
|
|
44
|
+
? `<tools-used>${toolNames.join(", ")}</tools-used>`
|
|
45
|
+
: "",
|
|
46
|
+
].filter(Boolean);
|
|
47
|
+
return [
|
|
48
|
+
{
|
|
49
|
+
role: "user",
|
|
50
|
+
content: [
|
|
51
|
+
{
|
|
52
|
+
type: "text",
|
|
53
|
+
text: request.length > 0 ? request.join("\n\n") : NO_REQUEST_TEXT,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
role: "assistant",
|
|
59
|
+
content: [
|
|
60
|
+
{
|
|
61
|
+
type: "text",
|
|
62
|
+
text: replyText
|
|
63
|
+
? clipMiddle(replyText, 0, COMPLETION_REPLY_TAIL_CHARS)
|
|
64
|
+
: NO_REPLY_TEXT,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
role: "user",
|
|
70
|
+
content: [
|
|
71
|
+
{ type: "text", text: FOLLOW_UP_SUGGESTIONS_COMPLETION_INSTRUCTION },
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
}
|
|
8
76
|
const followUpSuggestionsSchema = z
|
|
9
77
|
.strictObject({
|
|
10
78
|
suggestions: z
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { EventHandler as H3EventHandler } from "h3";
|
|
2
2
|
import "../authorization/check-action.js";
|
|
3
3
|
import type { Task } from "../a2a/types.js";
|
|
4
|
-
import { type ActionAutomationContext, type ActionCaller } from "../action.js";
|
|
4
|
+
import { type ActionAutomationContext, type ActionCaller, type WriteReceipt } from "../action.js";
|
|
5
5
|
import { type ArtifactReceipt } from "../artifacts/detect.js";
|
|
6
6
|
import type { AgentNativeHarnessSetting } from "../config.js";
|
|
7
7
|
import { type CredentialProvenance } from "../credentials/index.js";
|
|
@@ -19,6 +19,7 @@ import { subscribeToRun, getActiveRunForThread, getActiveRunForThreadAsync, getR
|
|
|
19
19
|
import type { ActiveRun } from "./run-manager.js";
|
|
20
20
|
import { type AgentTurnInitiator, insertRun, isTurnAborted, markRunAborted, updateRunHeartbeat, updateRunStatusIfRunning, setRunError, setRunTerminalReason, claimBackgroundRun, readBackgroundRunClaim, recordRunDiagnostic, countRunsForTurn } from "./run-store.js";
|
|
21
21
|
import { type AgentActionScope, ActionTool, AgentChatAttachment, AgentChatEvent, AgentFileMutationProof, AgentChatReference, AgentChatStructuredMessage } from "./types.js";
|
|
22
|
+
import { type ToolWriteReceipt } from "./write-receipts.js";
|
|
22
23
|
export { PROVIDER_TO_ENV };
|
|
23
24
|
/**
|
|
24
25
|
* Grace window + poll interval for the foreground circuit-breaker that confirms
|
|
@@ -394,6 +395,12 @@ export interface AgentLoopUsage {
|
|
|
394
395
|
engineName?: string;
|
|
395
396
|
model: string;
|
|
396
397
|
llmCalls?: number;
|
|
398
|
+
/** Wall time and input tokens of the end-of-turn follow-up suggestions call. */
|
|
399
|
+
followUpMs?: number;
|
|
400
|
+
followUpInputTokens?: number;
|
|
401
|
+
/** Write receipts this run with `verified` other than true / with `changed: false`. */
|
|
402
|
+
receiptUnverifiedCount?: number;
|
|
403
|
+
receiptChangedFalseCount?: number;
|
|
397
404
|
/**
|
|
398
405
|
* True once the engine reported at least one real `usage` event for this
|
|
399
406
|
* run. The token fields above start at 0 and are only ever incremented —
|
|
@@ -404,6 +411,12 @@ export interface AgentLoopUsage {
|
|
|
404
411
|
usageReported?: boolean;
|
|
405
412
|
firstEngineEventAtMs?: number;
|
|
406
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Folds one loop attempt's usage into a running total. Every wrapper that
|
|
416
|
+
* re-enters `runAgentLoop` merges through this, so a field added to
|
|
417
|
+
* `AgentLoopUsage` cannot be reported by the loop and dropped by a wrapper.
|
|
418
|
+
*/
|
|
419
|
+
export declare function mergeAgentLoopUsage(total: AgentLoopUsage, next: AgentLoopUsage): void;
|
|
407
420
|
export type AgentLoopOutcome = {
|
|
408
421
|
state: "completed";
|
|
409
422
|
} | {
|
|
@@ -428,7 +441,10 @@ export interface AgentLoopToolResultSummary {
|
|
|
428
441
|
content: string;
|
|
429
442
|
isError: boolean;
|
|
430
443
|
artifacts?: ArtifactReceipt[];
|
|
444
|
+
/** The action's `_receipt`, read before the result was truncated. */
|
|
445
|
+
receipt?: WriteReceipt;
|
|
431
446
|
}
|
|
447
|
+
export type { ToolWriteReceipt };
|
|
432
448
|
export interface AgentLoopFinalResponseGuardContext {
|
|
433
449
|
messages: EngineMessage[];
|
|
434
450
|
requestText?: string;
|
|
@@ -436,6 +452,8 @@ export interface AgentLoopFinalResponseGuardContext {
|
|
|
436
452
|
text: string;
|
|
437
453
|
toolCalls: AgentLoopToolCallSummary[];
|
|
438
454
|
toolResults: AgentLoopToolResultSummary[];
|
|
455
|
+
/** Every write receipt this turn; set by the loop, absent only in hand-built contexts. */
|
|
456
|
+
receipts?: ToolWriteReceipt[];
|
|
439
457
|
retryCount: number;
|
|
440
458
|
executionMode: AgentExecutionMode;
|
|
441
459
|
}
|
|
@@ -792,7 +810,7 @@ export declare function resolveAgentRequestReasoningEffort({ model, requestEffor
|
|
|
792
810
|
requestEffort?: unknown;
|
|
793
811
|
configuredEffort?: ReasoningEffort;
|
|
794
812
|
}): ReasoningEffort | undefined;
|
|
795
|
-
export type AgentModelSelectionSource = "request" | "configured" | "stored" | "default";
|
|
813
|
+
export type AgentModelSelectionSource = "request" | "configured" | "stored" | "default" | "provider-selection-fallback";
|
|
796
814
|
export declare function resolveAgentModelSelection(options: {
|
|
797
815
|
requestModel?: string | null;
|
|
798
816
|
configuredModel?: string | null;
|