eve 0.77.0 → 0.78.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/CHANGELOG.md +16 -0
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/context/keys.d.ts +16 -0
- package/dist/src/context/keys.js +1 -1
- package/dist/src/execution/agent-sessions/steps.d.ts +2 -0
- package/dist/src/execution/agent-sessions/steps.js +1 -1
- package/dist/src/execution/cancelled-model-call-batch.js +1 -1
- package/dist/src/execution/catalog/search.js +1 -1
- package/dist/src/execution/catalog/step-catalog.d.ts +12 -3
- package/dist/src/execution/catalog/step-catalog.js +1 -1
- package/dist/src/execution/coordination-dispatch-shared.d.ts +1 -2
- package/dist/src/execution/coordination-dispatch-shared.js +1 -1
- package/dist/src/execution/coordination-dispatch-step.js +1 -1
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker-container.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker.js +1 -1
- package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
- package/dist/src/execution/sandbox/bindings/just-bash.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/sandbox/session.d.ts +6 -0
- package/dist/src/execution/sandbox/session.js +2 -2
- package/dist/src/execution/session/active-turn.d.ts +9 -1
- package/dist/src/execution/session/active-turn.js +1 -1
- package/dist/src/execution/session/checkpoint-migrations.js +1 -1
- package/dist/src/execution/session/handoff.d.ts +1 -1
- package/dist/src/execution/session/handoff.js +1 -1
- package/dist/src/execution/session/next-input.js +1 -1
- package/dist/src/execution/session/turn.d.ts +11 -4
- package/dist/src/execution/session/turn.js +1 -1
- package/dist/src/execution/session-inbox/inbox.d.ts +3 -0
- package/dist/src/execution/session-inbox/inbox.js +1 -1
- package/dist/src/execution/session-workflow-tool-run.d.ts +14 -12
- package/dist/src/execution/session-workflow-tool-run.js +1 -1
- package/dist/src/execution/tasks/start.d.ts +14 -1
- package/dist/src/execution/tasks/start.js +1 -1
- package/dist/src/execution/tasks/steps.d.ts +7 -4
- package/dist/src/execution/tasks/steps.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/tools/workflow/apply-run-messages-step.d.ts +20 -0
- package/dist/src/execution/tools/workflow/apply-run-messages-step.js +1 -0
- package/dist/src/execution/tools/workflow/ask.d.ts +0 -1
- package/dist/src/execution/tools/workflow/ask.js +1 -1
- package/dist/src/execution/tools/workflow/interrupt.d.ts +5 -2
- package/dist/src/execution/tools/workflow/interrupt.js +1 -1
- package/dist/src/execution/tools/workflow/messages.d.ts +14 -0
- package/dist/src/execution/tools/workflow/messages.js +1 -1
- package/dist/src/execution/tools/workflow/owner.d.ts +18 -6
- package/dist/src/execution/tools/workflow/owner.js +1 -1
- package/dist/src/execution/tools/workflow/start.d.ts +10 -0
- package/dist/src/execution/tools/workflow/start.js +1 -1
- package/dist/src/execution/tools/workflow/step.js +1 -1
- package/dist/src/execution/tools/workflow/workflow-owner-blocking.d.ts +12 -0
- package/dist/src/execution/tools/workflow/workflow-owner-blocking.js +1 -1
- package/dist/src/execution/tools/workflow/workflow.js +1 -1
- package/dist/src/execution/workflow-runtime.d.ts +18 -3
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/harness/hitl/approvals.d.ts +4 -7
- package/dist/src/harness/hitl/approvals.js +1 -1
- package/dist/src/harness/hitl/approved-calls.d.ts +11 -0
- package/dist/src/harness/hitl/approved-calls.js +1 -1
- package/dist/src/harness/hitl/candidates.d.ts +0 -4
- package/dist/src/harness/hitl/candidates.js +1 -1
- package/dist/src/harness/hitl/delivery.d.ts +0 -1
- package/dist/src/harness/hitl/delivery.js +1 -1
- package/dist/src/harness/hitl/index.d.ts +2 -2
- package/dist/src/harness/hitl/index.js +1 -1
- package/dist/src/harness/hitl/intake.d.ts +2 -2
- package/dist/src/harness/hitl/intake.js +1 -1
- package/dist/src/harness/model-call/call.js +1 -1
- package/dist/src/harness/model-call/run.js +1 -1
- package/dist/src/harness/session-machine/state.d.ts +0 -2
- package/dist/src/harness/session-machine/view.d.ts +0 -3
- package/dist/src/harness/session-machine/view.js +1 -1
- package/dist/src/harness/step/after-model.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/tools.js +1 -1
- package/dist/src/internal/application/stamped-package-version.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/docs/agent-config.md +12 -4
- package/docs/concepts/built-in-tools.md +9 -9
- package/docs/guides/dynamic-capabilities.md +6 -2
- package/docs/sandbox/index.mdx +2 -0
- package/docs/tools/human-in-the-loop.md +1 -1
- package/package.json +1 -1
- package/dist/src/context/caller-scope.d.ts +0 -7
- package/dist/src/context/caller-scope.js +0 -1
- package/dist/src/execution/tools/workflow/emit-workflow-tool-run-report-step.d.ts +0 -13
- package/dist/src/execution/tools/workflow/emit-workflow-tool-run-report-step.js +0 -1
- package/dist/src/harness/hitl/approved-call-callers.d.ts +0 -14
- package/dist/src/harness/hitl/approved-call-callers.js +0 -1
|
@@ -27,8 +27,6 @@ export interface SuspendedStep {
|
|
|
27
27
|
readonly approved?: readonly InputRequest[];
|
|
28
28
|
/** Workflow and agent calls the runtime runs for the step. */
|
|
29
29
|
readonly tasks: readonly RuntimeWorkflowTaskRequest[];
|
|
30
|
-
/** Who approved each task an approval started, by call id: the task runs as them. */
|
|
31
|
-
readonly approvers?: Readonly<Record<string, SessionAuthContext>>;
|
|
32
30
|
readonly responseAuthRequiredRequestIds?: readonly string[];
|
|
33
31
|
/** The caller whose turn parked the step; `null` when unauthenticated. */
|
|
34
32
|
readonly requester?: SessionAuthContext | null;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { SessionAuthContext } from "#channel/types.js";
|
|
2
1
|
import type { TokenUsage } from "#shared/token-usage.js";
|
|
3
2
|
import type { ModelMessage } from "ai";
|
|
4
3
|
import type { AuthorizationChallenge } from "#harness/authorization.js";
|
|
@@ -51,8 +50,6 @@ export interface RuntimeWait {
|
|
|
51
50
|
readonly callIds: readonly string[];
|
|
52
51
|
readonly tasks: readonly RuntimeWorkflowTaskRequest[];
|
|
53
52
|
readonly taskToolCalls: readonly TaskToolCall[];
|
|
54
|
-
/** Who approved each task an approval started, by call id. */
|
|
55
|
-
readonly approvers: Readonly<Record<string, SessionAuthContext>>;
|
|
56
53
|
}
|
|
57
54
|
/** The calls suspended steps wait on the runtime for, or `undefined` when none do. */
|
|
58
55
|
export declare function runtimeWait(state: SessionStateMap | undefined): RuntimeWait | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readTurnState}from"./state.js";import{initialSessionProjection,turnCoordinates}from"#protocol/session-projection.js";import{pendingTaskToolCalls}from"#execution/tasks/calls.js";const SESSION_PROJECTION_STATE_KEY=`eve.harness.sessionProjection`;function storedProjection(e){return e?.[`eve.harness.sessionProjection`]??initialSessionProjection()}function turnPosition(e){let{sequence:t,stepIndex:n}=turnCoordinates(e),r=e.activeTurnId===void 0?void 0:e.turns[e.activeTurnId],i={sessionStarted:e.started===!0,sequence:t,stepIndex:n,turnId:r?.turnId??``};return r?.outputStarted===!0&&(i.assistantOutputStarted=!0),i}function activeTurnId(e){return e.turnId===``?`turn_${e.sequence}`:e.turnId}function isBetweenTurns(e){return e.activeTurnId===void 0}function nextStepIndex(e){let t=e.activeTurnId===void 0?void 0:e.turns[e.activeTurnId];return t?.stepIndex===void 0?0:t.stepIndex+1}function queuedInput(e){return readTurnState(e).queued}function suspendedSteps(e){return readTurnState(e).suspended}function answeredCallIds(e){let t=new Set;for(let n of e)if((n.role===`tool`||n.role===`assistant`)&&typeof n.content!=`string`)for(let e of n.content)e.type===`tool-result`&&t.add(e.toolCallId);return t}function runningTasks(e){let t=answeredCallIds(e.messages);return e.tasks.filter(e=>!t.has(e.callId))}function runtimeWait(e){let t=suspendedSteps(e).flatMap(e=>{let t=runningTasks(e),n=pendingTaskToolCalls(e.messages);return t.length===0&&n.length===0?[]:[{step:e,tasks:t,taskToolCalls:n}]}),n=t[0];if(n===void 0)return;let r=t.flatMap(e=>e.tasks),i=t.flatMap(e=>e.taskToolCalls);return{
|
|
1
|
+
import{readTurnState}from"./state.js";import{initialSessionProjection,turnCoordinates}from"#protocol/session-projection.js";import{pendingTaskToolCalls}from"#execution/tasks/calls.js";const SESSION_PROJECTION_STATE_KEY=`eve.harness.sessionProjection`;function storedProjection(e){return e?.[`eve.harness.sessionProjection`]??initialSessionProjection()}function turnPosition(e){let{sequence:t,stepIndex:n}=turnCoordinates(e),r=e.activeTurnId===void 0?void 0:e.turns[e.activeTurnId],i={sessionStarted:e.started===!0,sequence:t,stepIndex:n,turnId:r?.turnId??``};return r?.outputStarted===!0&&(i.assistantOutputStarted=!0),i}function activeTurnId(e){return e.turnId===``?`turn_${e.sequence}`:e.turnId}function isBetweenTurns(e){return e.activeTurnId===void 0}function nextStepIndex(e){let t=e.activeTurnId===void 0?void 0:e.turns[e.activeTurnId];return t?.stepIndex===void 0?0:t.stepIndex+1}function queuedInput(e){return readTurnState(e).queued}function suspendedSteps(e){return readTurnState(e).suspended}function answeredCallIds(e){let t=new Set;for(let n of e)if((n.role===`tool`||n.role===`assistant`)&&typeof n.content!=`string`)for(let e of n.content)e.type===`tool-result`&&t.add(e.toolCallId);return t}function runningTasks(e){let t=answeredCallIds(e.messages);return e.tasks.filter(e=>!t.has(e.callId))}function runtimeWait(e){let t=suspendedSteps(e).flatMap(e=>{let t=runningTasks(e),n=pendingTaskToolCalls(e.messages);return t.length===0&&n.length===0?[]:[{step:e,tasks:t,taskToolCalls:n}]}),n=t[0];if(n===void 0)return;let r=t.flatMap(e=>e.tasks),i=t.flatMap(e=>e.taskToolCalls);return{callIds:[...r.map(e=>e.callId),...i.map(e=>e.callId)],event:n.step.event,taskToolCalls:i,tasks:r}}export{SESSION_PROJECTION_STATE_KEY,activeTurnId,answeredCallIds,isBetweenTurns,nextStepIndex,queuedInput,runningTasks,runtimeWait,storedProjection,suspendedSteps,turnPosition};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{REPLY_TOOL_NAME}from"#protocol/reply-tool.js";import{resolveAssistantStepText,validateHarnessModelMessages}from"#harness/messages.js";import{renderFinalOutputWhileWorkingError}from"#execution/tasks/render.js";import{extractToolApprovalInputRequests,hasRunnableQueue,parkOnApprovals,stopForToolSignIn}from"#harness/hitl/index.js";import{stageToolResultMedia}from"#harness/attachment-staging.js";import{isWorkflowTool,workingTaskIds}from"#execution/tasks/model-step.js";import{collectWorkflowCalls}from"#harness/coordination.js";import{fail,finishTurn,hold,suspendStep,withResult}from"#harness/session-machine/transitions.js";import{createToolResultMessagePartFromToolError,isToolResultError}from"#harness/action-result-helpers.js";import{setRequestEnvelopeTokens}from"#harness/request-envelope.js";import{getInvalidToolCallInputError,isInvalidToolCall}from"#harness/tool-call-input-errors.js";import{resolveInlineAuthorizationInterrupt}from"#harness/inline-tool-authorization.js";import{FINAL_OUTPUT_BESIDE_PENDING_CALLS}from"#harness/final-output.js";import{appendMissingToolResultMessages,extractToolResultCallIds}from"#harness/model-call/response.js";import{clearTurnClientContextState}from"#harness/turn-client-context.js";import{normalizeProviderToolHistory}from"#harness/provider-tool-history.js";const log=createLogger(`harness.tool-loop`);function getInvalidToolCallInputErrors(e){let t=[];for(let n of e.toolCalls){if(n.toolName===REPLY_TOOL_NAME)continue;let e=getInvalidToolCallInputError({toolCall:n});e!==void 0&&t.push(e)}return t}async function handleStepResult(e,t){let{promptMessages:n,result:r}=t,i=resolveAssistantStepText(r.response.messages,r.text),a=getInvalidToolCallInputErrors({toolCalls:r.toolCalls}),o=new Set([...r.invalidInputToolCallIds??[],...r.toolCalls.filter(isInvalidToolCall).map(e=>e.toolCallId),...a.map(e=>e.toolCallId)]),s=appendMissingToolResultMessages({append:a.map(e=>createToolResultMessagePartFromToolError(e)),responseMessages:r.response.messages}),c=new Set;for(let e of[...r.content??[],...r.toolResults??[]])(e.type===`tool-result`||e.type===`tool-error`)&&e.providerExecuted===!0&&c.add(e.toolCallId);let l=normalizeProviderToolHistory({messages:s,providerExecutedOutcomeIds:c}),u=await stageToolResultMedia(withoutApprovalParts(l.messages));e.session=setRequestEnvelopeTokens({...e.session,compaction:createNextCompactionConfig(e.session.compaction,t.durableModelPromptMessageCount,r)},r.usage?.inputTokens!==void 0&&t.durableModelPromptMessageCount!==void 0?t.requestEnvelopeTokens:void 0);let d=extractToolApprovalInputRequests({content:r.content??[],excludedCallIds:o,tools:t.catalog}),f=new Set([...d.map(e=>e.action.callId),...extractToolResultCallIds(u)]),p=(r.toolCalls??[]).filter(e=>!o.has(e.toolCallId)).filter(e=>!f.has(e.toolCallId)).filter(e=>isWorkflowTool(t.catalog.get(e.toolName)));if(p.length>0||d.length>0){let{sequence:i,stepIndex:a,turnId:o}=e.position(),s=collectWorkflowCalls({session:e.session,toolCalls:p,tools:t.catalog,turnId:o});e.session={...s.session,history:validateHarnessModelMessages(n)};let c={event:{sequence:i,stepIndex:a,turnId:o},messages:answerCallsThatWontRun(u,r),tasks:s.workflowRequests};
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{REPLY_TOOL_NAME}from"#protocol/reply-tool.js";import{resolveAssistantStepText,validateHarnessModelMessages}from"#harness/messages.js";import{renderFinalOutputWhileWorkingError}from"#execution/tasks/render.js";import{extractToolApprovalInputRequests,hasRunnableQueue,parkOnApprovals,stopForToolSignIn}from"#harness/hitl/index.js";import{stageToolResultMedia}from"#harness/attachment-staging.js";import{isWorkflowTool,workingTaskIds}from"#execution/tasks/model-step.js";import{collectWorkflowCalls}from"#harness/coordination.js";import{fail,finishTurn,hold,suspendStep,withResult}from"#harness/session-machine/transitions.js";import{createToolResultMessagePartFromToolError,isToolResultError}from"#harness/action-result-helpers.js";import{setRequestEnvelopeTokens}from"#harness/request-envelope.js";import{getInvalidToolCallInputError,isInvalidToolCall}from"#harness/tool-call-input-errors.js";import{resolveInlineAuthorizationInterrupt}from"#harness/inline-tool-authorization.js";import{FINAL_OUTPUT_BESIDE_PENDING_CALLS}from"#harness/final-output.js";import{appendMissingToolResultMessages,extractToolResultCallIds}from"#harness/model-call/response.js";import{clearTurnClientContextState}from"#harness/turn-client-context.js";import{normalizeProviderToolHistory}from"#harness/provider-tool-history.js";const log=createLogger(`harness.tool-loop`);function getInvalidToolCallInputErrors(e){let t=[];for(let n of e.toolCalls){if(n.toolName===REPLY_TOOL_NAME)continue;let e=getInvalidToolCallInputError({toolCall:n});e!==void 0&&t.push(e)}return t}async function handleStepResult(e,t){let{promptMessages:n,result:r}=t,i=resolveAssistantStepText(r.response.messages,r.text),a=getInvalidToolCallInputErrors({toolCalls:r.toolCalls}),o=new Set([...r.invalidInputToolCallIds??[],...r.toolCalls.filter(isInvalidToolCall).map(e=>e.toolCallId),...a.map(e=>e.toolCallId)]),s=appendMissingToolResultMessages({append:a.map(e=>createToolResultMessagePartFromToolError(e)),responseMessages:r.response.messages}),c=new Set;for(let e of[...r.content??[],...r.toolResults??[]])(e.type===`tool-result`||e.type===`tool-error`)&&e.providerExecuted===!0&&c.add(e.toolCallId);let l=normalizeProviderToolHistory({messages:s,providerExecutedOutcomeIds:c}),u=await stageToolResultMedia(withoutApprovalParts(l.messages));e.session=setRequestEnvelopeTokens({...e.session,compaction:createNextCompactionConfig(e.session.compaction,t.durableModelPromptMessageCount,r)},r.usage?.inputTokens!==void 0&&t.durableModelPromptMessageCount!==void 0?t.requestEnvelopeTokens:void 0);let d=extractToolApprovalInputRequests({content:r.content??[],excludedCallIds:o,tools:t.catalog}),f=new Set([...d.map(e=>e.action.callId),...extractToolResultCallIds(u)]),p=(r.toolCalls??[]).filter(e=>!o.has(e.toolCallId)).filter(e=>!f.has(e.toolCallId)).filter(e=>isWorkflowTool(t.catalog.get(e.toolName))),m=resolveInlineAuthorizationInterrupt({messages:[...n,...u],toolResults:r.toolResults});if(p.length>0||d.length>0){let{sequence:i,stepIndex:a,turnId:o}=e.position(),s=collectWorkflowCalls({session:e.session,toolCalls:p,tools:t.catalog,turnId:o});e.session={...s.session,history:validateHarnessModelMessages(n)};let c={event:{sequence:i,stepIndex:a,turnId:o},messages:answerCallsThatWontRun(u,r),tasks:s.workflowRequests};if(d.length>0){let n=await parkOnApprovals(e,{...c,requests:d,tools:t.catalog,waitsOn:m?`sign-in`:p.length>0?`runtime`:void 0});return m?stopForToolSignIn(e,{...m,history:e.session.history}):n}return await e.apply(suspendStep(e.view(),c)),m?stopForToolSignIn(e,{...m,history:e.session.history}):(s.workflowRequests.some(e=>e.entry.entryPoint===`execute`)&&await e.apply(hold(e.view(),{on:`tasks`})),{next:null,session:e.session})}if(m)return stopForToolSignIn(e,m);e.session={...e.session,history:validateHarnessModelMessages([...n,...u])};let h=e.session.outputSchema!==void 0&&extractFinalOutput(r)!==void 0,g=workingTaskIds(e.session),_=h&&g.length>0,v=u;_&&(v=rejectFinalOutput(u,r,g),e.session={...e.session,history:validateHarnessModelMessages([...n,...v])});let y=await stepEndsTurn(r,u,t.endsTurnTools);return(!h||_)&&(v.at(-1)?.role===`tool`&&!y||l.outcomeEndsResponse||hasRunnableQueue(e.view()))?{next:e.runStep,session:e.session}:g.length>0?(await e.apply(hold(e.view(),{on:`tasks`})),{held:{kind:`tasks`,taskIds:g},next:null,session:e.session}):settleTurn(e,{history:n,result:r,stepOutput:y?null:i})}function answerCallsThatWontRun(e,t){let n=extractToolResultCallIds(e);return(t.toolCalls??[]).filter(e=>e.toolName===REPLY_TOOL_NAME).map(e=>({output:{type:`error-text`,value:FINAL_OUTPUT_BESIDE_PENDING_CALLS},toolCallId:e.toolCallId,toolName:e.toolName,type:`tool-result`})).filter(e=>!n.has(e.toolCallId)).reduce((e,t)=>withResult(e,t),[...e])}function withoutApprovalParts(e){return e.flatMap(e=>{if(e.role!==`assistant`&&e.role!==`tool`||!Array.isArray(e.content))return[e];let t=e.content.filter(e=>e.type!==`tool-approval-request`&&e.type!==`tool-approval-response`);return t.length===0?[]:[{...e,content:t}]})}async function stepEndsTurn(e,t,n){let r=e.toolCalls??[];if(r.length===0)return!1;let i=new Map;for(let e of t)if(e.role===`tool`)for(let t of e.content)t.type===`tool-result`&&i.set(t.toolCallId,t.output);if(!r.every(e=>{let t=i.get(e.toolCallId);return n.has(e.toolName)&&t!==void 0&&!isToolResultError(t)}))return!1;let a=new Map((e.toolResults??[]).map(e=>[e.toolCallId,e.output]));for(let e of r){let t=n.get(e.toolName);if(typeof t==`function`&&!await callEndsTurn(t,a.get(e.toolCallId),e))return!1}return!0}async function callEndsTurn(e,t,n){try{return await e(t)===!0}catch(e){return log.warn(`endsTurn threw; continuing the turn`,{callId:n.toolCallId,error:e,toolName:n.toolName}),!1}}function rejectFinalOutput(e,t,n){let r=(t.toolCalls??[]).find(e=>e.toolName===REPLY_TOOL_NAME);if(r===void 0)return[...e];let i={output:{type:`error-text`,value:renderFinalOutputWhileWorkingError(n)},toolCallId:r.toolCallId,toolName:REPLY_TOOL_NAME,type:`tool-result`};return[...e,{content:[i],role:`tool`}]}const OUTPUT_SCHEMA_NOT_FULFILLED={code:`OUTPUT_SCHEMA_NOT_FULFILLED`,message:`The agent could not produce a result matching the requested schema.`};function extractFinalOutput(e){return(e.toolCalls??[]).find(e=>e.toolName===REPLY_TOOL_NAME&&!isInvalidToolCall(e))?.input}async function settleTurn(e,t){let{history:n,result:r,stepOutput:i}=t,a=e.session.outputSchema;if(e.session=clearTurnClientContextState(e.session),a===void 0)return await e.apply(finishTurn(e.view()),e.session.history),{next:null,session:e.session,settledTurn:{output:i??``}};let o=extractFinalOutput(r);return o===void 0?(e.session={...e.session,outputSchema:void 0},await e.apply(fail(e.view(),OUTPUT_SCHEMA_NOT_FULFILLED)),{next:null,session:e.session,settledTurn:{isError:!0,output:OUTPUT_SCHEMA_NOT_FULFILLED.message}}):(e.session={...e.session,history:[...n,{content:JSON.stringify(o),role:`assistant`}],outputSchema:void 0},await e.apply(finishTurn(e.view(),{result:o}),e.session.history),{next:null,session:e.session,settledTurn:{output:o}})}function createNextCompactionConfig(e,t,n){let r={recentWindowSize:e.recentWindowSize,threshold:e.threshold,thresholdPercent:e.thresholdPercent};return n.usage?.inputTokens!==void 0&&t!==void 0&&(r.lastKnownInputTokens=n.usage.inputTokens,r.lastKnownPromptMessageCount=t),r}export{handleStepResult,withoutApprovalParts};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{contextStorage}from"#context/container.js";import{saveProjection,stepProjection}from"#harness/session-machine/current.js";import{ScheduleIdKey,StaticModelReferenceKey}from"#context/keys.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{clearMemorySessionState}from"#shared/memory-state.js";import{activeTurnId,turnPosition}from"#harness/session-machine/view.js";import{acceptHumanInput,admitApprovedWork,discardClearedHumanInput}from"#harness/hitl/index.js";import{clear}from"#harness/session-machine/transitions.js";import{createHistoryViewPreparer}from"#shared/history-view.js";import{
|
|
1
|
+
import{contextStorage}from"#context/container.js";import{saveProjection,stepProjection}from"#harness/session-machine/current.js";import{ScheduleIdKey,StaticModelReferenceKey}from"#context/keys.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{clearMemorySessionState}from"#shared/memory-state.js";import{activeTurnId,turnPosition}from"#harness/session-machine/view.js";import{acceptHumanInput,admitApprovedWork,discardClearedHumanInput}from"#harness/hitl/index.js";import{clear}from"#harness/session-machine/transitions.js";import{createHistoryViewPreparer}from"#shared/history-view.js";import{compactHistory,replaceSessionHistory}from"#harness/compaction/step.js";import{createStep,openTurn}from"#harness/step/context.js";import{GenerationSteering}from"#harness/generation-steering.js";import{runModelStep}from"#harness/model-call/run.js";import{handleStepResult}from"#harness/step/after-model.js";import{prepareTurnInput,settleRuntimeWork}from"#harness/step/intake.js";const environment=process.env.NODE_ENV??`unknown`,eveVersion=resolveInstalledPackageInfo().version;function createToolLoopHarness(e){e.instrumentation?.installAiSdkWarningLogger();async function runStep(t,n){let executeStep=async r=>{let i=r?.session??t,a=stepProjection(contextStorage.getStore(),i.state),o=new GenerationSteering({abortSignal:e.abortSignal,steeringSignal:e.steeringSignal,outputStarted:turnPosition(a.read()).assistantOutputStarted});try{let e=await executeStepBody(i,o,a,n,r);return{...e,session:saveProjection(e.session,a.read())}}finally{o.dispose()}};return e.instrumentation?.runStep({environment,eveVersion,hasInput:hasStepInput(n),session:t},executeStep)??executeStep()}async function executeStepBody(t,n,r,i,a){let o=createHistoryViewPreparer({previous:e.historyView,projector:e.historyProjector});o(t.history,t.state);let s=contextStorage.getStore();s!==void 0&&!s.has(StaticModelReferenceKey)&&s.setVirtualContext(StaticModelReferenceKey,t.agent.dynamicModel===!0?null:t.agent.modelReference??null);let c,l=a?.createHandleEvent({getAttemptScope:()=>c,isFrameworkTool:e=>u.frameworkToolNames.has(e),handleEvent:e.handleEvent,turnId:activeTurnId(turnPosition(r.read()))})??e.handleEvent,u=createStep({config:e,ctx:s,emit:l,instrumentation:a,live:r,prepareHistory:o,publish:async(e,t)=>{n.beforeEvent(e),l!==void 0&&await l(e,t),(l===void 0||s===void 0)&&r.record(e)},runStep,session:t});if(e.clearOnly===!0)return clearContext(u);if(e.compactOnly===!0)return compactHistory(u);let d=await settleRuntimeWork(u,i);if(d===void 0)return{next:null,session:u.session};let f=await acceptHumanInput(u,d.input,{takeQueued:!d.waited});if(f.kind===`stop`)return f.result;let p=await prepareTurnInput(u,f.input,{consumedMessage:f.consumedMessage});if(f.opensTurn){let e=await openTurn(u,{input:[...p.ephemeral,...p.messages],message:f.message});if(e!==void 0)return e}return await admitApprovedWork(u,f.approved),runModelStep(u,{approved:f.approved,onResponse:e=>handleStepResult(u,e),generation:n,hidesHeldText:u.hasDelegatedCaller||s?.get(ScheduleIdKey)!==void 0,setAttemptScope:e=>{c=e},turn:p})}return runStep}async function clearContext(e){await e.apply(clear(e.view(),{sessionId:e.session.sessionId}));let t=discardClearedHumanInput({...e.session,state:clearMemorySessionState(e.session.state)});return{next:null,session:replaceSessionHistory(t,[])}}function hasStepInput(e){return e===void 0?!1:e.message!==void 0||(e.inputResponses?.length??0)>0}export{createToolLoopHarness};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{tool}from"ai";import{createLogger}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{loadContext}from"#context/container.js";import{toModelSchema}from"#tools/schema.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{resolveApprovalPolicy}from"#approval/definition.js";import{isApprovedToolCall,markApprovalRecheck}from"#harness/approval-recheck.js";import{isAuthorizationSignal,modelFacingAuthorizationOutput}from"#harness/authorization.js";import{entryModelOutput,stubbedCall}from"#harness/execute-call.js";import{normalizeToolJsonOutput}from"#harness/tool-model-output.js";import{isAsyncIterable}from"#shared/async-iterable.js";import{executeWithToolStub}from"#tool-stubs/execute.js";import{stashToolInterrupt}from"#harness/tool-interrupts.js";import{resolveWebSearchBackend,resolveWebSearchProviderTool}from"#harness/provider-tools.js";
|
|
1
|
+
import{tool}from"ai";import{createLogger}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{loadContext}from"#context/container.js";import{toModelSchema}from"#tools/schema.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{resolveApprovalPolicy}from"#approval/definition.js";import{isApprovedToolCall,markApprovalRecheck}from"#harness/approval-recheck.js";import{isAuthorizationSignal,modelFacingAuthorizationOutput}from"#harness/authorization.js";import{entryModelOutput,stubbedCall}from"#harness/execute-call.js";import{normalizeToolJsonOutput}from"#harness/tool-model-output.js";import{isAsyncIterable}from"#shared/async-iterable.js";import{executeWithToolStub}from"#tool-stubs/execute.js";import{stashToolInterrupt}from"#harness/tool-interrupts.js";import{resolveWebSearchBackend,resolveWebSearchProviderTool}from"#harness/provider-tools.js";const log=createLogger(`harness.tools`);function buildToolSet(e){let t={},n=e.disabledProviderTools;for(let r of e.tools.values())n?.has(r.name)||(t[r.name]=tool({description:e.describe(r),execute:wrapToolExecute(r,e.resolve),inputSchema:toModelSchema(r.inputSchema,`input`),strict:!1,outputSchema:toModelSchema(r.outputSchema,`output`),...r.execute!==void 0||r.toModelOutput!==void 0?{toModelOutput:({input:t,output:n,toolCallId:i})=>entryModelOutput(e.resolve({input:t,toolName:r.name})?.definition??r,n,i)}:{}}));return t}function wrapToolExecute(e,t){let n=e.execute;if(n!==void 0)return(r,i)=>{let a={input:r,toolName:e.name},o=t?.(a),s=o?.definition.name??e.name,c=stubbedCall(a,o),run=()=>n(r,i),l;try{l=c===void 0?run():executeWithToolStub(c.toolName,c.input,i,run)}catch(e){return Promise.reject(e)}return isAsyncIterable(l)?normalizeToolExecuteIterable(l,s,i):Promise.resolve(l).then(e=>normalizeToolExecuteOutput(e,s,i))}}async function*normalizeToolExecuteIterable(e,t,n){for await(let r of e)yield normalizeToolExecuteOutput(r,t,n)}function normalizeToolExecuteOutput(e,t,n){return isAuthorizationSignal(e)?(stashToolInterrupt(loadContext(),n.toolCallId,e),modelFacingAuthorizationOutput(e)):normalizeToolJsonOutput({boundary:`execute`,output:e,toolCallId:n.toolCallId,toolName:t})}async function buildToolSetWithProviderTools(e){let t=e.disabledProviderTools,n={...buildToolSet(e)};for(let r of e.tools.values()){let i=r.behavior?.handling;if(i?.kind===`provider-tool`&&r.execute===void 0&&!t?.has(r.name)){let t=resolveWebSearchBackend(e.profile,i);t===null?(log.debug(`model has no web search backend; leaving the tool out`,{gateway:e.profile.gateway,modelProvider:e.profile.provider,searchProvider:i.provider,tool:r.name}),delete n[r.name]):n[r.name]=await resolveWebSearchProviderTool(t)}}return n}function buildToolApproval(e){return async({toolCall:t,messages:n})=>{let r=e.resolve(t);if(r!==void 0)return await evaluateApproval(r.definition,{abortSignal:e.abortSignal,approvedTools:e.approvedTools,callId:t.toolCallId,input:r.call.input,recheck:isApprovedToolCall(n,t.toolCallId)})}}async function recheckApprovedCall(e,t){let n=await evaluateApproval(e,{...t,recheck:!0});return n===`denied`?{denied:!0}:typeof n==`object`&&n&&n.type===`denied`?{denied:!0,reason:n.reason}:{denied:!1}}async function evaluateApproval(e,t){if(e.approval===void 0)return;let n={...buildCallbackContext(),abortSignal:t.abortSignal??new AbortController().signal,approvedTools:t.approvedTools??new Set,callId:t.callId,toolInput:isObject(t.input)?t.input:void 0,toolName:e.name},r=await resolveApprovalPolicy(e.approval)(t.recheck?markApprovalRecheck(n):n);return typeof r==`boolean`?r?`user-approval`:`not-applicable`:r}export{buildToolApproval,buildToolSet,buildToolSetWithProviderTools,recheckApprovedCall,wrapToolExecute};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const STAMPED_PACKAGE_VERSION=`0.
|
|
1
|
+
const STAMPED_PACKAGE_VERSION=`0.78.0`;function readStampedPackageVersion(){return STAMPED_PACKAGE_VERSION.startsWith(`__`)?void 0:STAMPED_PACKAGE_VERSION}export{readStampedPackageVersion};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{DEFAULT_CONNECT_PACKAGE_VERSION,resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_CHANNEL_TEMPLATES}from"./web-template.js";import{AGENT_INSTRUCTIONS_TEMPLATE}from"./instructions-template.js";import{SCAFFOLDED_AGENT_PATHS}from"./agent-paths.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.137`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.
|
|
1
|
+
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{DEFAULT_CONNECT_PACKAGE_VERSION,resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_CHANNEL_TEMPLATES}from"./web-template.js";import{AGENT_INSTRUCTIONS_TEMPLATE}from"./instructions-template.js";import{SCAFFOLDED_AGENT_PATHS}from"./agent-paths.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.137`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.78.0`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e,t){return{[SCAFFOLDED_AGENT_PATHS.config]:renderAgentTemplate(e,t),[SCAFFOLDED_AGENT_PATHS.channel]:WEB_CHANNEL_TEMPLATES.default,[SCAFFOLDED_AGENT_PATHS.instructions]:AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,t){let n=parseChatGptModelSelection(e);return n===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(n)}),\n${reasoningTemplateLine(t)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,t){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(t.model)!==void 0?renderAgentTemplate(t.model,t.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
|
|
2
2
|
|
|
3
3
|
export default defineAgent({
|
|
4
4
|
model: "__EVE_INIT_MODEL__",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
async function executeAskQuestionTool(e,t){"use workflow";return toAskQuestionOutput(await t.ask(toAskQuestionRequest(e)))}function toAskQuestionRequest(e){let t=e.options?.map(e=>({description:e.description,id:e.label,label:e.label}));return{allowFreeform:!0,display:t===void 0?`text`:`select`,prompt:e.question,...t!==void 0&&{options:t}}}function toAskQuestionOutput(e){switch(e.status){case`answered`:return{answer:e.optionId??e.text??``,status:`answered`};case`cancelled`:return{interrupted:!0};case`unavailable`:return{status:`unavailable`}}}executeAskQuestionTool.workflowId=`workflow//eve@0.
|
|
1
|
+
async function executeAskQuestionTool(e,t){"use workflow";return toAskQuestionOutput(await t.ask(toAskQuestionRequest(e)))}function toAskQuestionRequest(e){let t=e.options?.map(e=>({description:e.description,id:e.label,label:e.label}));return{allowFreeform:!0,display:t===void 0?`text`:`select`,prompt:e.question,...t!==void 0&&{options:t}}}function toAskQuestionOutput(e){switch(e.status){case`answered`:return{answer:e.optionId??e.text??``,status:`answered`};case`cancelled`:return{interrupted:!0};case`unavailable`:return{status:`unavailable`}}}executeAskQuestionTool.workflowId=`workflow//eve@0.78.0//executeAskQuestionTool`;export{executeAskQuestionTool,toAskQuestionOutput,toAskQuestionRequest};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sleep}from"#compiled/@workflow/core/index.js";async function executeSleepTool(e,t){"use workflow";let n=new Promise(e=>t.abortSignal.addEventListener(`abort`,()=>e(`interrupted`),{once:!0})),r=sleep(Math.ceil(e.seconds*1e3)).then(()=>`elapsed`);return await Promise.race([r,n])===`elapsed`?{waitedSeconds:e.seconds}:{interrupted:!0}}executeSleepTool.workflowId=`workflow//eve@0.
|
|
1
|
+
import{sleep}from"#compiled/@workflow/core/index.js";async function executeSleepTool(e,t){"use workflow";let n=new Promise(e=>t.abortSignal.addEventListener(`abort`,()=>e(`interrupted`),{once:!0})),r=sleep(Math.ceil(e.seconds*1e3)).then(()=>`elapsed`);return await Promise.race([r,n])===`elapsed`?{waitedSeconds:e.seconds}:{interrupted:!0}}executeSleepTool.workflowId=`workflow//eve@0.78.0//executeSleepTool`;export{executeSleepTool};
|
package/docs/agent-config.md
CHANGED
|
@@ -220,16 +220,24 @@ timeout. Expiration does not delete stored session data.
|
|
|
220
220
|
Input tokens, output tokens, and model token cost are checked independently.
|
|
221
221
|
The model call that crosses a limit is allowed to finish because exact usage
|
|
222
222
|
arrives after the call completes. Before the next model call, eve pauses the
|
|
223
|
-
|
|
224
|
-
**
|
|
223
|
+
turn (`turn.waiting`) and sends a deterministic continuation prompt with two options:
|
|
224
|
+
**Continue** grants a fresh window of each configured size and resumes the same
|
|
225
|
+
turn, and **Stop**
|
|
225
226
|
cancels the in-flight turn through the standard cancellation path
|
|
226
227
|
(`turn.cancelled` → `session.waiting`) — a user decision, not an error. The session stays resumable; because it is
|
|
227
|
-
still over budget, the next message
|
|
228
|
+
still over budget after Stop, the next message raises a new prompt. Declining a
|
|
228
229
|
delegated child's prompt cancels the root turn, which cascades to the whole
|
|
229
230
|
delegation tree — the delegating parent never receives an error result it
|
|
230
231
|
could retry against a fresh quota share. A reply that answers neither option
|
|
231
232
|
is queued while the existing prompt stays pending; eve does not raise another
|
|
232
|
-
copy. The reply is
|
|
233
|
+
copy or start another turn. The reply is received (`message.received`) and
|
|
234
|
+
processed in the held turn once the budget is granted.
|
|
235
|
+
|
|
236
|
+
For sessions already waiting on a continuation prompt from an older deployment,
|
|
237
|
+
the previous turn has completed. A non-answer message still queues behind the
|
|
238
|
+
existing prompt, but emits no event until Continue is chosen. Continue starts a
|
|
239
|
+
new turn and receives the queued message once; it does not reopen the completed
|
|
240
|
+
turn or duplicate the prompt.
|
|
233
241
|
|
|
234
242
|
Sessions that cannot request input from a human, such as markdown schedules and
|
|
235
243
|
delegated runs without input proxying, skip the prompt and fail the next model
|
|
@@ -24,7 +24,7 @@ export default defineAgent({
|
|
|
24
24
|
|
|
25
25
|
This turns off the optional defaults described below. Add back only the tools the agent needs with the command in each tool's section. Existing files under `agent/tools/` remain available, including same-name replacements such as `agent/tools/bash.ts`.
|
|
26
26
|
|
|
27
|
-
`defaultTools` doesn't affect [the catalog tools](#eve__search-eve__tool-and-eve__skill): eve adds them from what the
|
|
27
|
+
`defaultTools` doesn't affect [the catalog tools](#eve__search-eve__tool-and-eve__skill): eve adds them from what the session can reach, as listed in that section.
|
|
28
28
|
|
|
29
29
|
### `bash`
|
|
30
30
|
|
|
@@ -301,16 +301,16 @@ export default disableTool();
|
|
|
301
301
|
|
|
302
302
|
### `eve__search`, `eve__tool`, and `eve__skill`
|
|
303
303
|
|
|
304
|
-
These tools let the model reach what isn't in its tool list. `eve__search` finds tools defined with `deferred: true`, agents defined with `tool: "deferred"`, every tool from the agent's [connections](../connections), and deferred [skills](../skills). `eve__tool` calls a deferred tool, agent, or connection tool by name, and `eve__skill` loads a skill, deferred or not. There is no add command; eve adds each one
|
|
304
|
+
These tools let the model reach what isn't in its tool list. `eve__search` finds tools defined with `deferred: true`, agents defined with `tool: "deferred"`, every tool from the agent's [connections](../connections), and deferred [skills](../skills). `eve__tool` calls a deferred tool, agent, or connection tool by name, and `eve__skill` loads a skill, deferred or not. There is no add command; eve adds each one when the session has something it reaches, even when `defaultTools` is `false`:
|
|
305
305
|
|
|
306
|
-
- `eve__tool` comes with anything it can call: a deferred tool or agent,
|
|
307
|
-
- `eve__skill` comes with any skill,
|
|
308
|
-
- `eve__search` comes with anything it could find: whatever `eve__tool` can call, plus deferred skills
|
|
309
|
-
-
|
|
306
|
+
- `eve__tool` comes with anything it can call: a deferred tool or agent, or a connection.
|
|
307
|
+
- `eve__skill` comes with any skill, so an agent whose only catalog entries are listed skills gets `eve__skill` alone.
|
|
308
|
+
- `eve__search` comes with anything it could find: whatever `eve__tool` can call, plus deferred skills.
|
|
309
|
+
- A session with none of these gets no catalog tools.
|
|
310
310
|
|
|
311
|
-
|
|
311
|
+
Entries the agent declares count from the session's first step. An entry a dynamic resolver returns counts from the step where it first appears, so a resolver in `agent/tools/` that returns only tools without `deferred: true` adds no catalog tools. Once a session's tool list includes a catalog tool, the session keeps it, even after a resolver stops returning the entry that brought it. The catalog tools change only when the session first reaches a new kind of entry, such as its first deferred tool or its first connection.
|
|
312
312
|
|
|
313
|
-
- `eve__search({ query, limit? })` returns the best matches, up to `limit` (default 10, at most 50). `query` is required and must contain a word. A tool match has its exact `tool` name, its `description`, and a TypeScript `signature` rendered from its schemas. A deferred skill's match has its `skill` name, its `description`, and the `path` of its `SKILL.md` when it has supporting files. A result with `tool` is called with `eve__tool`, and one with `skill` is loaded with `eve__skill`. Tools and skills rank together, in tiers: an entry whose name is exactly the query, then one whose name after its last `__` is the query, such as `linear__create_issue` or `sre__create_issue` for `create_issue`, then the tools of a connection named by the query, then entries whose names, or names after their last `__`, start with the query, then keyword matches in names, parameters, and descriptions. So `eve__search({ query: "linear" })` lists the `linear` connection's tools first. One-letter and filler words such as `a` and `the` don't count toward keyword matches unless the query has nothing else.
|
|
313
|
+
- `eve__search({ query, limit? })` returns the best matches, up to `limit` (default 10, at most 50). `query` is required and must contain a word. A tool match has its exact `tool` name, its `description`, and a TypeScript `signature` rendered from its schemas. A deferred skill's match has its `skill` name, its `description`, and the `path` of its `SKILL.md` when it has supporting files. A result with `tool` is called with `eve__tool`, and one with `skill` is loaded with `eve__skill`. Next to `results`, `searched` counts the entries the query covered, the whole catalog or one namespace, and `remaining` counts the matches past `limit`. A connection behind sign-in counts as its one sign-in result until the user signs in, and an unavailable connection counts as none. Tools and skills rank together, in tiers: an entry whose name is exactly the query, then one whose name after its last `__` is the query, such as `linear__create_issue` or `sre__create_issue` for `create_issue`, then the tools of a connection named by the query, then entries whose names, or names after their last `__`, start with the query, then keyword matches in names, parameters, and descriptions. So `eve__search({ query: "linear" })` lists the `linear` connection's tools first. One-letter and filler words such as `a` and `the` don't count toward keyword matches unless the query has nothing else.
|
|
314
314
|
- A query whose first word contains `__` searches one namespace: everything before its last `__`, without trailing underscores. The namespace only filters. `eve__search` keeps names under `<namespace>__` and anything named exactly the namespace, such as a connection's sign-in entry, then ranks them by the whole query, so `eve__search({ query: "linear__" })` returns only the `linear` connection's tools, or its sign-in result, and an exact name that contains `__` still ranks first. eve lists only the connections that can own names in that namespace, so other connections make no network call and don't appear in `unavailable`. A namespace that matches nothing fails with the closest connection names. Characters that can't appear in a name, such as a leading `^`, are ignored; `query` isn't a regular expression.
|
|
315
315
|
- `eve__search` never asks the user to sign in. A connection whose server won't list its tools until the user signs in appears as one result named after the connection, such as `linear`; a connection whose server lists its tools without a token is searched like any other. A connection whose tools fail to load, or don't load within 10 seconds, appears under `unavailable` with its `error`, such as `"crm" did not list its tools within 10s. Try again later.` Matches from everything else are still returned, so a slow server doesn't hold up the search. An `eve__tool` call on that connection's tools fails with the same error.
|
|
316
316
|
- `eve__tool({ name: "linear" })`, with a connection's own name, asks the user to sign in to that connection when its tools need it, and returns once they can be listed, so the next `eve__search` finds them. On a server that lists its tools without sign-in, it confirms the tools are available without asking.
|
|
@@ -319,7 +319,7 @@ The decision depends only on what the agent declares, never on what its resolver
|
|
|
319
319
|
|
|
320
320
|
After `eve__tool` or `eve__skill` resolves its entry, the call runs exactly like a direct call to that entry. A skill load reports a `load-skill` action and a `load-skill-result`, both with the skill's `name`, and an `execute_tool eve:load-skill` span. Approval policies and `approvedTools`, workflow tools and tasks, agents, `endsTurn`, `toModelOutput`, hooks, and stream events all see the entry's own name and input, such as `linear__list_issues`. Only model history records the call as `eve__tool` or `eve__skill`.
|
|
321
321
|
|
|
322
|
-
eve tells the model what it can reach in an append-only context message rather than in the system prompt: which kinds of deferred entries exist, up to 20 namespaces (the first `__` segment of deferred names, such as `sre` for `sre__list_alerts`), and up to 20 connections with their descriptions. It never names a deferred entry, so deferred entries stay out of context until `eve__search` finds them. A later step appends the listing again only when that changes; a deferred entry added to a listed namespace, or without one, changes nothing.
|
|
322
|
+
eve tells the model what it can reach in an append-only context message rather than in the system prompt: which kinds of deferred entries exist, up to 20 namespaces (the first `__` segment of deferred names, such as `sre` for `sre__list_alerts`), and up to 20 connections with their descriptions. It never names a deferred entry, so deferred entries stay out of context until `eve__search` finds them. A later step appends the listing again only when that changes; a deferred entry added to a listed namespace, or without one, changes nothing. After the session first reaches each kind of entry, adding or removing entries, signing in, or resolving more dynamic connections doesn't change the catalog tools, so the cached prompt prefix holds.
|
|
323
323
|
|
|
324
324
|
The tools eve adds itself all live in the `eve` namespace: `eve__search`, `eve__tool`, `eve__skill`, `eve__task_wait`, `eve__task_cancel`, and `eve__reply`. Nothing you author or resolve may be named `eve` or start with `eve__`: tools, subagents, skills, connections, and extension mounts, static or dynamic, since a connection or mount named `eve` would own every `eve__` name. The compiler rejects an authored tool, skill, connection, or mount, such as `agent/tools/eve__search.ts`; eve rejects an authored subagent when the agent loads, and a dynamic entry when its resolver returns it. Any other name is free, including `search` and `execute`. A connection's own name is also the entry that signs the user in to it.
|
|
325
325
|
|
|
@@ -195,7 +195,9 @@ arguments, and approval options as static [MCP](../connections/mcp) and
|
|
|
195
195
|
[OpenAPI](../connections/openapi) connections. Each resolved connection joins
|
|
196
196
|
the per-step connection registry. eve announces it to the model in an
|
|
197
197
|
append-only context message, and the model reaches its tools through
|
|
198
|
-
`eve__search` and `eve__tool
|
|
198
|
+
`eve__search` and `eve__tool`. If the session doesn't have those two tools yet,
|
|
199
|
+
eve adds them when its first connection resolves and keeps them for the rest of
|
|
200
|
+
the session, so later connections don't change the tool list.
|
|
199
201
|
|
|
200
202
|
Set `instanceKey` on every authenticated dynamic connection. Use a stable,
|
|
201
203
|
non-secret account or tenant identifier, and change it whenever the endpoint,
|
|
@@ -274,6 +276,8 @@ export default defineDynamic({
|
|
|
274
276
|
});
|
|
275
277
|
```
|
|
276
278
|
|
|
279
|
+
An entry with `deferred: true` stays out of the model's tool list, like a static [deferred tool](../tools#keep-a-tool-out-of-the-tool-list). The model finds it with `eve__search` and calls it with `eve__tool`. If the session doesn't have those two tools yet, eve adds them on the first step where a resolver returns a deferred entry, and keeps them for the rest of the session. A resolver whose entries are all listed adds neither, so the model doesn't spend steps searching for tools it already has.
|
|
280
|
+
|
|
277
281
|
### Author replayable callbacks
|
|
278
282
|
|
|
279
283
|
Write callback properties as inline function expressions, arrows, method shorthand, or module-level function references. eve transforms authored modules that import `defineTool`, including helper modules outside `agent/tools/`, and stores each callback's referenced closure values independently.
|
|
@@ -377,7 +381,7 @@ A dynamic connection, tool, or skill whose name matches an **authored** one **ov
|
|
|
377
381
|
|
|
378
382
|
At `turn.started`, model, tool, skill, and subagent resolvers receive the visible conversation history and incoming message in `ctx.messages`, oldest first. Request context is included, and history projection still applies. Read these messages from the handler's second argument; the event itself contains turn metadata. Instruction resolvers use the separate snapshot described under [Dynamic instructions](#dynamic-instructions).
|
|
379
383
|
|
|
380
|
-
A message that steers a held turn joins it without another `turn.started`, as does a completed sign-in, so `turn.started` resolvers do not see it; `step.started` resolvers do. A message sent while a session-limit prompt waits
|
|
384
|
+
A message that steers a held turn joins it without another `turn.started`, as does a completed sign-in, so `turn.started` resolvers do not see it; `step.started` resolvers do. A message sent while a session-limit prompt waits queues in the held turn without another `turn.started`. After Continue grants the budget, `step.started` resolvers see the queued message before the model runs. When memory recall runs, its results appear in the projected snapshot before incoming input.
|
|
381
385
|
|
|
382
386
|
### Execution order
|
|
383
387
|
|
package/docs/sandbox/index.mdx
CHANGED
|
@@ -28,6 +28,8 @@ export default defineTool({
|
|
|
28
28
|
|
|
29
29
|
Relative paths resolve under `/workspace`. `run()` returns `{ exitCode, stdout, stderr }`; a nonzero exit code does not throw automatically. Use `spawn()` for a long-running process.
|
|
30
30
|
|
|
31
|
+
Built-in environments set `AI_AGENT=eve` on every `run()` and `spawn()` call, including the `bash` tool and `prepare`, so agent-aware CLIs such as `vercel` skip interactive prompts. To use a different value, set `AI_AGENT` in the environment's `env` option or pass it in the `env` of one `run()` or `spawn()` call.
|
|
32
|
+
|
|
31
33
|
Pass the configured environment to preserve its specific session capabilities in authored runtime code:
|
|
32
34
|
|
|
33
35
|
```ts
|
|
@@ -232,7 +232,7 @@ The run picks back up exactly where it parked. Because the pause is durable, not
|
|
|
232
232
|
|
|
233
233
|
When a subagent requests input, eve emits the same `input.requested` event on its parent session. Answering through that parent session routes the response directly to the blocked child without invoking the parent model.
|
|
234
234
|
|
|
235
|
-
|
|
235
|
+
Approval is consent only. An approved tool call runs with the requesting user's identity, connections, and credentials, including its policy recheck. The approver's access is never lent to the call. Subsequent tool calls in the turn also stay with the original owner.
|
|
236
236
|
|
|
237
237
|
For approval requests, a follow-up message that doesn't match an option steers the turn instead of answering it. eve cancels the turn's pending approval, so the call doesn't run and `input.resolved` reports `outcome: "ignored"`, and the model reads the message next. This happens even when the message is sent with `turnPolicy: "queue"`, because a turn held on a person can't end until they act. Calls the person already approved in the same batch still run. A message from someone other than the person the turn serves waits until the turn ends. Cancelling the turn withdraws its approval: the call doesn't run, `input.resolved` reports `outcome: "cancelled"`, and a later answer to it approves nothing.
|
|
238
238
|
|
package/package.json
CHANGED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { SessionAuthContext } from "#channel/types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Runs `fn` with `caller` as the session's current caller. Writes still reach
|
|
4
|
-
* the outer context; only reads of the caller change, so work running beside
|
|
5
|
-
* `fn` in the same step keeps the outer caller.
|
|
6
|
-
*/
|
|
7
|
-
export declare function runAsCaller<T>(caller: SessionAuthContext, fn: () => T): T;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{contextStorage}from"#context/container.js";import{AuthKey,SessionKey}from"#context/keys.js";function runAsCaller(e,t){let n=contextStorage.getStore();return n===void 0?t():contextStorage.run(new CallerScope(n,e),t)}var CallerScope=class{#e;#t;constructor(e,t){this.#t=e,this.#e=t}get localDevRequest(){return this.#t.localDevRequest}get(e){if(e.name===AuthKey.name)return this.#e;if(e.name===SessionKey.name){let e=this.#t.get(SessionKey);return e===void 0?void 0:{...e,auth:{...e.auth,current:this.#e}}}return this.#t.get(e)}require(e){if(!this.has(e))throw Error(`Context key "${e.name}" is not set.`);return this.get(e)}has(e){return e.name===AuthKey.name||this.#t.has(e)}set(e,t){return this.#t.set(e,t)}ensure(e,t){return this.#t.ensure(e,t)}delete(e){return this.#t.delete(e)}entries(){return this.#t.entries()}setVirtualContext(e,t){this.#t.setVirtualContext(e,t)}};export{runAsCaller};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { type SessionStepState } from "#execution/publish-session-events.js";
|
|
2
|
-
import { type SessionStateTransition } from "#execution/session/state-delta.js";
|
|
3
|
-
import type { WorkflowToolRunAgentStartedMessage, WorkflowToolRunRef } from "#execution/tools/workflow/messages.js";
|
|
4
|
-
import type { JsonValue } from "#shared/json.js";
|
|
5
|
-
/** Publishes a workflow tool run's `ctx.report()` update as `action.partial`. */
|
|
6
|
-
export declare function emitWorkflowToolRunReportStep(input: SessionStepState & {
|
|
7
|
-
readonly from: WorkflowToolRunRef;
|
|
8
|
-
readonly update: JsonValue;
|
|
9
|
-
}): Promise<SessionStateTransition>;
|
|
10
|
-
/** Publishes `agent.started`, in order, for sessions workflow tool runs opened. */
|
|
11
|
-
export declare function emitAgentStartedStep(input: SessionStepState & {
|
|
12
|
-
readonly messages: readonly WorkflowToolRunAgentStartedMessage[];
|
|
13
|
-
}): Promise<SessionStateTransition>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{createActionPartialEvent,createAgentStartedEvent}from"#protocol/message.js";import{publishSessionEvents}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{createRuntimeToolResultFromValue}from"#harness/action-result-helpers.js";async function emitWorkflowToolRunReportStep(e){"use step";let t=createActionPartialEvent({result:createRuntimeToolResultFromValue({callId:e.from.callId,output:e.update,toolName:e.from.toolName}),sequence:e.from.sequence,stepIndex:e.from.stepIndex,turnId:e.from.turnId});return await withSessionStateDelta(e,e=>publishSessionEvents(e,[t]))}async function emitAgentStartedStep(e){"use step";let t=e.messages.map(({from:t,session:n})=>createAgentStartedEvent({callId:t.callId,name:n.name,parentSessionId:e.sessionState.sessionId,remote:n.kind===`remote`?{url:n.url,...n.resolverId!==void 0&&{resolverId:n.resolverId}}:void 0,sessionId:n.sessionId,...t.taskId!==void 0&&{taskId:t.taskId},turnId:t.turnId}));return await withSessionStateDelta(e,e=>publishSessionEvents(e,t))}export{emitAgentStartedStep,emitWorkflowToolRunReportStep};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { SessionAuthContext } from "#channel/types.js";
|
|
2
|
-
import type { InputRequest } from "#shared/input.js";
|
|
3
|
-
import type { SessionStateMap } from "#harness/types.js";
|
|
4
|
-
/** Who approved each of the `approved` calls, by call id. */
|
|
5
|
-
export declare function approversOf(approved: readonly InputRequest[], state: SessionStateMap | undefined): Readonly<Record<string, SessionAuthContext>>;
|
|
6
|
-
/**
|
|
7
|
-
* Records who approved each of the `approved` calls, so each runs as its approver while the rest
|
|
8
|
-
* of the turn keeps the turn's own caller.
|
|
9
|
-
*/
|
|
10
|
-
export declare function setApprovedCallCallers(approved: readonly InputRequest[], state: SessionStateMap | undefined): void;
|
|
11
|
-
/** Runs `fn` as the call's approver when `callId` is an approved call; otherwise as is. */
|
|
12
|
-
export declare function runAsApprover<T>(callId: string | undefined, fn: () => T): T;
|
|
13
|
-
/** A streaming call's body runs on each `next()`, so each one runs as the approver too. */
|
|
14
|
-
export declare function iterateAsApprover<T>(callId: string | undefined, iterable: AsyncIterable<T>): AsyncIterable<T>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{approverOfRequest}from"./candidates.js";import{contextStorage}from"#context/container.js";import{ContextKey}from"#context/key.js";import{runAsCaller}from"#context/caller-scope.js";const ApprovedCallCallersKey=new ContextKey(`eve.approvedCallCallers`);function approversOf(e,t){let n={};for(let r of e){if(r.action===void 0)continue;let e=approverOfRequest(t,r.requestId);e!==void 0&&(n[r.action.callId]=e)}return n}function setApprovedCallCallers(e,t){let n=contextStorage.getStore();n!==void 0&&n.setVirtualContext(ApprovedCallCallersKey,new Map(Object.entries(approversOf(e,t))))}function runAsApprover(e,t){let n=e===void 0?void 0:contextStorage.getStore()?.get(ApprovedCallCallersKey)?.get(e);return n===void 0?t():runAsCaller(n,t)}async function*iterateAsApprover(e,t){let n=t[Symbol.asyncIterator]();try{for(;;){let t=await runAsApprover(e,()=>n.next());if(t.done===!0)return;yield t.value}}finally{await n.return?.()}}export{approversOf,iterateAsApprover,runAsApprover,setApprovedCallCallers};
|