Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/api-reference/veryfront/agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ Input delivered to a hosted agent-service detached execution callback.
| `buildRootOwnedChildRunResultHint` | Builds root owned child run result hint. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/child-run/result-summary.ts#L348) |
| `buildRootOwnedChildRunResultText` | Builds root owned child run result text. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/child-run/result-summary.ts#L333) |
| `buildRootOwnedDelegatedFindingsInstruction` | Builds root owned delegated findings instruction. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/conversation/delegation-policy.ts#L34) |
| `buildRuntimeAgentControlPlaneStreamRequestFromInvocation` | Builds runtime agent control plane stream request from invocation. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/agent-invocation-contract.ts#L452) |
| `buildRuntimeAgentControlPlaneStreamRequestFromInvocation` | Builds runtime agent control plane stream request from invocation. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/agent-invocation-contract.ts#L453) |
| `buildRuntimeAvailableSkillsPromptBlock` | Builds a bounded, injection-safe runtime available-skills prompt. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/skill-prompt.ts#L457) |
| `buildRuntimeLoadedSkillResponse` | Build a bounded loaded-skill response and fail closed on invalid metadata. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/skill-metadata.ts#L1097) |
| `buildRuntimeSkillDefinition` | Build a bounded, immutable runtime skill definition. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/skill-metadata.ts#L913) |
Expand Down Expand Up @@ -884,10 +884,10 @@ Input delivered to a hosted agent-service detached execution callback.
| `parseHostedAgentServiceConfig` | Configuration used by parse hosted agent service. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/service/config.ts#L167) |
| `parseHostedChatRequestFromRequest` | Request payload for parse hosted chat request from. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/hosted/chat-request-parser.ts#L593) |
| `parseRuntimeAgentMarkdownDefinition` | Definition for parse runtime agent markdown. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/agent-definition.ts#L192) |
| `parseRuntimeAgentRunInvocation` | Parses runtime agent run invocation. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/agent-invocation-contract.ts#L479) |
| `parseRuntimeAgentRunInvocation` | Parses runtime agent run invocation. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/agent-invocation-contract.ts#L481) |
| `parseRuntimeAgentRunInvocationAgentServiceChatRequestFromRequest` | Request payload for parse runtime agent run invocation hosted chat request from. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/hosted/chat-request-parser.ts#L632) |
| `parseRuntimeAgentRunInvocationHostedChatRequestFromRequest` | Request payload for parse runtime agent run invocation hosted chat request from. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/hosted/chat-request-parser.ts#L632) |
| `parseRuntimeAgentRunInvocationOrError` | Error shape for parse runtime agent run invocation or. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/agent-invocation-contract.ts#L486) |
| `parseRuntimeAgentRunInvocationOrError` | Error shape for parse runtime agent run invocation or. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/agent-invocation-contract.ts#L488) |
| `parseRuntimeSkillDocument` | Parses a bounded runtime skill document and fails closed on invalid input. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/skill-metadata.ts#L561) |
| `parseRuntimeSkillMetadata` | Parses bounded runtime skill metadata and fails closed on invalid input. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/skill-metadata.ts#L569) |
| `parseToolInputObject` | Parses tool input object. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/streaming/tool-input.ts#L135) |
Expand Down Expand Up @@ -1020,7 +1020,7 @@ Input delivered to a hosted agent-service detached execution callback.

| Name | Description | Source |
| ------------------------------------ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `AgentRuntime` | Implement agent runtime. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/index.ts#L1164) |
| `AgentRuntime` | Implement agent runtime. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/index.ts#L1197) |
| `AgentRuntimeMessageConversionError` | Error shape for agent runtime message conversion. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/runtime/message-adapter.ts#L138) |
| `AgentServiceAuthError` | Error shape for hosted service auth. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/service/auth.ts#L14) |
| `AppendConversationRunEventsError` | Error shape for append conversation run events. | [source](https://github.com/veryfront/veryfront-code/blob/main/src/agent/conversation/durable-append-errors.ts#L4) |
Expand Down
17 changes: 17 additions & 0 deletions src/agent/runtime/agent-invocation-contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
buildRuntimeAgentControlPlaneStreamRequestFromInvocation,
parseRuntimeAgentRunInvocation,
parseRuntimeAgentRunInvocationOrError,
type RuntimeAgentControlPlaneStreamRequest,
RuntimeAgentRunInvocationSchema,
} from "../index.ts";
import { DEFAULT_LIMITS } from "#veryfront/security/input-validation/types.ts";
Expand Down Expand Up @@ -67,6 +68,21 @@ function createInvocation(overrides: Record<string, unknown> = {}) {
}

describe("agent/runtime-agent-invocation-contract", () => {
it("keeps the legacy control-plane request shape source-compatible", () => {
const request: RuntimeAgentControlPlaneStreamRequest = {
agentId: "builder",
threadId: conversationId,
runId: "run_legacy_1",
messages: [],
tools: [],
context: [],
runtimeTargetKind: "main_branch",
agentSource: { type: "branch", branch: "main" },
};

assertEquals(request.messageId, undefined);
});

it("exports the control-plane runtime agent invocation schema from veryfront/agent", () => {
const parsed = RuntimeAgentRunInvocationSchema.parse(createInvocation());

Expand Down Expand Up @@ -412,6 +428,7 @@ describe("agent/runtime-agent-invocation-contract", () => {
agentId: "builder",
threadId: conversationId,
runId: "run_child_1",
messageId,
parentRunId: "run_root_1",
messages: parsed.messages,
tools: parsed.tools,
Expand Down
2 changes: 2 additions & 0 deletions src/agent/runtime/agent-invocation-contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ export type RuntimeAgentControlPlaneStreamRequest = {
agentId: RuntimeAgentRunContext["agentId"];
threadId: RuntimeAgentRunContext["conversationId"];
runId: RuntimeAgentRunContext["runId"];
messageId?: RuntimeAgentRunContext["messageId"];
taskId?: string;
parentRunId?: Exclude<RuntimeAgentRunContext["parentRunId"], null | undefined>;
messages: RuntimeAgentRunInvocation["messages"];
Expand All @@ -456,6 +457,7 @@ export function buildRuntimeAgentControlPlaneStreamRequestFromInvocation(
agentId: input.run.agentId,
threadId: input.run.conversationId,
runId: input.run.runId,
messageId: input.run.messageId,
...(input.taskId ? { taskId: input.taskId } : {}),
...(input.run.parentRunId ? { parentRunId: input.run.parentRunId } : {}),
messages: input.messages,
Expand Down
61 changes: 54 additions & 7 deletions src/agent/runtime/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ import {
getRuntimeProviderReplayCheckpointMessageId,
getRuntimeProviderReplayCheckpointPersister,
getRuntimeProviderReplayCheckpoints,
getRuntimeProviderReplayCheckpointTurnComplete,
getRuntimeProviderReplayCheckpointTurnFailed,
getRuntimeProviderTools,
getRuntimeSourceIntegrationPolicy,
getRuntimeToolExposureCheckpoint,
Expand Down Expand Up @@ -690,6 +692,9 @@ async function persistToolExposureCheckpointBeforeContinuation(input: {
type RuntimeProviderReplayCheckpointEmission = {
state: ProviderReplayCheckpointEmissionState | undefined;
persist: ((checkpoint: ProviderReplayCheckpoint) => void | Promise<void>) | undefined;
complete: (() => void | Promise<void>) | undefined;
fail: (() => void | Promise<void>) | undefined;
failed: boolean;
required: boolean;
};

Expand All @@ -707,27 +712,54 @@ function resolveRuntimeProviderReplayCheckpointEmission(
? createProviderReplayCheckpointEmissionState({ messageId, existingCheckpoint })
: undefined,
persist: getRuntimeProviderReplayCheckpointPersister(config),
complete: getRuntimeProviderReplayCheckpointTurnComplete(config),
fail: getRuntimeProviderReplayCheckpointTurnFailed(config),
failed: false,
required: isRuntimeProviderReplayCheckpointPersistenceRequired(config),
};
}

async function failProviderReplayCheckpointTurn(
emission: RuntimeProviderReplayCheckpointEmission,
): Promise<void> {
if (emission.failed) return;
emission.failed = true;
await emission.fail?.();
}

async function persistProviderReplayCheckpointAfterTurn(input: {
emission: RuntimeProviderReplayCheckpointEmission;
providerMetadata: Record<string, unknown> | undefined;
}): Promise<void> {
try {
await persistProviderReplayCheckpointAfterTurnUnsafe(input);
} catch (error) {
await failProviderReplayCheckpointTurn(input.emission);
throw error;
}
}

async function persistProviderReplayCheckpointAfterTurnUnsafe(input: {
emission: RuntimeProviderReplayCheckpointEmission;
providerMetadata: Record<string, unknown> | undefined;
}): Promise<void> {
if (!input.emission.state) {
if (input.emission.required) {
throw DURABLE_RUN_EVENT_PERSISTENCE_FAILED.create({
detail: "provider replay checkpoint message identity is required",
});
}
await input.emission.complete?.();
return;
}
const checkpoint = captureProviderReplayCheckpoint(
input.emission.state,
input.providerMetadata,
);
if (!checkpoint) return;
if (!checkpoint) {
await input.emission.complete?.();
return;
}
if (!input.emission.persist) {
if (input.emission.required) {
throw DURABLE_RUN_EVENT_PERSISTENCE_FAILED.create({
Expand All @@ -737,6 +769,7 @@ async function persistProviderReplayCheckpointAfterTurn(input: {
return;
}
await input.emission.persist(checkpoint);
await input.emission.complete?.();
}

function isToolVisibleForStep(toolName: string, plan: ToolExposurePlan): boolean {
Expand Down Expand Up @@ -1306,6 +1339,9 @@ export class AgentRuntime {
const requestedModel = transport.requestedModel;
const resolvedModelString = transport.resolvedModelString;
const supportsToolCalling = supportsModelRuntimeToolCalling(transport.languageModel);
const providerReplayCheckpointEmission = resolveRuntimeProviderReplayCheckpointEmission(
this.config,
);
debugRuntimeModelRemap(requestedModel, resolvedModelString);

return withSpan("agent.generate", async (span) => {
Expand Down Expand Up @@ -1344,6 +1380,7 @@ export class AgentRuntime {
context,
runRuntimeContext,
supportsToolCalling,
providerReplayCheckpointEmission,
resolvedModelString,
transport.languageModel,
transport.headers,
Expand All @@ -1360,6 +1397,9 @@ export class AgentRuntime {
)
),
);
}).catch(async (error) => {
await failProviderReplayCheckpointTurn(providerReplayCheckpointEmission);
throw error;
});
}

Expand Down Expand Up @@ -1426,6 +1466,9 @@ export class AgentRuntime {
// Determine inference mode from the resolved model object, not the string.
const isLocal = isLocalModelRuntime(languageModel);
const supportsToolCalling = supportsModelRuntimeToolCalling(languageModel);
const providerReplayCheckpointEmission = resolveRuntimeProviderReplayCheckpointEmission(
this.config,
);

// Eagerly verify the model runtime is available. For local models this
// checks that @huggingface/transformers can be imported. Must happen
Expand Down Expand Up @@ -1487,6 +1530,7 @@ export class AgentRuntime {
context,
runRuntimeContext,
supportsToolCalling,
providerReplayCheckpointEmission,
resolvedModelString,
languageModel,
transport.headers,
Expand Down Expand Up @@ -1516,6 +1560,13 @@ export class AgentRuntime {
});
closeSSEStream(controller);
} catch (error) {
try {
await failProviderReplayCheckpointTurn(providerReplayCheckpointEmission);
} catch (failureHookError) {
logger.debug("Provider replay failure hook rejected", {
error: failureHookError,
});
}
if (isAbortError(error, streamAbortSignal)) {
closeSSEStream(controller);
return;
Expand Down Expand Up @@ -1559,6 +1610,7 @@ export class AgentRuntime {
runtimeContext: Record<string, unknown> | undefined,
runRuntimeContext: AgentRunRuntimeContext,
supportsToolCalling: boolean,
providerReplayCheckpointEmission: RuntimeProviderReplayCheckpointEmission,
modelString?: string,
resolvedModel?: ModelRuntime,
headers?: HeadersInit,
Expand All @@ -1583,9 +1635,6 @@ export class AgentRuntime {
getRuntimeProviderReplayCheckpoints(this.config),
{ activeProvider: getActiveProviderReplayProvider(languageModel) },
);
const providerReplayCheckpointEmission = resolveRuntimeProviderReplayCheckpointEmission(
this.config,
);
const totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };

if (!supportsToolCalling && this.config.tools) {
Expand Down Expand Up @@ -2236,6 +2285,7 @@ export class AgentRuntime {
runtimeContext: Record<string, unknown> | undefined,
runRuntimeContext: AgentRunRuntimeContext,
supportsToolCalling: boolean,
providerReplayCheckpointEmission: RuntimeProviderReplayCheckpointEmission,
modelString?: string,
resolvedModel?: ModelRuntime,
headers?: HeadersInit,
Expand All @@ -2258,9 +2308,6 @@ export class AgentRuntime {
getRuntimeProviderReplayCheckpoints(this.config),
{ activeProvider: getActiveProviderReplayProvider(languageModel) },
);
const providerReplayCheckpointEmission = resolveRuntimeProviderReplayCheckpointEmission(
this.config,
);
const totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };

if (!supportsToolCalling && this.config.tools) {
Expand Down
Loading
Loading