@yolk-sdk/agent 0.1.0-canary.16 → 0.1.0-canary.17

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/README.md CHANGED
@@ -57,6 +57,8 @@ import {
57
57
  import {
58
58
  makeNonRecursiveTaskToolModule,
59
59
  makeTaskToolResult,
60
+ modelVisibleToolError,
61
+ modelVisibleToolErrorStructuredContent,
60
62
  makeQuestionToolModule,
61
63
  resolveTools
62
64
  } from '@yolk-sdk/agent/tools'
@@ -210,6 +212,17 @@ Recommended setup:
210
212
 
211
213
  See `examples/next/lib/agents/workflow-runtime/text-response.ts` for host-owned execution wiring.
212
214
 
215
+ ## Tool failures
216
+
217
+ Use `modelVisibleToolError(...)` for expected tool-domain failures the model can recover
218
+ from, such as invalid arguments, not-found resources, denied policy, or unavailable upstream
219
+ data. `makeTool` converts these failures into `ToolResult.isError = true` so the agent can
220
+ see the message and continue. The result includes structured content with `type`, `tool`,
221
+ `reason`, `message`, and optional `details` for UI/runtime handling.
222
+
223
+ Use `ToolError` for fatal runtime/tool infrastructure failures: broken wiring, auth/config
224
+ defects, storage failures, or implementation bugs.
225
+
213
226
  ## Host responsibilities
214
227
 
215
228
  - Choose models/providers and map provider streams into protocol events.
@@ -1,6 +1,6 @@
1
1
  import { AgentContentCapabilities, AgentModelCapabilities, textImageDocumentModelCapabilities, textImageModelCapabilities, textOnlyModelCapabilities } from "./capability.mjs";
2
2
  import { AttachmentContentPart, AttachmentSource, AttachmentSourceResolver, AudioPart, Content, ContentPart, DocumentPart, ImagePart, InlineBase64AttachmentSource, RefAttachmentSource, TextPart, UrlAttachmentSource, appendTextToContent, attachmentSourceBase64, attachmentSourceDataUrl, attachmentSourcePreview, contentPartPreview, contentPartText, contentParts, contentPreview, contentText, inlineBase64AttachmentSource, inlineBase64Source, isContentEmpty, refAttachmentSource, resolveContentAttachmentSources, urlAttachmentSource } from "./content.mjs";
3
- import { HitlRequest, HitlResponse, HitlResponseSource, PlainHitlResponse, PlainQuestionAnswer, PlainQuestionResponse, PlainToolApprovalResponse, QuestionAnswer, QuestionOption, QuestionPrompt, QuestionRequest, QuestionResponse, QuestionResponseOutcome, QuestionResponseStructuredContent, QuestionToolParams, ToolApprovalDecision, ToolApprovalMode, ToolApprovalPolicy, ToolApprovalRequest, ToolApprovalResponse, ToolCall, ToolDef, ToolResult, formatQuestionResponseContent, plainHitlResponse, plainQuestionAnswer, plainQuestionResponse, plainToolApprovalResponse, questionResponseStructuredContent } from "./tool.mjs";
3
+ import { ErrorToolResultInput, HitlRequest, HitlResponse, HitlResponseSource, PlainHitlResponse, PlainQuestionAnswer, PlainQuestionResponse, PlainToolApprovalResponse, QuestionAnswer, QuestionOption, QuestionPrompt, QuestionRequest, QuestionResponse, QuestionResponseOutcome, QuestionResponseStructuredContent, QuestionToolParams, ToolApprovalDecision, ToolApprovalMode, ToolApprovalPolicy, ToolApprovalRequest, ToolApprovalResponse, ToolCall, ToolDef, ToolResult, formatQuestionResponseContent, makeErrorToolResult, plainHitlResponse, plainQuestionAnswer, plainQuestionResponse, plainToolApprovalResponse, questionResponseStructuredContent } from "./tool.mjs";
4
4
  import { AgentMessage, AssistantAgentMessage, AssistantPart, AssistantReasoningPart, AssistantTextPart, HostToolCallPart, MessageAnnotations, MessageAuthor, MessageEnvelope, ProviderToolCallPart, ProviderToolResultPart, ToolResultMessage, UserMessage, assistantContent, assistantHostToolCalls, assistantReasoningText, messageContextText, prependMessageContextToContent } from "./message.mjs";
5
5
  import { AgentInputUsage, AgentOutputUsage, AgentUsage, addAgentUsage, zeroAgentUsage } from "./usage.mjs";
6
6
  import { AgentAwaitingInput, AgentEnd, AgentError, AgentErrorCode, AgentEvent, AgentRetry, AgentStart, AssistantMessageEvent, CompactionEnd, CompactionStart, LLMReasoningDelta, LLMStreamEnd, LLMStreamStart, LLMTextDelta, ProviderToolResult, QuestionAnswered, QuestionCancelled, QuestionRequested, SubagentCompleted, SubagentStarted, SubagentStatus, ToolApprovalDenied, ToolApprovalGranted, ToolApprovalRequested, ToolExecutionCompleted, ToolExecutionError, ToolExecutionStarted, ToolInputDelta, ToolInputEnd, ToolInputStart, TurnEnd, TurnStart, UsageUpdate, hitlResponseEvent, makeSubagentRunId } from "./event.mjs";
@@ -10,5 +10,5 @@ import { AgentWebSocketClientMessage, AgentWebSocketServerMessage, QuestionRespo
10
10
  //#region src/protocol/index.d.ts
11
11
  type MessageId = string;
12
12
  //#endregion
13
- export { AgentAwaitingInput, AgentContentCapabilities, AgentEnd, AgentError, AgentErrorCode, AgentEvent, AgentInputUsage, AgentMessage, AgentModelCapabilities, AgentOutputUsage, AgentReasoningEffort, AgentRetry, AgentStart, AgentUsage, AgentWebSocketClientMessage, AgentWebSocketServerMessage, AssistantAgentMessage, AssistantMessageEvent, AssistantPart, AssistantReasoningPart, AssistantTextPart, type AttachmentContentPart, AttachmentSource, type AttachmentSourceResolver, AudioPart, CompactionEnd, CompactionStart, Content, ContentPart, DocumentPart, HitlRequest, HitlResponse, HitlResponseSource, HostToolCallPart, ImagePart, InlineBase64AttachmentSource, LLMReasoningDelta, LLMStreamEnd, LLMStreamStart, LLMTextDelta, MessageAnnotations, MessageAuthor, type MessageEnvelope, MessageId, type PlainHitlResponse, type PlainQuestionAnswer, type PlainQuestionResponse, type PlainToolApprovalResponse, ProviderToolCallPart, ProviderToolResult, ProviderToolResultPart, QuestionAnswer, QuestionAnswered, QuestionCancelled, QuestionOption, QuestionPrompt, QuestionRequest, QuestionRequested, QuestionResponse, QuestionResponseInput, QuestionResponseOutcome, type QuestionResponseStructuredContent, QuestionToolParams, RefAttachmentSource, SessionSnapshot, SubagentCompleted, SubagentStarted, SubagentStatus, TextPart, ToolApprovalDecision, ToolApprovalDenied, ToolApprovalGranted, ToolApprovalMode, ToolApprovalPolicy, ToolApprovalRequest, ToolApprovalRequested, ToolApprovalResponse, ToolApprovalResponseInput, ToolCall, ToolDef, ToolExecutionCompleted, ToolExecutionError, ToolExecutionStarted, ToolInputDelta, ToolInputEnd, ToolInputStart, ToolResult, ToolResultMessage, TurnEnd, TurnStart, UrlAttachmentSource, UsageUpdate, UserInput, UserMessage, addAgentUsage, appendTextToContent, assistantContent, assistantHostToolCalls, assistantReasoningText, attachmentSourceBase64, attachmentSourceDataUrl, attachmentSourcePreview, contentPartPreview, contentPartText, contentParts, contentPreview, contentText, formatQuestionResponseContent, hitlResponseEvent, inlineBase64AttachmentSource, inlineBase64Source, isContentEmpty, makeSubagentRunId, messageContextText, plainHitlResponse, plainQuestionAnswer, plainQuestionResponse, plainToolApprovalResponse, prependMessageContextToContent, questionResponseStructuredContent, refAttachmentSource, resolveContentAttachmentSources, textImageDocumentModelCapabilities, textImageModelCapabilities, textOnlyModelCapabilities, urlAttachmentSource, zeroAgentUsage };
13
+ export { AgentAwaitingInput, AgentContentCapabilities, AgentEnd, AgentError, AgentErrorCode, AgentEvent, AgentInputUsage, AgentMessage, AgentModelCapabilities, AgentOutputUsage, AgentReasoningEffort, AgentRetry, AgentStart, AgentUsage, AgentWebSocketClientMessage, AgentWebSocketServerMessage, AssistantAgentMessage, AssistantMessageEvent, AssistantPart, AssistantReasoningPart, AssistantTextPart, type AttachmentContentPart, AttachmentSource, type AttachmentSourceResolver, AudioPart, CompactionEnd, CompactionStart, Content, ContentPart, DocumentPart, type ErrorToolResultInput, HitlRequest, HitlResponse, HitlResponseSource, HostToolCallPart, ImagePart, InlineBase64AttachmentSource, LLMReasoningDelta, LLMStreamEnd, LLMStreamStart, LLMTextDelta, MessageAnnotations, MessageAuthor, type MessageEnvelope, MessageId, type PlainHitlResponse, type PlainQuestionAnswer, type PlainQuestionResponse, type PlainToolApprovalResponse, ProviderToolCallPart, ProviderToolResult, ProviderToolResultPart, QuestionAnswer, QuestionAnswered, QuestionCancelled, QuestionOption, QuestionPrompt, QuestionRequest, QuestionRequested, QuestionResponse, QuestionResponseInput, QuestionResponseOutcome, type QuestionResponseStructuredContent, QuestionToolParams, RefAttachmentSource, SessionSnapshot, SubagentCompleted, SubagentStarted, SubagentStatus, TextPart, ToolApprovalDecision, ToolApprovalDenied, ToolApprovalGranted, ToolApprovalMode, ToolApprovalPolicy, ToolApprovalRequest, ToolApprovalRequested, ToolApprovalResponse, ToolApprovalResponseInput, ToolCall, ToolDef, ToolExecutionCompleted, ToolExecutionError, ToolExecutionStarted, ToolInputDelta, ToolInputEnd, ToolInputStart, ToolResult, ToolResultMessage, TurnEnd, TurnStart, UrlAttachmentSource, UsageUpdate, UserInput, UserMessage, addAgentUsage, appendTextToContent, assistantContent, assistantHostToolCalls, assistantReasoningText, attachmentSourceBase64, attachmentSourceDataUrl, attachmentSourcePreview, contentPartPreview, contentPartText, contentParts, contentPreview, contentText, formatQuestionResponseContent, hitlResponseEvent, inlineBase64AttachmentSource, inlineBase64Source, isContentEmpty, makeErrorToolResult, makeSubagentRunId, messageContextText, plainHitlResponse, plainQuestionAnswer, plainQuestionResponse, plainToolApprovalResponse, prependMessageContextToContent, questionResponseStructuredContent, refAttachmentSource, resolveContentAttachmentSources, textImageDocumentModelCapabilities, textImageModelCapabilities, textOnlyModelCapabilities, urlAttachmentSource, zeroAgentUsage };
14
14
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/protocol/index.ts"],"mappings":";;;;;;;;;;KA+IY,SAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/protocol/index.ts"],"mappings":";;;;;;;;;;KAiJY,SAAA"}
@@ -1,9 +1,9 @@
1
1
  import { AgentContentCapabilities, AgentModelCapabilities, textImageDocumentModelCapabilities, textImageModelCapabilities, textOnlyModelCapabilities } from "./capability.mjs";
2
2
  import { AttachmentSource, AudioPart, Content, ContentPart, DocumentPart, ImagePart, InlineBase64AttachmentSource, RefAttachmentSource, TextPart, UrlAttachmentSource, appendTextToContent, attachmentSourceBase64, attachmentSourceDataUrl, attachmentSourcePreview, contentPartPreview, contentPartText, contentParts, contentPreview, contentText, inlineBase64AttachmentSource, inlineBase64Source, isContentEmpty, refAttachmentSource, resolveContentAttachmentSources, urlAttachmentSource } from "./content.mjs";
3
- import { HitlRequest, HitlResponse, HitlResponseSource, QuestionAnswer, QuestionOption, QuestionPrompt, QuestionRequest, QuestionResponse, QuestionResponseOutcome, QuestionToolParams, ToolApprovalDecision, ToolApprovalMode, ToolApprovalPolicy, ToolApprovalRequest, ToolApprovalResponse, ToolCall, ToolDef, ToolResult, formatQuestionResponseContent, plainHitlResponse, plainQuestionAnswer, plainQuestionResponse, plainToolApprovalResponse, questionResponseStructuredContent } from "./tool.mjs";
3
+ import { HitlRequest, HitlResponse, HitlResponseSource, QuestionAnswer, QuestionOption, QuestionPrompt, QuestionRequest, QuestionResponse, QuestionResponseOutcome, QuestionToolParams, ToolApprovalDecision, ToolApprovalMode, ToolApprovalPolicy, ToolApprovalRequest, ToolApprovalResponse, ToolCall, ToolDef, ToolResult, formatQuestionResponseContent, makeErrorToolResult, plainHitlResponse, plainQuestionAnswer, plainQuestionResponse, plainToolApprovalResponse, questionResponseStructuredContent } from "./tool.mjs";
4
4
  import { AgentMessage, AssistantAgentMessage, AssistantPart, AssistantReasoningPart, AssistantTextPart, HostToolCallPart, MessageAnnotations, MessageAuthor, ProviderToolCallPart, ProviderToolResultPart, ToolResultMessage, UserMessage, assistantContent, assistantHostToolCalls, assistantReasoningText, messageContextText, prependMessageContextToContent } from "./message.mjs";
5
5
  import { AgentInputUsage, AgentOutputUsage, AgentUsage, addAgentUsage, zeroAgentUsage } from "./usage.mjs";
6
6
  import { AgentAwaitingInput, AgentEnd, AgentError, AgentErrorCode, AgentEvent, AgentRetry, AgentStart, AssistantMessageEvent, CompactionEnd, CompactionStart, LLMReasoningDelta, LLMStreamEnd, LLMStreamStart, LLMTextDelta, ProviderToolResult, QuestionAnswered, QuestionCancelled, QuestionRequested, SubagentCompleted, SubagentStarted, SubagentStatus, ToolApprovalDenied, ToolApprovalGranted, ToolApprovalRequested, ToolExecutionCompleted, ToolExecutionError, ToolExecutionStarted, ToolInputDelta, ToolInputEnd, ToolInputStart, TurnEnd, TurnStart, UsageUpdate, hitlResponseEvent, makeSubagentRunId } from "./event.mjs";
7
7
  import { AgentReasoningEffort } from "./reasoning.mjs";
8
8
  import { AgentWebSocketClientMessage, AgentWebSocketServerMessage, QuestionResponseInput, SessionSnapshot, ToolApprovalResponseInput, UserInput } from "./session.mjs";
9
- export { AgentAwaitingInput, AgentContentCapabilities, AgentEnd, AgentError, AgentErrorCode, AgentEvent, AgentInputUsage, AgentMessage, AgentModelCapabilities, AgentOutputUsage, AgentReasoningEffort, AgentRetry, AgentStart, AgentUsage, AgentWebSocketClientMessage, AgentWebSocketServerMessage, AssistantAgentMessage, AssistantMessageEvent, AssistantPart, AssistantReasoningPart, AssistantTextPart, AttachmentSource, AudioPart, CompactionEnd, CompactionStart, Content, ContentPart, DocumentPart, HitlRequest, HitlResponse, HitlResponseSource, HostToolCallPart, ImagePart, InlineBase64AttachmentSource, LLMReasoningDelta, LLMStreamEnd, LLMStreamStart, LLMTextDelta, MessageAnnotations, MessageAuthor, ProviderToolCallPart, ProviderToolResult, ProviderToolResultPart, QuestionAnswer, QuestionAnswered, QuestionCancelled, QuestionOption, QuestionPrompt, QuestionRequest, QuestionRequested, QuestionResponse, QuestionResponseInput, QuestionResponseOutcome, QuestionToolParams, RefAttachmentSource, SessionSnapshot, SubagentCompleted, SubagentStarted, SubagentStatus, TextPart, ToolApprovalDecision, ToolApprovalDenied, ToolApprovalGranted, ToolApprovalMode, ToolApprovalPolicy, ToolApprovalRequest, ToolApprovalRequested, ToolApprovalResponse, ToolApprovalResponseInput, ToolCall, ToolDef, ToolExecutionCompleted, ToolExecutionError, ToolExecutionStarted, ToolInputDelta, ToolInputEnd, ToolInputStart, ToolResult, ToolResultMessage, TurnEnd, TurnStart, UrlAttachmentSource, UsageUpdate, UserInput, UserMessage, addAgentUsage, appendTextToContent, assistantContent, assistantHostToolCalls, assistantReasoningText, attachmentSourceBase64, attachmentSourceDataUrl, attachmentSourcePreview, contentPartPreview, contentPartText, contentParts, contentPreview, contentText, formatQuestionResponseContent, hitlResponseEvent, inlineBase64AttachmentSource, inlineBase64Source, isContentEmpty, makeSubagentRunId, messageContextText, plainHitlResponse, plainQuestionAnswer, plainQuestionResponse, plainToolApprovalResponse, prependMessageContextToContent, questionResponseStructuredContent, refAttachmentSource, resolveContentAttachmentSources, textImageDocumentModelCapabilities, textImageModelCapabilities, textOnlyModelCapabilities, urlAttachmentSource, zeroAgentUsage };
9
+ export { AgentAwaitingInput, AgentContentCapabilities, AgentEnd, AgentError, AgentErrorCode, AgentEvent, AgentInputUsage, AgentMessage, AgentModelCapabilities, AgentOutputUsage, AgentReasoningEffort, AgentRetry, AgentStart, AgentUsage, AgentWebSocketClientMessage, AgentWebSocketServerMessage, AssistantAgentMessage, AssistantMessageEvent, AssistantPart, AssistantReasoningPart, AssistantTextPart, AttachmentSource, AudioPart, CompactionEnd, CompactionStart, Content, ContentPart, DocumentPart, HitlRequest, HitlResponse, HitlResponseSource, HostToolCallPart, ImagePart, InlineBase64AttachmentSource, LLMReasoningDelta, LLMStreamEnd, LLMStreamStart, LLMTextDelta, MessageAnnotations, MessageAuthor, ProviderToolCallPart, ProviderToolResult, ProviderToolResultPart, QuestionAnswer, QuestionAnswered, QuestionCancelled, QuestionOption, QuestionPrompt, QuestionRequest, QuestionRequested, QuestionResponse, QuestionResponseInput, QuestionResponseOutcome, QuestionToolParams, RefAttachmentSource, SessionSnapshot, SubagentCompleted, SubagentStarted, SubagentStatus, TextPart, ToolApprovalDecision, ToolApprovalDenied, ToolApprovalGranted, ToolApprovalMode, ToolApprovalPolicy, ToolApprovalRequest, ToolApprovalRequested, ToolApprovalResponse, ToolApprovalResponseInput, ToolCall, ToolDef, ToolExecutionCompleted, ToolExecutionError, ToolExecutionStarted, ToolInputDelta, ToolInputEnd, ToolInputStart, ToolResult, ToolResultMessage, TurnEnd, TurnStart, UrlAttachmentSource, UsageUpdate, UserInput, UserMessage, addAgentUsage, appendTextToContent, assistantContent, assistantHostToolCalls, assistantReasoningText, attachmentSourceBase64, attachmentSourceDataUrl, attachmentSourcePreview, contentPartPreview, contentPartText, contentParts, contentPreview, contentText, formatQuestionResponseContent, hitlResponseEvent, inlineBase64AttachmentSource, inlineBase64Source, isContentEmpty, makeErrorToolResult, makeSubagentRunId, messageContextText, plainHitlResponse, plainQuestionAnswer, plainQuestionResponse, plainToolApprovalResponse, prependMessageContextToContent, questionResponseStructuredContent, refAttachmentSource, resolveContentAttachmentSources, textImageDocumentModelCapabilities, textImageModelCapabilities, textOnlyModelCapabilities, urlAttachmentSource, zeroAgentUsage };
@@ -1,4 +1,4 @@
1
- import { AudioPart, DocumentPart, ImagePart, TextPart } from "./content.mjs";
1
+ import { AudioPart, Content, DocumentPart, ImagePart, TextPart } from "./content.mjs";
2
2
  import * as Schema from "effect/Schema";
3
3
 
4
4
  //#region src/protocol/tool.d.ts
@@ -33,6 +33,12 @@ declare const ToolResult_base: Schema.Class<ToolResult, Schema.Struct<{
33
33
  readonly structuredContent: Schema.optional<Schema.Unknown>;
34
34
  }>, {}>;
35
35
  declare class ToolResult extends ToolResult_base {}
36
+ type ErrorToolResultInput = {
37
+ readonly toolCallId: string;
38
+ readonly content: Content;
39
+ readonly structuredContent?: unknown;
40
+ };
41
+ declare const makeErrorToolResult: (input: ErrorToolResultInput) => ToolResult;
36
42
  declare const ToolApprovalRequest_base: Schema.Class<ToolApprovalRequest, Schema.TaggedStruct<"ToolApprovalRequest", {
37
43
  readonly requestId: Schema.Trimmed;
38
44
  readonly toolCallId: Schema.Trimmed;
@@ -132,5 +138,5 @@ type HitlRequest = typeof HitlRequest.Type;
132
138
  declare const HitlResponse: Schema.Union<readonly [typeof ToolApprovalResponse, typeof QuestionResponse]>;
133
139
  type HitlResponse = typeof HitlResponse.Type;
134
140
  //#endregion
135
- export { HitlRequest, HitlResponse, HitlResponseSource, PlainHitlResponse, PlainQuestionAnswer, PlainQuestionResponse, PlainToolApprovalResponse, QuestionAnswer, QuestionOption, QuestionPrompt, QuestionRequest, QuestionResponse, QuestionResponseOutcome, QuestionResponseStructuredContent, QuestionToolParams, ToolApprovalDecision, ToolApprovalMode, ToolApprovalPolicy, ToolApprovalRequest, ToolApprovalResponse, ToolCall, ToolDef, ToolResult, formatQuestionResponseContent, plainHitlResponse, plainQuestionAnswer, plainQuestionResponse, plainToolApprovalResponse, questionResponseStructuredContent };
141
+ export { ErrorToolResultInput, HitlRequest, HitlResponse, HitlResponseSource, PlainHitlResponse, PlainQuestionAnswer, PlainQuestionResponse, PlainToolApprovalResponse, QuestionAnswer, QuestionOption, QuestionPrompt, QuestionRequest, QuestionResponse, QuestionResponseOutcome, QuestionResponseStructuredContent, QuestionToolParams, ToolApprovalDecision, ToolApprovalMode, ToolApprovalPolicy, ToolApprovalRequest, ToolApprovalResponse, ToolCall, ToolDef, ToolResult, formatQuestionResponseContent, makeErrorToolResult, plainHitlResponse, plainQuestionAnswer, plainQuestionResponse, plainToolApprovalResponse, questionResponseStructuredContent };
136
142
  //# sourceMappingURL=tool.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool.d.mts","names":[],"sources":["../../src/protocol/tool.ts"],"mappings":";;;;cAKa,kBAAA,EAAkB,MAAA,CAAA,QAAA;AAAA,KACnB,kBAAA,UAA4B,kBAAA,CAAmB,IAAI;AAAA,cAElD,oBAAA,EAAoB,MAAA,CAAA,QAAA;AAAA,KACrB,oBAAA,UAA8B,oBAAA,CAAqB,IAAI;AAAA,cAEtD,gBAAA,EAAgB,MAAA,CAAA,QAAA;AAAA,KACjB,gBAAA,UAA0B,gBAAA,CAAiB,IAAI;AAAA,cAAA,uBAAA;;;;cAE9C,kBAAA,SAA2B,uBAGtC;AAAA,cAAG,aAAA;;;;;cAEQ,QAAA,SAAiB,aAI5B;AAAA,cAAG,YAAA;;;;;;cAEQ,OAAA,SAAgB,YAK3B;AAAA,cAAG,eAAA;;;;;;cAEQ,UAAA,SAAmB,eAK9B;AAAA,cAAG,wBAAA;;;;;;cAEQ,mBAAA,SAA4B,wBAQxC;AAAA,cAAG,yBAAA;;;;;;;cAES,oBAAA,SAA6B,yBASzC;AAAA,cAAG,mBAAA;;;;;cAES,cAAA,SAAuB,mBAIlC;AAAA,cAAG,mBAAA;;;;;;;;cAEQ,cAAA,SAAuB,mBAOlC;AAAA,cAAG,uBAAA;;;cAEQ,kBAAA,SAA2B,uBAEtC;AAAA,cAAG,oBAAA;;;;;;cAEQ,eAAA,SAAwB,oBAKnC;AAAA,cAAG,mBAAA;;;;;cAEQ,cAAA,SAAuB,mBAIlC;AAAA,KAEU,mBAAA;EAAA,SACD,UAAA;EAAA,SACA,SAAA,GAAY,aAAa;EAAA,SACzB,YAAA;AAAA;AAAA,cAGE,uBAAA,EAAuB,MAAA,CAAA,QAAA;AAAA,KACxB,uBAAA,UAAiC,uBAAA,CAAwB,IAAI;AAAA,cAAA,qBAAA;;;;;;;;cAE5D,gBAAA,SAAyB,qBAOpC;AAAA,KAEU,qBAAA;EAAA,SACD,IAAA;EAAA,SACA,SAAA;EAAA,SACA,UAAA;EAAA,SACA,OAAA,EAAS,uBAAA;EAAA,SACT,MAAA,EAAQ,kBAAA;EAAA,SACR,OAAA,GAAU,aAAA,CAAc,mBAAA;EAAA,SACxB,MAAA;AAAA;AAAA,KAGC,yBAAA;EAAA,SACD,IAAA;EAAA,SACA,SAAA;EAAA,SACA,UAAA;EAAA,SACA,QAAA,EAAU,oBAAA;EAAA,SACV,MAAA,EAAQ,kBAAkB;EAAA,SAC1B,MAAA;AAAA;AAAA,KAGC,iBAAA,GAAoB,yBAAA,GAA4B,qBAAqB;AAAA,KAErE,iCAAA;EAAA,SACD,IAAA;EAAA,SACA,OAAA,EAAS,uBAAA;EAAA,SACT,OAAA,EAAS,aAAA,CAAc,mBAAA;EAAA,SACvB,MAAA;EAAA,SACA,MAAA,EAAQ,kBAAA;AAAA;AAAA,cAGN,mBAAA,GAAuB,MAAA,EAAQ,cAAA,KAAiB,mBAI3D;AAAA,cAEW,qBAAA,GAAyB,QAAA,EAAU,gBAAA,KAAmB,qBAUjE;AAAA,cAEW,yBAAA,GACX,QAAA,EAAU,oBAAA,KACT,yBAOD;AAAA,cAEW,iBAAA,GAAqB,QAAA,EAAU,YAAA,KAAe,iBAO1D;AAAA,cAEY,iCAAA,GACX,QAAA,EAAU,gBAAA,KACT,iCAMD;AAAA,cAqBW,6BAAA,GACX,QAAA,EAAU,gBAAA,EACV,SAAA,GAAW,aAAA,CAAc,cAAA;AAAA,cAoBd,WAAA,EAAW,MAAA,CAAA,KAAA,kBAAA,mBAAA,SAAA,eAAA;AAAA,KACZ,WAAA,UAAqB,WAAA,CAAY,IAAI;AAAA,cAEpC,YAAA,EAAY,MAAA,CAAA,KAAA,kBAAA,oBAAA,SAAA,gBAAA;AAAA,KACb,YAAA,UAAsB,YAAA,CAAa,IAAI"}
1
+ {"version":3,"file":"tool.d.mts","names":[],"sources":["../../src/protocol/tool.ts"],"mappings":"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"}
@@ -30,6 +30,12 @@ var ToolResult = class extends Schema.Class("ToolResult")({
30
30
  isError: Schema.optional(Schema.Boolean),
31
31
  structuredContent: Schema.optional(Schema.Unknown)
32
32
  }) {};
33
+ const makeErrorToolResult = (input) => ToolResult.make({
34
+ toolCallId: input.toolCallId,
35
+ content: input.content,
36
+ isError: true,
37
+ ...input.structuredContent === void 0 ? {} : { structuredContent: input.structuredContent }
38
+ });
33
39
  var ToolApprovalRequest = class extends Schema.TaggedClass()("ToolApprovalRequest", {
34
40
  requestId: NonEmptyTrimmedString,
35
41
  toolCallId: NonEmptyTrimmedString,
@@ -132,6 +138,6 @@ const formatQuestionResponseContent = (response, questions = []) => {
132
138
  const HitlRequest = Schema.Union([ToolApprovalRequest, QuestionRequest]);
133
139
  const HitlResponse = Schema.Union([ToolApprovalResponse, QuestionResponse]);
134
140
  //#endregion
135
- export { HitlRequest, HitlResponse, HitlResponseSource, QuestionAnswer, QuestionOption, QuestionPrompt, QuestionRequest, QuestionResponse, QuestionResponseOutcome, QuestionToolParams, ToolApprovalDecision, ToolApprovalMode, ToolApprovalPolicy, ToolApprovalRequest, ToolApprovalResponse, ToolCall, ToolDef, ToolResult, formatQuestionResponseContent, plainHitlResponse, plainQuestionAnswer, plainQuestionResponse, plainToolApprovalResponse, questionResponseStructuredContent };
141
+ export { HitlRequest, HitlResponse, HitlResponseSource, QuestionAnswer, QuestionOption, QuestionPrompt, QuestionRequest, QuestionResponse, QuestionResponseOutcome, QuestionToolParams, ToolApprovalDecision, ToolApprovalMode, ToolApprovalPolicy, ToolApprovalRequest, ToolApprovalResponse, ToolCall, ToolDef, ToolResult, formatQuestionResponseContent, makeErrorToolResult, plainHitlResponse, plainQuestionAnswer, plainQuestionResponse, plainToolApprovalResponse, questionResponseStructuredContent };
136
142
 
137
143
  //# sourceMappingURL=tool.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool.mjs","names":[],"sources":["../../src/protocol/tool.ts"],"sourcesContent":["import * as Schema from 'effect/Schema'\nimport { Content } from './content.ts'\n\nconst NonEmptyTrimmedString = Schema.Trimmed.pipe(Schema.check(Schema.isNonEmpty()))\n\nexport const HitlResponseSource = Schema.Literals(['user', 'policy', 'replay'])\nexport type HitlResponseSource = typeof HitlResponseSource.Type\n\nexport const ToolApprovalDecision = Schema.Literals(['approved', 'denied'])\nexport type ToolApprovalDecision = typeof ToolApprovalDecision.Type\n\nexport const ToolApprovalMode = Schema.Literals(['manual'])\nexport type ToolApprovalMode = typeof ToolApprovalMode.Type\n\nexport class ToolApprovalPolicy extends Schema.Class<ToolApprovalPolicy>('ToolApprovalPolicy')({\n mode: ToolApprovalMode,\n reason: Schema.optional(Schema.String)\n}) {}\n\nexport class ToolCall extends Schema.Class<ToolCall>('ToolCall')({\n id: NonEmptyTrimmedString,\n name: NonEmptyTrimmedString,\n params: Schema.Unknown\n}) {}\n\nexport class ToolDef extends Schema.Class<ToolDef>('ToolDef')({\n name: NonEmptyTrimmedString,\n description: Schema.String,\n parameters: Schema.Unknown,\n approval: Schema.optional(ToolApprovalPolicy)\n}) {}\n\nexport class ToolResult extends Schema.Class<ToolResult>('ToolResult')({\n toolCallId: NonEmptyTrimmedString,\n content: Content,\n isError: Schema.optional(Schema.Boolean),\n structuredContent: Schema.optional(Schema.Unknown)\n}) {}\n\nexport class ToolApprovalRequest extends Schema.TaggedClass<ToolApprovalRequest>()(\n 'ToolApprovalRequest',\n {\n requestId: NonEmptyTrimmedString,\n toolCallId: NonEmptyTrimmedString,\n call: ToolCall,\n policy: Schema.optional(ToolApprovalPolicy)\n }\n) {}\n\nexport class ToolApprovalResponse extends Schema.TaggedClass<ToolApprovalResponse>()(\n 'ToolApprovalResponse',\n {\n requestId: NonEmptyTrimmedString,\n toolCallId: NonEmptyTrimmedString,\n decision: ToolApprovalDecision,\n source: HitlResponseSource,\n reason: Schema.optional(Schema.String)\n }\n) {}\n\nexport class QuestionOption extends Schema.Class<QuestionOption>('QuestionOption')({\n id: NonEmptyTrimmedString,\n label: NonEmptyTrimmedString,\n description: Schema.optional(Schema.String)\n}) {}\n\nexport class QuestionPrompt extends Schema.Class<QuestionPrompt>('QuestionPrompt')({\n id: NonEmptyTrimmedString,\n prompt: NonEmptyTrimmedString,\n options: Schema.optional(Schema.Array(QuestionOption)),\n multiple: Schema.optional(Schema.Boolean),\n allowCustom: Schema.optional(Schema.Boolean),\n required: Schema.optional(Schema.Boolean)\n}) {}\n\nexport class QuestionToolParams extends Schema.Class<QuestionToolParams>('QuestionToolParams')({\n questions: Schema.NonEmptyArray(QuestionPrompt)\n}) {}\n\nexport class QuestionRequest extends Schema.TaggedClass<QuestionRequest>()('QuestionRequest', {\n requestId: NonEmptyTrimmedString,\n toolCallId: NonEmptyTrimmedString,\n call: ToolCall,\n questions: Schema.NonEmptyArray(QuestionPrompt)\n}) {}\n\nexport class QuestionAnswer extends Schema.Class<QuestionAnswer>('QuestionAnswer')({\n questionId: NonEmptyTrimmedString,\n optionIds: Schema.optional(Schema.Array(NonEmptyTrimmedString)),\n customAnswer: Schema.optional(Schema.String)\n}) {}\n\nexport type PlainQuestionAnswer = {\n readonly questionId: string\n readonly optionIds?: ReadonlyArray<string>\n readonly customAnswer?: string\n}\n\nexport const QuestionResponseOutcome = Schema.Literals(['answered', 'cancelled'])\nexport type QuestionResponseOutcome = typeof QuestionResponseOutcome.Type\n\nexport class QuestionResponse extends Schema.TaggedClass<QuestionResponse>()('QuestionResponse', {\n requestId: NonEmptyTrimmedString,\n toolCallId: NonEmptyTrimmedString,\n outcome: QuestionResponseOutcome,\n source: HitlResponseSource,\n answers: Schema.optional(Schema.Array(QuestionAnswer)),\n reason: Schema.optional(Schema.String)\n}) {}\n\nexport type PlainQuestionResponse = {\n readonly _tag: 'QuestionResponse'\n readonly requestId: string\n readonly toolCallId: string\n readonly outcome: QuestionResponseOutcome\n readonly source: HitlResponseSource\n readonly answers?: ReadonlyArray<PlainQuestionAnswer>\n readonly reason?: string\n}\n\nexport type PlainToolApprovalResponse = {\n readonly _tag: 'ToolApprovalResponse'\n readonly requestId: string\n readonly toolCallId: string\n readonly decision: ToolApprovalDecision\n readonly source: HitlResponseSource\n readonly reason?: string\n}\n\nexport type PlainHitlResponse = PlainToolApprovalResponse | PlainQuestionResponse\n\nexport type QuestionResponseStructuredContent = {\n readonly type: 'question_response'\n readonly outcome: QuestionResponseOutcome\n readonly answers: ReadonlyArray<PlainQuestionAnswer>\n readonly reason?: string\n readonly source: HitlResponseSource\n}\n\nexport const plainQuestionAnswer = (answer: QuestionAnswer): PlainQuestionAnswer => ({\n questionId: answer.questionId,\n ...(answer.optionIds === undefined ? {} : { optionIds: [...answer.optionIds] }),\n ...(answer.customAnswer === undefined ? {} : { customAnswer: answer.customAnswer })\n})\n\nexport const plainQuestionResponse = (response: QuestionResponse): PlainQuestionResponse => ({\n _tag: 'QuestionResponse',\n requestId: response.requestId,\n toolCallId: response.toolCallId,\n outcome: response.outcome,\n source: response.source,\n ...(response.answers === undefined\n ? {}\n : { answers: response.answers.map(answer => plainQuestionAnswer(answer)) }),\n ...(response.reason === undefined ? {} : { reason: response.reason })\n})\n\nexport const plainToolApprovalResponse = (\n response: ToolApprovalResponse\n): PlainToolApprovalResponse => ({\n _tag: 'ToolApprovalResponse',\n requestId: response.requestId,\n toolCallId: response.toolCallId,\n decision: response.decision,\n source: response.source,\n ...(response.reason === undefined ? {} : { reason: response.reason })\n})\n\nexport const plainHitlResponse = (response: HitlResponse): PlainHitlResponse => {\n switch (response._tag) {\n case 'QuestionResponse':\n return plainQuestionResponse(response)\n case 'ToolApprovalResponse':\n return plainToolApprovalResponse(response)\n }\n}\n\nexport const questionResponseStructuredContent = (\n response: QuestionResponse\n): QuestionResponseStructuredContent => ({\n type: 'question_response',\n outcome: response.outcome,\n answers: (response.answers ?? []).map(answer => plainQuestionAnswer(answer)),\n ...(response.reason === undefined ? {} : { reason: response.reason }),\n source: response.source\n})\n\nconst optionLabel = (question: QuestionPrompt, optionId: string) =>\n question.options?.find(option => option.id === optionId)?.label ?? optionId\n\nconst questionForAnswer = (questions: ReadonlyArray<QuestionPrompt>, answer: QuestionAnswer) =>\n questions.find(question => question.id === answer.questionId)\n\nconst formatQuestionAnswer = (answer: QuestionAnswer, questions: ReadonlyArray<QuestionPrompt>) => {\n const question = questionForAnswer(questions, answer)\n const prompt = question?.prompt ?? answer.questionId\n const selected =\n answer.optionIds?.map(optionId =>\n question === undefined ? optionId : optionLabel(question, optionId)\n ) ?? []\n const custom = answer.customAnswer?.trim()\n const values = custom === undefined || custom.length === 0 ? selected : [...selected, custom]\n\n return values.length === 0 ? `- ${prompt}: answered` : `- ${prompt}: ${values.join(', ')}`\n}\n\nexport const formatQuestionResponseContent = (\n response: QuestionResponse,\n questions: ReadonlyArray<QuestionPrompt> = []\n) => {\n if (response.outcome === 'cancelled') {\n return `Question cancelled: ${response.reason ?? 'Question cancelled'}`\n }\n\n const answers = response.answers ?? []\n\n if (answers.length === 0) {\n return 'User answered the question, but no answer values were provided. Continue with this in mind.'\n }\n\n const formatted = answers\n .map(answer => formatQuestionAnswer(answer, questions).slice('- '.length))\n .join('; ')\n const label = answers.length === 1 ? 'question' : 'questions'\n\n return `User has answered your ${label}: ${formatted}. Continue with the user's answers in mind.`\n}\n\nexport const HitlRequest = Schema.Union([ToolApprovalRequest, QuestionRequest])\nexport type HitlRequest = typeof HitlRequest.Type\n\nexport const HitlResponse = Schema.Union([ToolApprovalResponse, QuestionResponse])\nexport type HitlResponse = typeof HitlResponse.Type\n"],"mappings":"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"}
1
+ {"version":3,"file":"tool.mjs","names":[],"sources":["../../src/protocol/tool.ts"],"sourcesContent":["import * as Schema from 'effect/Schema'\nimport { Content } from './content.ts'\n\nconst NonEmptyTrimmedString = Schema.Trimmed.pipe(Schema.check(Schema.isNonEmpty()))\n\nexport const HitlResponseSource = Schema.Literals(['user', 'policy', 'replay'])\nexport type HitlResponseSource = typeof HitlResponseSource.Type\n\nexport const ToolApprovalDecision = Schema.Literals(['approved', 'denied'])\nexport type ToolApprovalDecision = typeof ToolApprovalDecision.Type\n\nexport const ToolApprovalMode = Schema.Literals(['manual'])\nexport type ToolApprovalMode = typeof ToolApprovalMode.Type\n\nexport class ToolApprovalPolicy extends Schema.Class<ToolApprovalPolicy>('ToolApprovalPolicy')({\n mode: ToolApprovalMode,\n reason: Schema.optional(Schema.String)\n}) {}\n\nexport class ToolCall extends Schema.Class<ToolCall>('ToolCall')({\n id: NonEmptyTrimmedString,\n name: NonEmptyTrimmedString,\n params: Schema.Unknown\n}) {}\n\nexport class ToolDef extends Schema.Class<ToolDef>('ToolDef')({\n name: NonEmptyTrimmedString,\n description: Schema.String,\n parameters: Schema.Unknown,\n approval: Schema.optional(ToolApprovalPolicy)\n}) {}\n\nexport class ToolResult extends Schema.Class<ToolResult>('ToolResult')({\n toolCallId: NonEmptyTrimmedString,\n content: Content,\n isError: Schema.optional(Schema.Boolean),\n structuredContent: Schema.optional(Schema.Unknown)\n}) {}\n\nexport type ErrorToolResultInput = {\n readonly toolCallId: string\n readonly content: Content\n readonly structuredContent?: unknown\n}\n\nexport const makeErrorToolResult = (input: ErrorToolResultInput) =>\n ToolResult.make({\n toolCallId: input.toolCallId,\n content: input.content,\n isError: true,\n ...(input.structuredContent === undefined\n ? {}\n : { structuredContent: input.structuredContent })\n })\n\nexport class ToolApprovalRequest extends Schema.TaggedClass<ToolApprovalRequest>()(\n 'ToolApprovalRequest',\n {\n requestId: NonEmptyTrimmedString,\n toolCallId: NonEmptyTrimmedString,\n call: ToolCall,\n policy: Schema.optional(ToolApprovalPolicy)\n }\n) {}\n\nexport class ToolApprovalResponse extends Schema.TaggedClass<ToolApprovalResponse>()(\n 'ToolApprovalResponse',\n {\n requestId: NonEmptyTrimmedString,\n toolCallId: NonEmptyTrimmedString,\n decision: ToolApprovalDecision,\n source: HitlResponseSource,\n reason: Schema.optional(Schema.String)\n }\n) {}\n\nexport class QuestionOption extends Schema.Class<QuestionOption>('QuestionOption')({\n id: NonEmptyTrimmedString,\n label: NonEmptyTrimmedString,\n description: Schema.optional(Schema.String)\n}) {}\n\nexport class QuestionPrompt extends Schema.Class<QuestionPrompt>('QuestionPrompt')({\n id: NonEmptyTrimmedString,\n prompt: NonEmptyTrimmedString,\n options: Schema.optional(Schema.Array(QuestionOption)),\n multiple: Schema.optional(Schema.Boolean),\n allowCustom: Schema.optional(Schema.Boolean),\n required: Schema.optional(Schema.Boolean)\n}) {}\n\nexport class QuestionToolParams extends Schema.Class<QuestionToolParams>('QuestionToolParams')({\n questions: Schema.NonEmptyArray(QuestionPrompt)\n}) {}\n\nexport class QuestionRequest extends Schema.TaggedClass<QuestionRequest>()('QuestionRequest', {\n requestId: NonEmptyTrimmedString,\n toolCallId: NonEmptyTrimmedString,\n call: ToolCall,\n questions: Schema.NonEmptyArray(QuestionPrompt)\n}) {}\n\nexport class QuestionAnswer extends Schema.Class<QuestionAnswer>('QuestionAnswer')({\n questionId: NonEmptyTrimmedString,\n optionIds: Schema.optional(Schema.Array(NonEmptyTrimmedString)),\n customAnswer: Schema.optional(Schema.String)\n}) {}\n\nexport type PlainQuestionAnswer = {\n readonly questionId: string\n readonly optionIds?: ReadonlyArray<string>\n readonly customAnswer?: string\n}\n\nexport const QuestionResponseOutcome = Schema.Literals(['answered', 'cancelled'])\nexport type QuestionResponseOutcome = typeof QuestionResponseOutcome.Type\n\nexport class QuestionResponse extends Schema.TaggedClass<QuestionResponse>()('QuestionResponse', {\n requestId: NonEmptyTrimmedString,\n toolCallId: NonEmptyTrimmedString,\n outcome: QuestionResponseOutcome,\n source: HitlResponseSource,\n answers: Schema.optional(Schema.Array(QuestionAnswer)),\n reason: Schema.optional(Schema.String)\n}) {}\n\nexport type PlainQuestionResponse = {\n readonly _tag: 'QuestionResponse'\n readonly requestId: string\n readonly toolCallId: string\n readonly outcome: QuestionResponseOutcome\n readonly source: HitlResponseSource\n readonly answers?: ReadonlyArray<PlainQuestionAnswer>\n readonly reason?: string\n}\n\nexport type PlainToolApprovalResponse = {\n readonly _tag: 'ToolApprovalResponse'\n readonly requestId: string\n readonly toolCallId: string\n readonly decision: ToolApprovalDecision\n readonly source: HitlResponseSource\n readonly reason?: string\n}\n\nexport type PlainHitlResponse = PlainToolApprovalResponse | PlainQuestionResponse\n\nexport type QuestionResponseStructuredContent = {\n readonly type: 'question_response'\n readonly outcome: QuestionResponseOutcome\n readonly answers: ReadonlyArray<PlainQuestionAnswer>\n readonly reason?: string\n readonly source: HitlResponseSource\n}\n\nexport const plainQuestionAnswer = (answer: QuestionAnswer): PlainQuestionAnswer => ({\n questionId: answer.questionId,\n ...(answer.optionIds === undefined ? {} : { optionIds: [...answer.optionIds] }),\n ...(answer.customAnswer === undefined ? {} : { customAnswer: answer.customAnswer })\n})\n\nexport const plainQuestionResponse = (response: QuestionResponse): PlainQuestionResponse => ({\n _tag: 'QuestionResponse',\n requestId: response.requestId,\n toolCallId: response.toolCallId,\n outcome: response.outcome,\n source: response.source,\n ...(response.answers === undefined\n ? {}\n : { answers: response.answers.map(answer => plainQuestionAnswer(answer)) }),\n ...(response.reason === undefined ? {} : { reason: response.reason })\n})\n\nexport const plainToolApprovalResponse = (\n response: ToolApprovalResponse\n): PlainToolApprovalResponse => ({\n _tag: 'ToolApprovalResponse',\n requestId: response.requestId,\n toolCallId: response.toolCallId,\n decision: response.decision,\n source: response.source,\n ...(response.reason === undefined ? {} : { reason: response.reason })\n})\n\nexport const plainHitlResponse = (response: HitlResponse): PlainHitlResponse => {\n switch (response._tag) {\n case 'QuestionResponse':\n return plainQuestionResponse(response)\n case 'ToolApprovalResponse':\n return plainToolApprovalResponse(response)\n }\n}\n\nexport const questionResponseStructuredContent = (\n response: QuestionResponse\n): QuestionResponseStructuredContent => ({\n type: 'question_response',\n outcome: response.outcome,\n answers: (response.answers ?? []).map(answer => plainQuestionAnswer(answer)),\n ...(response.reason === undefined ? {} : { reason: response.reason }),\n source: response.source\n})\n\nconst optionLabel = (question: QuestionPrompt, optionId: string) =>\n question.options?.find(option => option.id === optionId)?.label ?? optionId\n\nconst questionForAnswer = (questions: ReadonlyArray<QuestionPrompt>, answer: QuestionAnswer) =>\n questions.find(question => question.id === answer.questionId)\n\nconst formatQuestionAnswer = (answer: QuestionAnswer, questions: ReadonlyArray<QuestionPrompt>) => {\n const question = questionForAnswer(questions, answer)\n const prompt = question?.prompt ?? answer.questionId\n const selected =\n answer.optionIds?.map(optionId =>\n question === undefined ? optionId : optionLabel(question, optionId)\n ) ?? []\n const custom = answer.customAnswer?.trim()\n const values = custom === undefined || custom.length === 0 ? selected : [...selected, custom]\n\n return values.length === 0 ? `- ${prompt}: answered` : `- ${prompt}: ${values.join(', ')}`\n}\n\nexport const formatQuestionResponseContent = (\n response: QuestionResponse,\n questions: ReadonlyArray<QuestionPrompt> = []\n) => {\n if (response.outcome === 'cancelled') {\n return `Question cancelled: ${response.reason ?? 'Question cancelled'}`\n }\n\n const answers = response.answers ?? []\n\n if (answers.length === 0) {\n return 'User answered the question, but no answer values were provided. Continue with this in mind.'\n }\n\n const formatted = answers\n .map(answer => formatQuestionAnswer(answer, questions).slice('- '.length))\n .join('; ')\n const label = answers.length === 1 ? 'question' : 'questions'\n\n return `User has answered your ${label}: ${formatted}. Continue with the user's answers in mind.`\n}\n\nexport const HitlRequest = Schema.Union([ToolApprovalRequest, QuestionRequest])\nexport type HitlRequest = typeof HitlRequest.Type\n\nexport const HitlResponse = Schema.Union([ToolApprovalResponse, QuestionResponse])\nexport type HitlResponse = typeof HitlResponse.Type\n"],"mappings":";;;AAGA,MAAM,wBAAwB,OAAO,QAAQ,KAAK,OAAO,MAAM,OAAO,WAAW,CAAC,CAAC;AAEnF,MAAa,qBAAqB,OAAO,SAAS;CAAC;CAAQ;CAAU;AAAQ,CAAC;AAG9E,MAAa,uBAAuB,OAAO,SAAS,CAAC,YAAY,QAAQ,CAAC;AAG1E,MAAa,mBAAmB,OAAO,SAAS,CAAC,QAAQ,CAAC;AAG1D,IAAa,qBAAb,cAAwC,OAAO,MAA0B,oBAAoB,EAAE;CAC7F,MAAM;CACN,QAAQ,OAAO,SAAS,OAAO,MAAM;AACvC,CAAC,EAAE,CAAC;AAEJ,IAAa,WAAb,cAA8B,OAAO,MAAgB,UAAU,EAAE;CAC/D,IAAI;CACJ,MAAM;CACN,QAAQ,OAAO;AACjB,CAAC,EAAE,CAAC;AAEJ,IAAa,UAAb,cAA6B,OAAO,MAAe,SAAS,EAAE;CAC5D,MAAM;CACN,aAAa,OAAO;CACpB,YAAY,OAAO;CACnB,UAAU,OAAO,SAAS,kBAAkB;AAC9C,CAAC,EAAE,CAAC;AAEJ,IAAa,aAAb,cAAgC,OAAO,MAAkB,YAAY,EAAE;CACrE,YAAY;CACZ,SAAS;CACT,SAAS,OAAO,SAAS,OAAO,OAAO;CACvC,mBAAmB,OAAO,SAAS,OAAO,OAAO;AACnD,CAAC,EAAE,CAAC;AAQJ,MAAa,uBAAuB,UAClC,WAAW,KAAK;CACd,YAAY,MAAM;CAClB,SAAS,MAAM;CACf,SAAS;CACT,GAAI,MAAM,sBAAsB,KAAA,IAC5B,CAAC,IACD,EAAE,mBAAmB,MAAM,kBAAkB;AACnD,CAAC;AAEH,IAAa,sBAAb,cAAyC,OAAO,YAAiC,EAC/E,uBACA;CACE,WAAW;CACX,YAAY;CACZ,MAAM;CACN,QAAQ,OAAO,SAAS,kBAAkB;AAC5C,CACF,EAAE,CAAC;AAEH,IAAa,uBAAb,cAA0C,OAAO,YAAkC,EACjF,wBACA;CACE,WAAW;CACX,YAAY;CACZ,UAAU;CACV,QAAQ;CACR,QAAQ,OAAO,SAAS,OAAO,MAAM;AACvC,CACF,EAAE,CAAC;AAEH,IAAa,iBAAb,cAAoC,OAAO,MAAsB,gBAAgB,EAAE;CACjF,IAAI;CACJ,OAAO;CACP,aAAa,OAAO,SAAS,OAAO,MAAM;AAC5C,CAAC,EAAE,CAAC;AAEJ,IAAa,iBAAb,cAAoC,OAAO,MAAsB,gBAAgB,EAAE;CACjF,IAAI;CACJ,QAAQ;CACR,SAAS,OAAO,SAAS,OAAO,MAAM,cAAc,CAAC;CACrD,UAAU,OAAO,SAAS,OAAO,OAAO;CACxC,aAAa,OAAO,SAAS,OAAO,OAAO;CAC3C,UAAU,OAAO,SAAS,OAAO,OAAO;AAC1C,CAAC,EAAE,CAAC;AAEJ,IAAa,qBAAb,cAAwC,OAAO,MAA0B,oBAAoB,EAAE,EAC7F,WAAW,OAAO,cAAc,cAAc,EAChD,CAAC,EAAE,CAAC;AAEJ,IAAa,kBAAb,cAAqC,OAAO,YAA6B,EAAE,mBAAmB;CAC5F,WAAW;CACX,YAAY;CACZ,MAAM;CACN,WAAW,OAAO,cAAc,cAAc;AAChD,CAAC,EAAE,CAAC;AAEJ,IAAa,iBAAb,cAAoC,OAAO,MAAsB,gBAAgB,EAAE;CACjF,YAAY;CACZ,WAAW,OAAO,SAAS,OAAO,MAAM,qBAAqB,CAAC;CAC9D,cAAc,OAAO,SAAS,OAAO,MAAM;AAC7C,CAAC,EAAE,CAAC;AAQJ,MAAa,0BAA0B,OAAO,SAAS,CAAC,YAAY,WAAW,CAAC;AAGhF,IAAa,mBAAb,cAAsC,OAAO,YAA8B,EAAE,oBAAoB;CAC/F,WAAW;CACX,YAAY;CACZ,SAAS;CACT,QAAQ;CACR,SAAS,OAAO,SAAS,OAAO,MAAM,cAAc,CAAC;CACrD,QAAQ,OAAO,SAAS,OAAO,MAAM;AACvC,CAAC,EAAE,CAAC;AA+BJ,MAAa,uBAAuB,YAAiD;CACnF,YAAY,OAAO;CACnB,GAAI,OAAO,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,OAAO,SAAS,EAAE;CAC7E,GAAI,OAAO,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc,OAAO,aAAa;AACnF;AAEA,MAAa,yBAAyB,cAAuD;CAC3F,MAAM;CACN,WAAW,SAAS;CACpB,YAAY,SAAS;CACrB,SAAS,SAAS;CAClB,QAAQ,SAAS;CACjB,GAAI,SAAS,YAAY,KAAA,IACrB,CAAC,IACD,EAAE,SAAS,SAAS,QAAQ,KAAI,WAAU,oBAAoB,MAAM,CAAC,EAAE;CAC3E,GAAI,SAAS,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,SAAS,OAAO;AACrE;AAEA,MAAa,6BACX,cAC+B;CAC/B,MAAM;CACN,WAAW,SAAS;CACpB,YAAY,SAAS;CACrB,UAAU,SAAS;CACnB,QAAQ,SAAS;CACjB,GAAI,SAAS,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,SAAS,OAAO;AACrE;AAEA,MAAa,qBAAqB,aAA8C;CAC9E,QAAQ,SAAS,MAAjB;EACE,KAAK,oBACH,OAAO,sBAAsB,QAAQ;EACvC,KAAK,wBACH,OAAO,0BAA0B,QAAQ;CAC7C;AACF;AAEA,MAAa,qCACX,cACuC;CACvC,MAAM;CACN,SAAS,SAAS;CAClB,UAAU,SAAS,WAAW,CAAC,GAAG,KAAI,WAAU,oBAAoB,MAAM,CAAC;CAC3E,GAAI,SAAS,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,SAAS,OAAO;CACnE,QAAQ,SAAS;AACnB;AAEA,MAAM,eAAe,UAA0B,aAC7C,SAAS,SAAS,MAAK,WAAU,OAAO,OAAO,QAAQ,GAAG,SAAS;AAErE,MAAM,qBAAqB,WAA0C,WACnE,UAAU,MAAK,aAAY,SAAS,OAAO,OAAO,UAAU;AAE9D,MAAM,wBAAwB,QAAwB,cAA6C;CACjG,MAAM,WAAW,kBAAkB,WAAW,MAAM;CACpD,MAAM,SAAS,UAAU,UAAU,OAAO;CAC1C,MAAM,WACJ,OAAO,WAAW,KAAI,aACpB,aAAa,KAAA,IAAY,WAAW,YAAY,UAAU,QAAQ,CACpE,KAAK,CAAC;CACR,MAAM,SAAS,OAAO,cAAc,KAAK;CACzC,MAAM,SAAS,WAAW,KAAA,KAAa,OAAO,WAAW,IAAI,WAAW,CAAC,GAAG,UAAU,MAAM;CAE5F,OAAO,OAAO,WAAW,IAAI,KAAK,OAAO,cAAc,KAAK,OAAO,IAAI,OAAO,KAAK,IAAI;AACzF;AAEA,MAAa,iCACX,UACA,YAA2C,CAAC,MACzC;CACH,IAAI,SAAS,YAAY,aACvB,OAAO,uBAAuB,SAAS,UAAU;CAGnD,MAAM,UAAU,SAAS,WAAW,CAAC;CAErC,IAAI,QAAQ,WAAW,GACrB,OAAO;CAGT,MAAM,YAAY,QACf,KAAI,WAAU,qBAAqB,QAAQ,SAAS,EAAE,MAAM,CAAW,CAAC,EACxE,KAAK,IAAI;CAGZ,OAAO,0BAFO,QAAQ,WAAW,IAAI,aAAa,YAEX,IAAI,UAAU;AACvD;AAEA,MAAa,cAAc,OAAO,MAAM,CAAC,qBAAqB,eAAe,CAAC;AAG9E,MAAa,eAAe,OAAO,MAAM,CAAC,sBAAsB,gBAAgB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { EmptyToolParams, ResolvedToolSet, SchemaToolExecutionInput, ToolAccess, ToolExecutionInput, ToolMetadata, ToolModule, ToolRegistration, ToolRegistryError, makeTool, makeToolExecutorLayer, resolveTools } from "./registry.mjs";
1
+ import { EmptyToolParams, ModelVisibleToolError, ModelVisibleToolErrorInput, ModelVisibleToolErrorReason, ModelVisibleToolErrorStructuredContent, ModelVisibleToolErrorStructuredContentSchema, ResolvedToolSet, SchemaToolExecutionInput, ToolAccess, ToolExecutionInput, ToolMetadata, ToolModule, ToolRegistration, ToolRegistryError, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, resolveTools } from "./registry.mjs";
2
2
  import { QuestionExecutionInput, QuestionToolOptions, makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, questionToolName } from "./question.mjs";
3
3
  import { TaskExecutionInput, TaskSubagentContext, TaskSubagentDefinition, TaskToolOptions, TaskToolParams, TaskToolResultInput, formatTaskResult, makeNonRecursiveTaskToolModule, makeTaskToolDef, makeTaskToolModule, makeTaskToolRegistration, makeTaskToolResult, subagentResultText, taskSubagentRunId, taskToolName } from "./task.mjs";
4
- export { EmptyToolParams, type QuestionExecutionInput, type QuestionToolOptions, type ResolvedToolSet, type SchemaToolExecutionInput, type TaskExecutionInput, type TaskSubagentContext, type TaskSubagentDefinition, type TaskToolOptions, type TaskToolParams, type TaskToolResultInput, ToolAccess, type ToolExecutionInput, type ToolMetadata, type ToolModule, type ToolRegistration, ToolRegistryError, formatTaskResult, makeNonRecursiveTaskToolModule, makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, makeTaskToolDef, makeTaskToolModule, makeTaskToolRegistration, makeTaskToolResult, makeTool, makeToolExecutorLayer, questionToolName, resolveTools, subagentResultText, taskSubagentRunId, taskToolName };
4
+ export { EmptyToolParams, ModelVisibleToolError, type ModelVisibleToolErrorInput, ModelVisibleToolErrorReason, type ModelVisibleToolErrorStructuredContent, ModelVisibleToolErrorStructuredContentSchema, type QuestionExecutionInput, type QuestionToolOptions, type ResolvedToolSet, type SchemaToolExecutionInput, type TaskExecutionInput, type TaskSubagentContext, type TaskSubagentDefinition, type TaskToolOptions, type TaskToolParams, type TaskToolResultInput, ToolAccess, type ToolExecutionInput, type ToolMetadata, type ToolModule, type ToolRegistration, ToolRegistryError, formatTaskResult, makeNonRecursiveTaskToolModule, makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, makeTaskToolDef, makeTaskToolModule, makeTaskToolRegistration, makeTaskToolResult, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, questionToolName, resolveTools, subagentResultText, taskSubagentRunId, taskToolName };
@@ -1,4 +1,4 @@
1
- import { EmptyToolParams, ToolAccess, ToolRegistryError, makeTool, makeToolExecutorLayer, resolveTools } from "./registry.mjs";
1
+ import { EmptyToolParams, ModelVisibleToolError, ModelVisibleToolErrorReason, ModelVisibleToolErrorStructuredContentSchema, ToolAccess, ToolRegistryError, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, resolveTools } from "./registry.mjs";
2
2
  import { makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, questionToolName } from "./question.mjs";
3
3
  import { formatTaskResult, makeNonRecursiveTaskToolModule, makeTaskToolDef, makeTaskToolModule, makeTaskToolRegistration, makeTaskToolResult, subagentResultText, taskSubagentRunId, taskToolName } from "./task.mjs";
4
- export { EmptyToolParams, ToolAccess, ToolRegistryError, formatTaskResult, makeNonRecursiveTaskToolModule, makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, makeTaskToolDef, makeTaskToolModule, makeTaskToolRegistration, makeTaskToolResult, makeTool, makeToolExecutorLayer, questionToolName, resolveTools, subagentResultText, taskSubagentRunId, taskToolName };
4
+ export { EmptyToolParams, ModelVisibleToolError, ModelVisibleToolErrorReason, ModelVisibleToolErrorStructuredContentSchema, ToolAccess, ToolRegistryError, formatTaskResult, makeNonRecursiveTaskToolModule, makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, makeTaskToolDef, makeTaskToolModule, makeTaskToolRegistration, makeTaskToolResult, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, questionToolName, resolveTools, subagentResultText, taskSubagentRunId, taskToolName };
@@ -11,6 +11,32 @@ declare const ToolRegistryError_base: Schema.Class<ToolRegistryError, Schema.Tag
11
11
  readonly cause: Schema.Literals<readonly ["duplicate_tool"]>;
12
12
  }>, import("effect/Cause").YieldableError>;
13
13
  declare class ToolRegistryError extends ToolRegistryError_base {}
14
+ declare const ModelVisibleToolErrorReason: Schema.Literals<readonly ["validation", "invalid_input", "permission", "denied", "not_found", "unavailable", "timeout"]>;
15
+ type ModelVisibleToolErrorReason = typeof ModelVisibleToolErrorReason.Type;
16
+ declare const ModelVisibleToolError_base: Schema.Class<ModelVisibleToolError, Schema.TaggedStruct<"ModelVisibleToolError", {
17
+ readonly tool: Schema.String;
18
+ readonly message: Schema.String;
19
+ readonly reason: Schema.Literals<readonly ["validation", "invalid_input", "permission", "denied", "not_found", "unavailable", "timeout"]>;
20
+ readonly details: Schema.optional<Schema.Unknown>;
21
+ }>, import("effect/Cause").YieldableError>;
22
+ declare class ModelVisibleToolError extends ModelVisibleToolError_base {}
23
+ declare const ModelVisibleToolErrorStructuredContentSchema: Schema.Struct<{
24
+ readonly type: Schema.Literal<"model_visible_tool_error">;
25
+ readonly tool: Schema.String;
26
+ readonly reason: Schema.Literals<readonly ["validation", "invalid_input", "permission", "denied", "not_found", "unavailable", "timeout"]>;
27
+ readonly message: Schema.String;
28
+ readonly details: Schema.optional<Schema.Unknown>;
29
+ }>;
30
+ type ModelVisibleToolErrorStructuredContent = typeof ModelVisibleToolErrorStructuredContentSchema.Type;
31
+ type ModelVisibleToolErrorInput = {
32
+ readonly tool: string;
33
+ readonly message: string;
34
+ readonly reason: ModelVisibleToolErrorReason;
35
+ readonly details?: unknown;
36
+ };
37
+ declare const modelVisibleToolError: (input: ModelVisibleToolErrorInput) => ModelVisibleToolError;
38
+ declare const modelVisibleToolErrorStructuredContent: (error: ModelVisibleToolError) => ModelVisibleToolErrorStructuredContent;
39
+ declare const modelVisibleToolErrorResult: (call: ToolCall, error: ModelVisibleToolError) => ToolResult;
14
40
  type ToolExecutionInput<Context> = {
15
41
  readonly call: ToolCall;
16
42
  readonly context: Context;
@@ -37,7 +63,7 @@ type MakeToolOptions<Context, ParamsSchema extends ToolParamsSchema> = {
37
63
  readonly approval?: ToolApprovalPolicy;
38
64
  readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>;
39
65
  readonly invalidParamsMessage?: (error: unknown) => string;
40
- readonly execute: (input: SchemaToolExecutionInput<Context, ParamsSchema['Type']>) => Effect.Effect<ToolResult, ToolError>;
66
+ readonly execute: (input: SchemaToolExecutionInput<Context, ParamsSchema['Type']>) => Effect.Effect<ToolResult, ToolError | ModelVisibleToolError>;
41
67
  };
42
68
  type ToolModule<Context> = {
43
69
  readonly id: string;
@@ -57,5 +83,5 @@ declare const makeTool: <Context, ParamsSchema extends ToolParamsSchema>(options
57
83
  declare const resolveTools: <Context>(modules: ReadonlyArray<ToolModule<Context>>, context: Context) => Effect.Effect<ResolvedToolSet, ToolRegistryError>;
58
84
  declare const makeToolExecutorLayer: (toolSet: ResolvedToolSet) => Layer.Layer<ToolExecutor, never, never>;
59
85
  //#endregion
60
- export { EmptyToolParams, MakeToolOptions, ResolvedToolSet, SchemaToolExecutionInput, ToolAccess, ToolExecutionInput, ToolMetadata, ToolModule, ToolRegistration, ToolRegistryError, makeTool, makeToolExecutorLayer, resolveTools };
86
+ export { EmptyToolParams, MakeToolOptions, ModelVisibleToolError, ModelVisibleToolErrorInput, ModelVisibleToolErrorReason, ModelVisibleToolErrorStructuredContent, ModelVisibleToolErrorStructuredContentSchema, ResolvedToolSet, SchemaToolExecutionInput, ToolAccess, ToolExecutionInput, ToolMetadata, ToolModule, ToolRegistration, ToolRegistryError, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, resolveTools };
61
87
  //# sourceMappingURL=registry.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.mts","names":[],"sources":["../../src/tools/registry.ts"],"mappings":";;;;;;cAKa,UAAA,EAAU,MAAA,CAAA,QAAA;AAAA,KACX,UAAA,UAAoB,UAAA,CAAW,IAAI;AAAA,cAAA,sBAAA;;;;cAElC,iBAAA,SAA0B,sBAMtC;AAAA,KAEW,kBAAA;EAAA,SACD,IAAA,EAAM,QAAA;EAAA,SACN,OAAA,EAAS,OAAO;AAAA;AAAA,KAGf,wBAAA,oBAA4C,kBAAA,CAAmB,OAAA;EAAA,SAChE,MAAA,EAAQ,MAAA;AAAA;AAAA,KAGP,gBAAA;EAAA,SACD,GAAA,EAAK,OAAA;EAAA,SACL,MAAA,EAAQ,UAAA;EAAA,SACR,QAAA,GAAW,kBAAA;EAAA,SACX,SAAA,IAAa,OAAA,EAAS,OAAA,KAAY,MAAA,CAAO,MAAA,UAAgB,iBAAA;EAAA,SACzD,OAAA,GAAU,KAAA,EAAO,kBAAA,CAAmB,OAAA,MAAa,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,SAAA;AAAA;AAAA,KAGjF,gBAAA,GAAmB,MAAA,CAAO,MAAM;EAAA,SAAuB,gBAAA;AAAA;AAAA,cAE/C,eAAA,EAAe,MAAA,CAAA,OAAA,CAAA,MAAA,CAAA,MAAA,EAAA,MAAA,CAAA,KAAA;AAAA,KAEhB,eAAA,+BAA8C,gBAAA;EAAA,SAC/C,IAAA;EAAA,SACA,WAAA;EAAA,SACA,UAAA,EAAY,YAAA;EAAA,SACZ,MAAA,EAAQ,UAAA;EAAA,SACR,QAAA,GAAW,kBAAA;EAAA,SACX,SAAA,IAAa,OAAA,EAAS,OAAA,KAAY,MAAA,CAAO,MAAA,UAAgB,iBAAA;EAAA,SACzD,oBAAA,IAAwB,KAAA;EAAA,SACxB,OAAA,GACP,KAAA,EAAO,wBAAA,CAAyB,OAAA,EAAS,YAAA,cACtC,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,SAAA;AAAA;AAAA,KAGrB,UAAA;EAAA,SACD,EAAA;EAAA,SACA,KAAA,EAAO,aAAA,CAAc,gBAAA,CAAiB,OAAA;AAAA;AAAA,KAGrC,YAAA;EAAA,SACD,QAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA,EAAQ,UAAU;AAAA;AAAA,KAQjB,eAAA;EAAA,SACD,KAAA,EAAO,aAAA,CAAc,OAAA;EAAA,SACrB,QAAA,EAAU,aAAA,CAAc,YAAA;EAAA,SACxB,OAAA,GAAU,IAAA,EAAM,QAAA,KAAa,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,SAAA;AAAA;AAAA,cA4FrD,QAAA,iCAA0C,gBAAA,EACrD,OAAA,EAAS,eAAA,CAAgB,OAAA,EAAS,YAAA,MACjC,gBAAA,CAAiB,OAAA;AAAA,cA6BP,YAAA,YACX,OAAA,EAAS,aAAA,CAAc,UAAA,CAAW,OAAA,IAClC,OAAA,EAAS,OAAA,KACR,MAAA,CAAO,MAAA,CAAO,eAAA,EAAiB,iBAAA;AAAA,cA+BrB,qBAAA,GAAyB,OAAA,EAAS,eAAA,KAAe,KAAA,CAAA,KAAA,CAAA,YAAA"}
1
+ {"version":3,"file":"registry.d.mts","names":[],"sources":["../../src/tools/registry.ts"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { Array as Array$1, Effect, Layer, Option } from "effect";
2
2
  import * as Schema from "effect/Schema";
3
- import { ToolDef } from "@yolk-sdk/agent/protocol";
3
+ import { ToolDef, makeErrorToolResult } from "@yolk-sdk/agent/protocol";
4
4
  import { ToolError, ToolExecutor } from "@yolk-sdk/agent/loop";
5
5
  //#region src/tools/registry.ts
6
6
  const ToolAccess = Schema.Literals([
@@ -12,6 +12,41 @@ var ToolRegistryError = class extends Schema.TaggedErrorClass()("ToolRegistryErr
12
12
  message: Schema.String,
13
13
  cause: Schema.Literals(["duplicate_tool"])
14
14
  }) {};
15
+ const ModelVisibleToolErrorReason = Schema.Literals([
16
+ "validation",
17
+ "invalid_input",
18
+ "permission",
19
+ "denied",
20
+ "not_found",
21
+ "unavailable",
22
+ "timeout"
23
+ ]);
24
+ var ModelVisibleToolError = class extends Schema.TaggedErrorClass()("ModelVisibleToolError", {
25
+ tool: Schema.String,
26
+ message: Schema.String,
27
+ reason: ModelVisibleToolErrorReason,
28
+ details: Schema.optional(Schema.Unknown)
29
+ }) {};
30
+ const ModelVisibleToolErrorStructuredContentSchema = Schema.Struct({
31
+ type: Schema.Literal("model_visible_tool_error"),
32
+ tool: Schema.String,
33
+ reason: ModelVisibleToolErrorReason,
34
+ message: Schema.String,
35
+ details: Schema.optional(Schema.Unknown)
36
+ });
37
+ const modelVisibleToolError = (input) => new ModelVisibleToolError(input);
38
+ const modelVisibleToolErrorStructuredContent = (error) => ({
39
+ type: "model_visible_tool_error",
40
+ tool: error.tool,
41
+ reason: error.reason,
42
+ message: error.message,
43
+ ...error.details === void 0 ? {} : { details: error.details }
44
+ });
45
+ const modelVisibleToolErrorResult = (call, error) => makeErrorToolResult({
46
+ toolCallId: call.id,
47
+ content: error.message,
48
+ structuredContent: modelVisibleToolErrorStructuredContent(error)
49
+ });
15
50
  const EmptyToolParams = Schema.Record(Schema.String, Schema.Never);
16
51
  const enabled = (tool, context) => tool.isEnabled === void 0 ? Effect.succeed(true) : tool.isEnabled(context);
17
52
  const resolveModuleTools = (toolModule, context) => Effect.forEach(toolModule.tools, (tool) => enabled(tool, context).pipe(Effect.map((isToolEnabled) => isToolEnabled ? Option.some({
@@ -68,15 +103,21 @@ const makeTool = (options) => ({
68
103
  access: options.access,
69
104
  approval: options.approval,
70
105
  isEnabled: options.isEnabled,
71
- execute: ({ call, context }) => Schema.decodeUnknownEffect(options.parameters)(call.params).pipe(Effect.mapError((error) => new ToolError({
72
- tool: options.name,
73
- message: options.invalidParamsMessage?.(error) ?? `Invalid ${options.name} arguments: ${unknownToMessage(error)}`,
74
- cause: "validation"
75
- })), Effect.flatMap((params) => options.execute({
76
- call,
77
- context,
78
- params
79
- })))
106
+ execute: ({ call, context }) => Schema.decodeUnknownEffect(options.parameters)(call.params).pipe(Effect.matchEffect({
107
+ onFailure: (error) => {
108
+ const message = options.invalidParamsMessage?.(error) ?? `Invalid ${options.name} arguments: ${unknownToMessage(error)}`;
109
+ return Effect.succeed(modelVisibleToolErrorResult(call, modelVisibleToolError({
110
+ tool: options.name,
111
+ message,
112
+ reason: "validation"
113
+ })));
114
+ },
115
+ onSuccess: (params) => options.execute({
116
+ call,
117
+ context,
118
+ params
119
+ }).pipe(Effect.catchTag("ModelVisibleToolError", (error) => Effect.succeed(modelVisibleToolErrorResult(call, error))))
120
+ }))
80
121
  });
81
122
  const findDuplicateToolName = (resolved) => {
82
123
  const names = Array$1.map(resolved, (item) => item.tool.def.name);
@@ -108,6 +149,6 @@ const resolveTools = (modules, context) => Effect.gen(function* () {
108
149
  });
109
150
  const makeToolExecutorLayer = (toolSet) => Layer.succeed(ToolExecutor, ToolExecutor.of({ execute: toolSet.execute }));
110
151
  //#endregion
111
- export { EmptyToolParams, ToolAccess, ToolRegistryError, makeTool, makeToolExecutorLayer, resolveTools };
152
+ export { EmptyToolParams, ModelVisibleToolError, ModelVisibleToolErrorReason, ModelVisibleToolErrorStructuredContentSchema, ToolAccess, ToolRegistryError, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, resolveTools };
112
153
 
113
154
  //# sourceMappingURL=registry.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.mjs","names":["Arr"],"sources":["../../src/tools/registry.ts"],"sourcesContent":["import { Array as Arr, Effect, Layer, Option } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ToolError, ToolExecutor } from '@yolk-sdk/agent/loop'\nimport { ToolDef, type ToolApprovalPolicy, type ToolCall, type ToolResult } from '@yolk-sdk/agent/protocol'\n\nexport const ToolAccess = Schema.Literals(['read', 'write', 'destructive'])\nexport type ToolAccess = typeof ToolAccess.Type\n\nexport class ToolRegistryError extends Schema.TaggedErrorClass<ToolRegistryError>()(\n 'ToolRegistryError',\n {\n message: Schema.String,\n cause: Schema.Literals(['duplicate_tool'])\n }\n) {}\n\nexport type ToolExecutionInput<Context> = {\n readonly call: ToolCall\n readonly context: Context\n}\n\nexport type SchemaToolExecutionInput<Context, Params> = ToolExecutionInput<Context> & {\n readonly params: Params\n}\n\nexport type ToolRegistration<Context> = {\n readonly def: ToolDef\n readonly access: ToolAccess\n readonly approval?: ToolApprovalPolicy\n readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>\n readonly execute: (input: ToolExecutionInput<Context>) => Effect.Effect<ToolResult, ToolError>\n}\n\ntype ToolParamsSchema = Schema.Schema<unknown> & { readonly DecodingServices: never }\n\nexport const EmptyToolParams = Schema.Record(Schema.String, Schema.Never)\n\nexport type MakeToolOptions<Context, ParamsSchema extends ToolParamsSchema> = {\n readonly name: string\n readonly description: string\n readonly parameters: ParamsSchema\n readonly access: ToolAccess\n readonly approval?: ToolApprovalPolicy\n readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>\n readonly invalidParamsMessage?: (error: unknown) => string\n readonly execute: (\n input: SchemaToolExecutionInput<Context, ParamsSchema['Type']>\n ) => Effect.Effect<ToolResult, ToolError>\n}\n\nexport type ToolModule<Context> = {\n readonly id: string\n readonly tools: ReadonlyArray<ToolRegistration<Context>>\n}\n\nexport type ToolMetadata = {\n readonly moduleId: string\n readonly name: string\n readonly access: ToolAccess\n}\n\ntype ResolvedRegistration<Context> = {\n readonly moduleId: string\n readonly tool: ToolRegistration<Context>\n}\n\nexport type ResolvedToolSet = {\n readonly tools: ReadonlyArray<ToolDef>\n readonly metadata: ReadonlyArray<ToolMetadata>\n readonly execute: (call: ToolCall) => Effect.Effect<ToolResult, ToolError>\n}\n\nconst enabled = <Context>(tool: ToolRegistration<Context>, context: Context) =>\n tool.isEnabled === undefined ? Effect.succeed(true) : tool.isEnabled(context)\n\nconst resolveModuleTools = <Context>(toolModule: ToolModule<Context>, context: Context) =>\n Effect.forEach(toolModule.tools, tool =>\n enabled(tool, context).pipe(\n Effect.map(isToolEnabled =>\n isToolEnabled ? Option.some({ moduleId: toolModule.id, tool }) : Option.none()\n )\n )\n ).pipe(Effect.map(Arr.getSomes))\n\nconst duplicateToolError = (name: string) =>\n new ToolRegistryError({\n cause: 'duplicate_tool',\n message: `Duplicate tool registered: ${name}`\n })\n\nconst missingToolError = (name: string) =>\n new ToolError({\n tool: name,\n message: `Tool is not configured: ${name}`,\n cause: 'not_found'\n })\n\nconst unknownToMessage = (error: unknown) =>\n error instanceof Error ? error.message : String(error)\n\nconst objectField = (input: unknown, key: string) =>\n input !== null && typeof input === 'object' ? Object.getOwnPropertyDescriptor(input, key)?.value : undefined\n\nconst isObjectRecord = (input: unknown): input is Readonly<Record<string, unknown>> =>\n input !== null && typeof input === 'object' && !Array.isArray(input)\n\nconst localDefinitionName = (ref: unknown) => {\n if (typeof ref !== 'string') {\n return undefined\n }\n\n const prefix = '#/$defs/'\n\n return ref.startsWith(prefix) ? ref.slice(prefix.length) : undefined\n}\n\nconst hasJsonSchemaType = (input: unknown, type: string) => objectField(input, 'type') === type\n\nconst isEmptyStructJsonSchema = (schema: unknown) => {\n const anyOf = objectField(schema, 'anyOf')\n\n return Array.isArray(anyOf) &&\n anyOf.length === 2 &&\n anyOf.some(item => hasJsonSchemaType(item, 'object')) &&\n anyOf.some(item => hasJsonSchemaType(item, 'array'))\n}\n\nconst isEmptyRecordJsonSchema = (schema: unknown) =>\n hasJsonSchemaType(schema, 'object') &&\n objectField(schema, 'additionalProperties') === false &&\n objectField(schema, 'properties') === undefined &&\n objectField(schema, 'required') === undefined\n\nconst emptyObjectJsonSchema = {\n type: 'object',\n properties: {},\n required: [],\n additionalProperties: false\n}\n\nconst jsonSchemaFromSchema = (schema: Schema.Top) => {\n const document = Schema.toJsonSchemaDocument(schema)\n const definitionName = localDefinitionName(objectField(document.schema, '$ref'))\n const localDefinition = definitionName === undefined\n ? undefined\n : Object.getOwnPropertyDescriptor(document.definitions, definitionName)?.value\n const rootSchema = isObjectRecord(localDefinition) ? localDefinition : document.schema\n const remainingDefinitions = definitionName === undefined\n ? document.definitions\n : Object.fromEntries(\n Object.entries(document.definitions).filter(([name]) => name !== definitionName)\n )\n const jsonSchema = isEmptyStructJsonSchema(rootSchema) || isEmptyRecordJsonSchema(rootSchema)\n ? emptyObjectJsonSchema\n : rootSchema\n\n return Object.keys(remainingDefinitions).length > 0\n ? { ...jsonSchema, $defs: remainingDefinitions }\n : jsonSchema\n}\n\nexport const makeTool = <Context, ParamsSchema extends ToolParamsSchema>(\n options: MakeToolOptions<Context, ParamsSchema>\n): ToolRegistration<Context> => ({\n def: ToolDef.make({\n name: options.name,\n description: options.description,\n parameters: jsonSchemaFromSchema(options.parameters),\n approval: options.approval\n }),\n access: options.access,\n approval: options.approval,\n isEnabled: options.isEnabled,\n execute: ({ call, context }) =>\n Schema.decodeUnknownEffect(options.parameters)(call.params).pipe(\n Effect.mapError(error =>\n new ToolError({\n tool: options.name,\n message: options.invalidParamsMessage?.(error) ?? `Invalid ${options.name} arguments: ${unknownToMessage(error)}`,\n cause: 'validation'\n })\n ),\n Effect.flatMap(params => options.execute({ call, context, params }))\n )\n})\n\nconst findDuplicateToolName = <Context>(resolved: ReadonlyArray<ResolvedRegistration<Context>>) => {\n const names = Arr.map(resolved, item => item.tool.def.name)\n\n return Arr.findFirst(names, (name, index) => names.indexOf(name) !== index)\n}\n\nexport const resolveTools = <Context>(\n modules: ReadonlyArray<ToolModule<Context>>,\n context: Context\n): Effect.Effect<ResolvedToolSet, ToolRegistryError> =>\n Effect.gen(function* () {\n const resolvedByModule = yield* Effect.forEach(modules, toolModule =>\n resolveModuleTools(toolModule, context)\n )\n const resolved = Arr.flatten(resolvedByModule)\n const duplicateName = findDuplicateToolName(resolved)\n\n if (Option.isSome(duplicateName)) {\n return yield* Effect.fail(duplicateToolError(duplicateName.value))\n }\n\n const tools = Arr.map(resolved, item => item.tool.def)\n const metadata = Arr.map(resolved, item => ({\n moduleId: item.moduleId,\n name: item.tool.def.name,\n access: item.tool.access\n }))\n\n const execute = (call: ToolCall) =>\n Option.match(\n Arr.findFirst(resolved, item => item.tool.def.name === call.name),\n {\n onNone: () => Effect.fail(missingToolError(call.name)),\n onSome: match => match.tool.execute({ call, context })\n }\n )\n\n return { tools, metadata, execute }\n })\n\nexport const makeToolExecutorLayer = (toolSet: ResolvedToolSet) =>\n Layer.succeed(ToolExecutor, ToolExecutor.of({ execute: toolSet.execute }))\n"],"mappings":"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"}
1
+ {"version":3,"file":"registry.mjs","names":["Arr"],"sources":["../../src/tools/registry.ts"],"sourcesContent":["import { Array as Arr, Effect, Layer, Option } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ToolError, ToolExecutor } from '@yolk-sdk/agent/loop'\nimport {\n makeErrorToolResult,\n ToolDef,\n type ToolApprovalPolicy,\n type ToolCall,\n type ToolResult\n} from '@yolk-sdk/agent/protocol'\n\nexport const ToolAccess = Schema.Literals(['read', 'write', 'destructive'])\nexport type ToolAccess = typeof ToolAccess.Type\n\nexport class ToolRegistryError extends Schema.TaggedErrorClass<ToolRegistryError>()(\n 'ToolRegistryError',\n {\n message: Schema.String,\n cause: Schema.Literals(['duplicate_tool'])\n }\n) {}\n\nexport const ModelVisibleToolErrorReason = Schema.Literals([\n 'validation',\n 'invalid_input',\n 'permission',\n 'denied',\n 'not_found',\n 'unavailable',\n 'timeout'\n])\nexport type ModelVisibleToolErrorReason = typeof ModelVisibleToolErrorReason.Type\n\nexport class ModelVisibleToolError extends Schema.TaggedErrorClass<ModelVisibleToolError>()(\n 'ModelVisibleToolError',\n {\n tool: Schema.String,\n message: Schema.String,\n reason: ModelVisibleToolErrorReason,\n details: Schema.optional(Schema.Unknown)\n }\n) {}\n\nexport const ModelVisibleToolErrorStructuredContentSchema = Schema.Struct({\n type: Schema.Literal('model_visible_tool_error'),\n tool: Schema.String,\n reason: ModelVisibleToolErrorReason,\n message: Schema.String,\n details: Schema.optional(Schema.Unknown)\n})\nexport type ModelVisibleToolErrorStructuredContent =\n typeof ModelVisibleToolErrorStructuredContentSchema.Type\n\nexport type ModelVisibleToolErrorInput = {\n readonly tool: string\n readonly message: string\n readonly reason: ModelVisibleToolErrorReason\n readonly details?: unknown\n}\n\nexport const modelVisibleToolError = (input: ModelVisibleToolErrorInput) =>\n new ModelVisibleToolError(input)\n\nexport const modelVisibleToolErrorStructuredContent = (\n error: ModelVisibleToolError\n): ModelVisibleToolErrorStructuredContent => ({\n type: 'model_visible_tool_error',\n tool: error.tool,\n reason: error.reason,\n message: error.message,\n ...(error.details === undefined ? {} : { details: error.details })\n})\n\nexport const modelVisibleToolErrorResult = (\n call: ToolCall,\n error: ModelVisibleToolError\n) => makeErrorToolResult({\n toolCallId: call.id,\n content: error.message,\n structuredContent: modelVisibleToolErrorStructuredContent(error)\n})\n\nexport type ToolExecutionInput<Context> = {\n readonly call: ToolCall\n readonly context: Context\n}\n\nexport type SchemaToolExecutionInput<Context, Params> = ToolExecutionInput<Context> & {\n readonly params: Params\n}\n\nexport type ToolRegistration<Context> = {\n readonly def: ToolDef\n readonly access: ToolAccess\n readonly approval?: ToolApprovalPolicy\n readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>\n readonly execute: (input: ToolExecutionInput<Context>) => Effect.Effect<ToolResult, ToolError>\n}\n\ntype ToolParamsSchema = Schema.Schema<unknown> & { readonly DecodingServices: never }\n\nexport const EmptyToolParams = Schema.Record(Schema.String, Schema.Never)\n\nexport type MakeToolOptions<Context, ParamsSchema extends ToolParamsSchema> = {\n readonly name: string\n readonly description: string\n readonly parameters: ParamsSchema\n readonly access: ToolAccess\n readonly approval?: ToolApprovalPolicy\n readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>\n readonly invalidParamsMessage?: (error: unknown) => string\n readonly execute: (\n input: SchemaToolExecutionInput<Context, ParamsSchema['Type']>\n ) => Effect.Effect<ToolResult, ToolError | ModelVisibleToolError>\n}\n\nexport type ToolModule<Context> = {\n readonly id: string\n readonly tools: ReadonlyArray<ToolRegistration<Context>>\n}\n\nexport type ToolMetadata = {\n readonly moduleId: string\n readonly name: string\n readonly access: ToolAccess\n}\n\ntype ResolvedRegistration<Context> = {\n readonly moduleId: string\n readonly tool: ToolRegistration<Context>\n}\n\nexport type ResolvedToolSet = {\n readonly tools: ReadonlyArray<ToolDef>\n readonly metadata: ReadonlyArray<ToolMetadata>\n readonly execute: (call: ToolCall) => Effect.Effect<ToolResult, ToolError>\n}\n\nconst enabled = <Context>(tool: ToolRegistration<Context>, context: Context) =>\n tool.isEnabled === undefined ? Effect.succeed(true) : tool.isEnabled(context)\n\nconst resolveModuleTools = <Context>(toolModule: ToolModule<Context>, context: Context) =>\n Effect.forEach(toolModule.tools, tool =>\n enabled(tool, context).pipe(\n Effect.map(isToolEnabled =>\n isToolEnabled ? Option.some({ moduleId: toolModule.id, tool }) : Option.none()\n )\n )\n ).pipe(Effect.map(Arr.getSomes))\n\nconst duplicateToolError = (name: string) =>\n new ToolRegistryError({\n cause: 'duplicate_tool',\n message: `Duplicate tool registered: ${name}`\n })\n\nconst missingToolError = (name: string) =>\n new ToolError({\n tool: name,\n message: `Tool is not configured: ${name}`,\n cause: 'not_found'\n })\n\nconst unknownToMessage = (error: unknown) =>\n error instanceof Error ? error.message : String(error)\n\nconst objectField = (input: unknown, key: string) =>\n input !== null && typeof input === 'object' ? Object.getOwnPropertyDescriptor(input, key)?.value : undefined\n\nconst isObjectRecord = (input: unknown): input is Readonly<Record<string, unknown>> =>\n input !== null && typeof input === 'object' && !Array.isArray(input)\n\nconst localDefinitionName = (ref: unknown) => {\n if (typeof ref !== 'string') {\n return undefined\n }\n\n const prefix = '#/$defs/'\n\n return ref.startsWith(prefix) ? ref.slice(prefix.length) : undefined\n}\n\nconst hasJsonSchemaType = (input: unknown, type: string) => objectField(input, 'type') === type\n\nconst isEmptyStructJsonSchema = (schema: unknown) => {\n const anyOf = objectField(schema, 'anyOf')\n\n return Array.isArray(anyOf) &&\n anyOf.length === 2 &&\n anyOf.some(item => hasJsonSchemaType(item, 'object')) &&\n anyOf.some(item => hasJsonSchemaType(item, 'array'))\n}\n\nconst isEmptyRecordJsonSchema = (schema: unknown) =>\n hasJsonSchemaType(schema, 'object') &&\n objectField(schema, 'additionalProperties') === false &&\n objectField(schema, 'properties') === undefined &&\n objectField(schema, 'required') === undefined\n\nconst emptyObjectJsonSchema = {\n type: 'object',\n properties: {},\n required: [],\n additionalProperties: false\n}\n\nconst jsonSchemaFromSchema = (schema: Schema.Top) => {\n const document = Schema.toJsonSchemaDocument(schema)\n const definitionName = localDefinitionName(objectField(document.schema, '$ref'))\n const localDefinition = definitionName === undefined\n ? undefined\n : Object.getOwnPropertyDescriptor(document.definitions, definitionName)?.value\n const rootSchema = isObjectRecord(localDefinition) ? localDefinition : document.schema\n const remainingDefinitions = definitionName === undefined\n ? document.definitions\n : Object.fromEntries(\n Object.entries(document.definitions).filter(([name]) => name !== definitionName)\n )\n const jsonSchema = isEmptyStructJsonSchema(rootSchema) || isEmptyRecordJsonSchema(rootSchema)\n ? emptyObjectJsonSchema\n : rootSchema\n\n return Object.keys(remainingDefinitions).length > 0\n ? { ...jsonSchema, $defs: remainingDefinitions }\n : jsonSchema\n}\n\nexport const makeTool = <Context, ParamsSchema extends ToolParamsSchema>(\n options: MakeToolOptions<Context, ParamsSchema>\n): ToolRegistration<Context> => ({\n def: ToolDef.make({\n name: options.name,\n description: options.description,\n parameters: jsonSchemaFromSchema(options.parameters),\n approval: options.approval\n }),\n access: options.access,\n approval: options.approval,\n isEnabled: options.isEnabled,\n execute: ({ call, context }) =>\n Schema.decodeUnknownEffect(options.parameters)(call.params).pipe(\n Effect.matchEffect({\n onFailure: error => {\n const message = options.invalidParamsMessage?.(error) ??\n `Invalid ${options.name} arguments: ${unknownToMessage(error)}`\n\n return Effect.succeed(\n modelVisibleToolErrorResult(\n call,\n modelVisibleToolError({\n tool: options.name,\n message,\n reason: 'validation'\n })\n )\n )\n },\n onSuccess: params => options.execute({ call, context, params }).pipe(\n Effect.catchTag('ModelVisibleToolError', error =>\n Effect.succeed(modelVisibleToolErrorResult(call, error))\n )\n )\n })\n )\n})\n\nconst findDuplicateToolName = <Context>(resolved: ReadonlyArray<ResolvedRegistration<Context>>) => {\n const names = Arr.map(resolved, item => item.tool.def.name)\n\n return Arr.findFirst(names, (name, index) => names.indexOf(name) !== index)\n}\n\nexport const resolveTools = <Context>(\n modules: ReadonlyArray<ToolModule<Context>>,\n context: Context\n): Effect.Effect<ResolvedToolSet, ToolRegistryError> =>\n Effect.gen(function* () {\n const resolvedByModule = yield* Effect.forEach(modules, toolModule =>\n resolveModuleTools(toolModule, context)\n )\n const resolved = Arr.flatten(resolvedByModule)\n const duplicateName = findDuplicateToolName(resolved)\n\n if (Option.isSome(duplicateName)) {\n return yield* Effect.fail(duplicateToolError(duplicateName.value))\n }\n\n const tools = Arr.map(resolved, item => item.tool.def)\n const metadata = Arr.map(resolved, item => ({\n moduleId: item.moduleId,\n name: item.tool.def.name,\n access: item.tool.access\n }))\n\n const execute = (call: ToolCall) =>\n Option.match(\n Arr.findFirst(resolved, item => item.tool.def.name === call.name),\n {\n onNone: () => Effect.fail(missingToolError(call.name)),\n onSome: match => match.tool.execute({ call, context })\n }\n )\n\n return { tools, metadata, execute }\n })\n\nexport const makeToolExecutorLayer = (toolSet: ResolvedToolSet) =>\n Layer.succeed(ToolExecutor, ToolExecutor.of({ execute: toolSet.execute }))\n"],"mappings":";;;;;AAWA,MAAa,aAAa,OAAO,SAAS;CAAC;CAAQ;CAAS;AAAa,CAAC;AAG1E,IAAa,oBAAb,cAAuC,OAAO,iBAAoC,EAChF,qBACA;CACE,SAAS,OAAO;CAChB,OAAO,OAAO,SAAS,CAAC,gBAAgB,CAAC;AAC3C,CACF,EAAE,CAAC;AAEH,MAAa,8BAA8B,OAAO,SAAS;CACzD;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAGD,IAAa,wBAAb,cAA2C,OAAO,iBAAwC,EACxF,yBACA;CACE,MAAM,OAAO;CACb,SAAS,OAAO;CAChB,QAAQ;CACR,SAAS,OAAO,SAAS,OAAO,OAAO;AACzC,CACF,EAAE,CAAC;AAEH,MAAa,+CAA+C,OAAO,OAAO;CACxE,MAAM,OAAO,QAAQ,0BAA0B;CAC/C,MAAM,OAAO;CACb,QAAQ;CACR,SAAS,OAAO;CAChB,SAAS,OAAO,SAAS,OAAO,OAAO;AACzC,CAAC;AAWD,MAAa,yBAAyB,UACpC,IAAI,sBAAsB,KAAK;AAEjC,MAAa,0CACX,WAC4C;CAC5C,MAAM;CACN,MAAM,MAAM;CACZ,QAAQ,MAAM;CACd,SAAS,MAAM;CACf,GAAI,MAAM,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,MAAM,QAAQ;AAClE;AAEA,MAAa,+BACX,MACA,UACG,oBAAoB;CACvB,YAAY,KAAK;CACjB,SAAS,MAAM;CACf,mBAAmB,uCAAuC,KAAK;AACjE,CAAC;AAqBD,MAAa,kBAAkB,OAAO,OAAO,OAAO,QAAQ,OAAO,KAAK;AAqCxE,MAAM,WAAoB,MAAiC,YACzD,KAAK,cAAc,KAAA,IAAY,OAAO,QAAQ,IAAI,IAAI,KAAK,UAAU,OAAO;AAE9E,MAAM,sBAA+B,YAAiC,YACpE,OAAO,QAAQ,WAAW,QAAO,SAC/B,QAAQ,MAAM,OAAO,EAAE,KACrB,OAAO,KAAI,kBACT,gBAAgB,OAAO,KAAK;CAAE,UAAU,WAAW;CAAI;AAAK,CAAC,IAAI,OAAO,KAAK,CAC/E,CACF,CACF,EAAE,KAAK,OAAO,IAAIA,QAAI,QAAQ,CAAC;AAEjC,MAAM,sBAAsB,SAC1B,IAAI,kBAAkB;CACpB,OAAO;CACP,SAAS,8BAA8B;AACzC,CAAC;AAEH,MAAM,oBAAoB,SACxB,IAAI,UAAU;CACZ,MAAM;CACN,SAAS,2BAA2B;CACpC,OAAO;AACT,CAAC;AAEH,MAAM,oBAAoB,UACxB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAEvD,MAAM,eAAe,OAAgB,QACnC,UAAU,QAAQ,OAAO,UAAU,WAAW,OAAO,yBAAyB,OAAO,GAAG,GAAG,QAAQ,KAAA;AAErG,MAAM,kBAAkB,UACtB,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAErE,MAAM,uBAAuB,QAAiB;CAC5C,IAAI,OAAO,QAAQ,UACjB;CAKF,OAAO,IAAI,WAAW,UAAM,IAAI,IAAI,MAAM,CAAa,IAAI,KAAA;AAC7D;AAEA,MAAM,qBAAqB,OAAgB,SAAiB,YAAY,OAAO,MAAM,MAAM;AAE3F,MAAM,2BAA2B,WAAoB;CACnD,MAAM,QAAQ,YAAY,QAAQ,OAAO;CAEzC,OAAO,MAAM,QAAQ,KAAK,KACxB,MAAM,WAAW,KACjB,MAAM,MAAK,SAAQ,kBAAkB,MAAM,QAAQ,CAAC,KACpD,MAAM,MAAK,SAAQ,kBAAkB,MAAM,OAAO,CAAC;AACvD;AAEA,MAAM,2BAA2B,WAC/B,kBAAkB,QAAQ,QAAQ,KAClC,YAAY,QAAQ,sBAAsB,MAAM,SAChD,YAAY,QAAQ,YAAY,MAAM,KAAA,KACtC,YAAY,QAAQ,UAAU,MAAM,KAAA;AAEtC,MAAM,wBAAwB;CAC5B,MAAM;CACN,YAAY,CAAC;CACb,UAAU,CAAC;CACX,sBAAsB;AACxB;AAEA,MAAM,wBAAwB,WAAuB;CACnD,MAAM,WAAW,OAAO,qBAAqB,MAAM;CACnD,MAAM,iBAAiB,oBAAoB,YAAY,SAAS,QAAQ,MAAM,CAAC;CAC/E,MAAM,kBAAkB,mBAAmB,KAAA,IACvC,KAAA,IACA,OAAO,yBAAyB,SAAS,aAAa,cAAc,GAAG;CAC3E,MAAM,aAAa,eAAe,eAAe,IAAI,kBAAkB,SAAS;CAChF,MAAM,uBAAuB,mBAAmB,KAAA,IAC5C,SAAS,cACT,OAAO,YACL,OAAO,QAAQ,SAAS,WAAW,EAAE,QAAQ,CAAC,UAAU,SAAS,cAAc,CACjF;CACJ,MAAM,aAAa,wBAAwB,UAAU,KAAK,wBAAwB,UAAU,IACxF,wBACA;CAEJ,OAAO,OAAO,KAAK,oBAAoB,EAAE,SAAS,IAC9C;EAAE,GAAG;EAAY,OAAO;CAAqB,IAC7C;AACN;AAEA,MAAa,YACX,aAC+B;CAC/B,KAAK,QAAQ,KAAK;EAChB,MAAM,QAAQ;EACd,aAAa,QAAQ;EACrB,YAAY,qBAAqB,QAAQ,UAAU;EACnD,UAAU,QAAQ;CACpB,CAAC;CACD,QAAQ,QAAQ;CAChB,UAAU,QAAQ;CAClB,WAAW,QAAQ;CACnB,UAAU,EAAE,MAAM,cAChB,OAAO,oBAAoB,QAAQ,UAAU,EAAE,KAAK,MAAM,EAAE,KAC1D,OAAO,YAAY;EACjB,YAAW,UAAS;GAClB,MAAM,UAAU,QAAQ,uBAAuB,KAAK,KAClD,WAAW,QAAQ,KAAK,cAAc,iBAAiB,KAAK;GAE9D,OAAO,OAAO,QACZ,4BACE,MACA,sBAAsB;IACpB,MAAM,QAAQ;IACd;IACA,QAAQ;GACV,CAAC,CACH,CACF;EACF;EACA,YAAW,WAAU,QAAQ,QAAQ;GAAE;GAAM;GAAS;EAAO,CAAC,EAAE,KAC9D,OAAO,SAAS,0BAAyB,UACvC,OAAO,QAAQ,4BAA4B,MAAM,KAAK,CAAC,CACzD,CACF;CACF,CAAC,CACH;AACJ;AAEA,MAAM,yBAAkC,aAA2D;CACjG,MAAM,QAAQA,QAAI,IAAI,WAAU,SAAQ,KAAK,KAAK,IAAI,IAAI;CAE1D,OAAOA,QAAI,UAAU,QAAQ,MAAM,UAAU,MAAM,QAAQ,IAAI,MAAM,KAAK;AAC5E;AAEA,MAAa,gBACX,SACA,YAEA,OAAO,IAAI,aAAa;CACtB,MAAM,mBAAmB,OAAO,OAAO,QAAQ,UAAS,eACtD,mBAAmB,YAAY,OAAO,CACxC;CACA,MAAM,WAAWA,QAAI,QAAQ,gBAAgB;CAC7C,MAAM,gBAAgB,sBAAsB,QAAQ;CAEpD,IAAI,OAAO,OAAO,aAAa,GAC7B,OAAO,OAAO,OAAO,KAAK,mBAAmB,cAAc,KAAK,CAAC;CAGnE,MAAM,QAAQA,QAAI,IAAI,WAAU,SAAQ,KAAK,KAAK,GAAG;CACrD,MAAM,WAAWA,QAAI,IAAI,WAAU,UAAS;EAC1C,UAAU,KAAK;EACf,MAAM,KAAK,KAAK,IAAI;EACpB,QAAQ,KAAK,KAAK;CACpB,EAAE;CAEF,MAAM,WAAW,SACf,OAAO,MACLA,QAAI,UAAU,WAAU,SAAQ,KAAK,KAAK,IAAI,SAAS,KAAK,IAAI,GAChE;EACE,cAAc,OAAO,KAAK,iBAAiB,KAAK,IAAI,CAAC;EACrD,SAAQ,UAAS,MAAM,KAAK,QAAQ;GAAE;GAAM;EAAQ,CAAC;CACvD,CACF;CAEF,OAAO;EAAE;EAAO;EAAU;CAAQ;AACpC,CAAC;AAEH,MAAa,yBAAyB,YACpC,MAAM,QAAQ,cAAc,aAAa,GAAG,EAAE,SAAS,QAAQ,QAAQ,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"task.d.mts","names":[],"sources":["../../src/tools/task.ts"],"mappings":";;;;;;;cAca,YAAA;AAAA,cAEP,cAAA,EAAc,MAAA,CAAA,MAAA;EAAA;;;;KAYR,cAAA,UAAwB,cAAA,CAAe,IAAI;AAAA,KAE3C,sBAAA;EAAA,SACD,IAAA;EAAA,SACA,WAAW;AAAA;AAAA,KAGV,mBAAA;EAAA,SACD,QAAQ;AAAA;AAAA,KAGP,kBAAA;EAAA,SACD,IAAA,EAAM,QAAA;EAAA,SACN,OAAA,EAAS,OAAA;EAAA,SACT,MAAA,EAAQ,cAAA;AAAA;AAAA,KAGP,eAAA;EAAA,SACD,SAAA,EAAW,aAAA,CAAc,sBAAA;EAAA,SACzB,SAAA,IAAa,OAAA,EAAS,OAAA,KAAY,MAAA,CAAO,MAAA,UAAgB,iBAAA;EAAA,SACzD,OAAA,GAAU,KAAA,EAAO,kBAAA,CAAmB,OAAA,MAAa,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,SAAA;AAAA;AAAA,KAG1E,mBAAA;EAAA,SACD,MAAA;EAAA,SACA,MAAA;EAAA,SACA,YAAA;EAAA,SACA,WAAA;EAAA,SACA,aAAA;EAAA,SACA,WAAA;EAAA,SACA,SAAA;EAAA,SACA,KAAA;EAAA,SACA,OAAA;AAAA;AAAA,cAgEE,wBAAA,YACX,OAAA,EAAS,eAAA,CAAgB,OAAA,MACxB,gBAAA,CAAiB,OAAA;AAAA,cAoBP,eAAA,GAAmB,SAAA,EAAW,aAAa,CAAC,sBAAA,yCAAuB,OAAA;AAAA,cAMnE,kBAAA,YAA+B,OAAA,EAAS,eAAA,CAAgB,OAAA,MAAW,UAAA,CAAW,OAAA;AAAA,cAK9E,8BAAA,mBAAkD,mBAAA,EAC7D,OAAA,EAAS,eAAA,CAAgB,OAAA,MACxB,UAAA,CAAW,OAAA;AAAA,cASD,gBAAA,GAAoB,MAAc;AAAA,cAElC,iBAAA,GAAiB,gBAAA;AAAA,cAQjB,kBAAA,GAAsB,MAAA,EAAQ,aAAa,CAAC,UAAA;AAAA,cAO5C,kBAAA,GAAsB,KAAA,EAAO,mBAAA,KAAmB,UAc3D"}
1
+ {"version":3,"file":"task.d.mts","names":[],"sources":["../../src/tools/task.ts"],"mappings":";;;;;;;cAqBa,YAAA;AAAA,cAEP,cAAA,EAAc,MAAA,CAAA,MAAA;EAAA;;;;KAYR,cAAA,UAAwB,cAAA,CAAe,IAAI;AAAA,KAE3C,sBAAA;EAAA,SACD,IAAA;EAAA,SACA,WAAW;AAAA;AAAA,KAGV,mBAAA;EAAA,SACD,QAAQ;AAAA;AAAA,KAGP,kBAAA;EAAA,SACD,IAAA,EAAM,QAAA;EAAA,SACN,OAAA,EAAS,OAAA;EAAA,SACT,MAAA,EAAQ,cAAA;AAAA;AAAA,KAGP,eAAA;EAAA,SACD,SAAA,EAAW,aAAA,CAAc,sBAAA;EAAA,SACzB,SAAA,IAAa,OAAA,EAAS,OAAA,KAAY,MAAA,CAAO,MAAA,UAAgB,iBAAA;EAAA,SACzD,OAAA,GAAU,KAAA,EAAO,kBAAA,CAAmB,OAAA,MAAa,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,SAAA;AAAA;AAAA,KAG1E,mBAAA;EAAA,SACD,MAAA;EAAA,SACA,MAAA;EAAA,SACA,YAAA;EAAA,SACA,WAAA;EAAA,SACA,aAAA;EAAA,SACA,WAAA;EAAA,SACA,SAAA;EAAA,SACA,KAAA;EAAA,SACA,OAAA;AAAA;AAAA,cA2EE,wBAAA,YACX,OAAA,EAAS,eAAA,CAAgB,OAAA,MACxB,gBAAA,CAAiB,OAAA;AAAA,cAoBP,eAAA,GAAmB,SAAA,EAAW,aAAa,CAAC,sBAAA,yCAAuB,OAAA;AAAA,cAMnE,kBAAA,YAA+B,OAAA,EAAS,eAAA,CAAgB,OAAA,MAAW,UAAA,CAAW,OAAA;AAAA,cAK9E,8BAAA,mBAAkD,mBAAA,EAC7D,OAAA,EAAS,eAAA,CAAgB,OAAA,MACxB,UAAA,CAAW,OAAA;AAAA,cASD,gBAAA,GAAoB,MAAc;AAAA,cAElC,iBAAA,GAAiB,gBAAA;AAAA,cAQjB,kBAAA,GAAsB,MAAA,EAAQ,aAAa,CAAC,UAAA;AAAA,cAO5C,kBAAA,GAAsB,KAAA,EAAO,mBAAA,KAAmB,UAc3D"}
@@ -1,4 +1,4 @@
1
- import { makeTool } from "./registry.mjs";
1
+ import { makeTool, modelVisibleToolError } from "./registry.mjs";
2
2
  import { Effect } from "effect";
3
3
  import * as Schema from "effect/Schema";
4
4
  import { ToolResult, assistantContent, contentText, makeSubagentRunId } from "@yolk-sdk/agent/protocol";
@@ -15,6 +15,11 @@ const taskToolError = (message, cause) => new ToolError({
15
15
  message,
16
16
  cause
17
17
  });
18
+ const taskModelVisibleError = (message) => modelVisibleToolError({
19
+ tool: taskToolName,
20
+ message,
21
+ reason: "validation"
22
+ });
18
23
  const trimmedTaskParams = (params) => ({
19
24
  description: params.description.trim(),
20
25
  prompt: params.prompt.trim(),
@@ -22,15 +27,15 @@ const trimmedTaskParams = (params) => ({
22
27
  });
23
28
  const validateTaskParams = (params) => {
24
29
  const trimmed = trimmedTaskParams(params);
25
- if (trimmed.description.length === 0) return Effect.fail(taskToolError("description must not be empty", "validation"));
26
- if (trimmed.prompt.length === 0) return Effect.fail(taskToolError("prompt must not be empty", "validation"));
27
- if (trimmed.subagent_type.length === 0) return Effect.fail(taskToolError("subagent_type must not be empty", "validation"));
30
+ if (trimmed.description.length === 0) return Effect.fail(taskModelVisibleError("description must not be empty"));
31
+ if (trimmed.prompt.length === 0) return Effect.fail(taskModelVisibleError("prompt must not be empty"));
32
+ if (trimmed.subagent_type.length === 0) return Effect.fail(taskModelVisibleError("subagent_type must not be empty"));
28
33
  return Effect.succeed(trimmed);
29
34
  };
30
35
  const findSubagent = (subagents, name) => subagents.find((subagent) => subagent.name === name);
31
36
  const requireKnownSubagent = (subagents, name) => {
32
37
  const subagent = findSubagent(subagents, name);
33
- return subagent === void 0 ? Effect.fail(taskToolError(`Unknown subagent type: ${name}`, "validation")) : Effect.succeed(subagent);
38
+ return subagent === void 0 ? Effect.fail(taskModelVisibleError(`Unknown subagent type: ${name}`)) : Effect.succeed(subagent);
34
39
  };
35
40
  const subagentDescription = (subagent) => `- ${subagent.name}: ${subagent.description}`;
36
41
  const taskToolDescription = (subagents) => [
@@ -1 +1 @@
1
- {"version":3,"file":"task.mjs","names":[],"sources":["../../src/tools/task.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ToolError } from '@yolk-sdk/agent/loop'\nimport {\n assistantContent,\n contentText,\n makeSubagentRunId,\n ToolResult,\n type AgentEvent,\n type AgentMessage,\n type ToolCall\n} from '@yolk-sdk/agent/protocol'\nimport { makeTool, type ToolModule, type ToolRegistration, type ToolRegistryError } from './registry.ts'\n\nexport const taskToolName = 'task'\n\nconst TaskToolParams = Schema.Struct({\n description: Schema.String.pipe(Schema.annotate({ description: 'A short 3-5 word description of the task.' })),\n prompt: Schema.String.pipe(\n Schema.annotate({\n description: 'The complete task instructions for the subagent, including all context it needs.'\n })\n ),\n subagent_type: Schema.String.pipe(\n Schema.annotate({ description: 'The specialized subagent type to use for this task.' })\n )\n})\n\nexport type TaskToolParams = typeof TaskToolParams.Type\n\nexport type TaskSubagentDefinition = {\n readonly name: string\n readonly description: string\n}\n\nexport type TaskSubagentContext = {\n readonly subagent?: boolean\n}\n\nexport type TaskExecutionInput<Context> = {\n readonly call: ToolCall\n readonly context: Context\n readonly params: TaskToolParams\n}\n\nexport type TaskToolOptions<Context> = {\n readonly subagents: ReadonlyArray<TaskSubagentDefinition>\n readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>\n readonly execute: (input: TaskExecutionInput<Context>) => Effect.Effect<ToolResult, ToolError>\n}\n\nexport type TaskToolResultInput = {\n readonly callId: string\n readonly output: string\n readonly subagentType: string\n readonly description: string\n readonly subagentRunId: string\n readonly startedAtMs: number\n readonly endedAtMs: number\n readonly model: string\n readonly isError?: boolean\n}\n\nconst taskToolError = (message: string, cause: ToolError['cause']) =>\n new ToolError({\n tool: taskToolName,\n message,\n cause\n })\n\nconst trimmedTaskParams = (params: TaskToolParams) => ({\n description: params.description.trim(),\n prompt: params.prompt.trim(),\n subagent_type: params.subagent_type.trim()\n})\n\nconst validateTaskParams = (params: TaskToolParams) => {\n const trimmed = trimmedTaskParams(params)\n\n if (trimmed.description.length === 0) {\n return Effect.fail(taskToolError('description must not be empty', 'validation'))\n }\n\n if (trimmed.prompt.length === 0) {\n return Effect.fail(taskToolError('prompt must not be empty', 'validation'))\n }\n\n if (trimmed.subagent_type.length === 0) {\n return Effect.fail(taskToolError('subagent_type must not be empty', 'validation'))\n }\n\n return Effect.succeed(trimmed)\n}\n\nconst findSubagent = (subagents: ReadonlyArray<TaskSubagentDefinition>, name: string) =>\n subagents.find(subagent => subagent.name === name)\n\nconst requireKnownSubagent = (\n subagents: ReadonlyArray<TaskSubagentDefinition>,\n name: string\n) => {\n const subagent = findSubagent(subagents, name)\n\n return subagent === undefined\n ? Effect.fail(taskToolError(`Unknown subagent type: ${name}`, 'validation'))\n : Effect.succeed(subagent)\n}\n\nconst subagentDescription = (subagent: TaskSubagentDefinition) =>\n `- ${subagent.name}: ${subagent.description}`\n\nconst taskToolDescription = (subagents: ReadonlyArray<TaskSubagentDefinition>) =>\n [\n 'Launch a new agent to handle complex, multistep tasks autonomously.',\n 'Use this when delegating focused work to a specialized subagent would save context or allow parallel exploration.',\n 'To run subagents in parallel, call this task tool multiple times in the same assistant response.',\n 'Yolk runs same-turn task calls concurrently automatically.',\n 'A fresh subagent only sees the prompt you provide, so include all required context.',\n 'Subagents can use their normal tools but cannot launch further task subagents in v1.',\n subagents.length === 0\n ? 'No subagent types are currently available.'\n : `Available subagent types:\\n${subagents.map(subagentDescription).join('\\n')}`\n ].join('\\n\\n')\n\nexport const makeTaskToolRegistration = <Context>(\n options: TaskToolOptions<Context>\n): ToolRegistration<Context> => makeTool({\n name: taskToolName,\n description: taskToolDescription(options.subagents),\n parameters: TaskToolParams,\n access: 'read',\n isEnabled: options.isEnabled,\n invalidParamsMessage: error => `Invalid task arguments: ${error instanceof Error ? error.message : String(error)}`,\n execute: ({ call, context, params }) =>\n Effect.gen(function* () {\n if (call.name !== taskToolName) {\n return yield* Effect.fail(taskToolError(`Tool is not configured: ${call.name}`, 'not_found'))\n }\n\n const normalizedParams = yield* validateTaskParams(params)\n yield* requireKnownSubagent(options.subagents, normalizedParams.subagent_type)\n\n return yield* options.execute({ call, context, params: normalizedParams })\n })\n})\n\nexport const makeTaskToolDef = (subagents: ReadonlyArray<TaskSubagentDefinition>) =>\n makeTaskToolRegistration({\n subagents,\n execute: ({ call }) => Effect.succeed(ToolResult.make({ toolCallId: call.id, content: '' }))\n }).def\n\nexport const makeTaskToolModule = <Context>(options: TaskToolOptions<Context>): ToolModule<Context> => ({\n id: 'task',\n tools: [makeTaskToolRegistration(options)]\n})\n\nexport const makeNonRecursiveTaskToolModule = <Context extends TaskSubagentContext>(\n options: TaskToolOptions<Context>\n): ToolModule<Context> => makeTaskToolModule({\n ...options,\n isEnabled: context => context.subagent === true\n ? Effect.succeed(false)\n : options.isEnabled === undefined\n ? Effect.succeed(true)\n : options.isEnabled(context)\n})\n\nexport const formatTaskResult = (output: string) => ['<task_result>', output, '</task_result>'].join('\\n')\n\nexport const taskSubagentRunId = makeSubagentRunId\n\nconst latestAssistantText = (messages: ReadonlyArray<AgentMessage>) => {\n const assistant = [...messages].reverse().find(message => message._tag === 'Assistant')\n\n return assistant === undefined ? '' : contentText(assistantContent(assistant))\n}\n\nexport const subagentResultText = (events: ReadonlyArray<AgentEvent>) => {\n const messages = [...events].reverse().find(event => event._tag === 'AgentEnd')?.messages ?? []\n const text = latestAssistantText(messages).trim()\n\n return text.length === 0 ? 'Subagent completed without a final text response.' : text\n}\n\nexport const makeTaskToolResult = (input: TaskToolResultInput) => ToolResult.make({\n toolCallId: input.callId,\n content: formatTaskResult(input.output),\n isError: input.isError,\n structuredContent: {\n subagent_run_id: input.subagentRunId,\n subagent_type: input.subagentType,\n description: input.description,\n started_at_ms: input.startedAtMs,\n ended_at_ms: input.endedAtMs,\n duration_ms: Math.max(0, input.endedAtMs - input.startedAtMs),\n status: input.isError === true ? 'error' : 'completed',\n model: input.model\n }\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"task.mjs","names":[],"sources":["../../src/tools/task.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ToolError } from '@yolk-sdk/agent/loop'\nimport {\n assistantContent,\n contentText,\n makeSubagentRunId,\n ToolResult,\n type AgentEvent,\n type AgentMessage,\n type ToolCall\n} from '@yolk-sdk/agent/protocol'\nimport {\n makeTool,\n modelVisibleToolError,\n type ModelVisibleToolError,\n type ToolModule,\n type ToolRegistration,\n type ToolRegistryError\n} from './registry.ts'\n\nexport const taskToolName = 'task'\n\nconst TaskToolParams = Schema.Struct({\n description: Schema.String.pipe(Schema.annotate({ description: 'A short 3-5 word description of the task.' })),\n prompt: Schema.String.pipe(\n Schema.annotate({\n description: 'The complete task instructions for the subagent, including all context it needs.'\n })\n ),\n subagent_type: Schema.String.pipe(\n Schema.annotate({ description: 'The specialized subagent type to use for this task.' })\n )\n})\n\nexport type TaskToolParams = typeof TaskToolParams.Type\n\nexport type TaskSubagentDefinition = {\n readonly name: string\n readonly description: string\n}\n\nexport type TaskSubagentContext = {\n readonly subagent?: boolean\n}\n\nexport type TaskExecutionInput<Context> = {\n readonly call: ToolCall\n readonly context: Context\n readonly params: TaskToolParams\n}\n\nexport type TaskToolOptions<Context> = {\n readonly subagents: ReadonlyArray<TaskSubagentDefinition>\n readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>\n readonly execute: (input: TaskExecutionInput<Context>) => Effect.Effect<ToolResult, ToolError>\n}\n\nexport type TaskToolResultInput = {\n readonly callId: string\n readonly output: string\n readonly subagentType: string\n readonly description: string\n readonly subagentRunId: string\n readonly startedAtMs: number\n readonly endedAtMs: number\n readonly model: string\n readonly isError?: boolean\n}\n\nconst taskToolError = (message: string, cause: ToolError['cause']) =>\n new ToolError({\n tool: taskToolName,\n message,\n cause\n })\n\nconst taskModelVisibleError = (message: string) =>\n modelVisibleToolError({\n tool: taskToolName,\n message,\n reason: 'validation'\n })\n\nconst trimmedTaskParams = (params: TaskToolParams) => ({\n description: params.description.trim(),\n prompt: params.prompt.trim(),\n subagent_type: params.subagent_type.trim()\n})\n\nconst validateTaskParams = (params: TaskToolParams): Effect.Effect<{\n readonly description: string\n readonly prompt: string\n readonly subagent_type: string\n}, ModelVisibleToolError> => {\n const trimmed = trimmedTaskParams(params)\n\n if (trimmed.description.length === 0) {\n return Effect.fail(taskModelVisibleError('description must not be empty'))\n }\n\n if (trimmed.prompt.length === 0) {\n return Effect.fail(taskModelVisibleError('prompt must not be empty'))\n }\n\n if (trimmed.subagent_type.length === 0) {\n return Effect.fail(taskModelVisibleError('subagent_type must not be empty'))\n }\n\n return Effect.succeed(trimmed)\n}\n\nconst findSubagent = (subagents: ReadonlyArray<TaskSubagentDefinition>, name: string) =>\n subagents.find(subagent => subagent.name === name)\n\nconst requireKnownSubagent = (\n subagents: ReadonlyArray<TaskSubagentDefinition>,\n name: string\n): Effect.Effect<TaskSubagentDefinition, ModelVisibleToolError> => {\n const subagent = findSubagent(subagents, name)\n\n return subagent === undefined\n ? Effect.fail(taskModelVisibleError(`Unknown subagent type: ${name}`))\n : Effect.succeed(subagent)\n}\n\nconst subagentDescription = (subagent: TaskSubagentDefinition) =>\n `- ${subagent.name}: ${subagent.description}`\n\nconst taskToolDescription = (subagents: ReadonlyArray<TaskSubagentDefinition>) =>\n [\n 'Launch a new agent to handle complex, multistep tasks autonomously.',\n 'Use this when delegating focused work to a specialized subagent would save context or allow parallel exploration.',\n 'To run subagents in parallel, call this task tool multiple times in the same assistant response.',\n 'Yolk runs same-turn task calls concurrently automatically.',\n 'A fresh subagent only sees the prompt you provide, so include all required context.',\n 'Subagents can use their normal tools but cannot launch further task subagents in v1.',\n subagents.length === 0\n ? 'No subagent types are currently available.'\n : `Available subagent types:\\n${subagents.map(subagentDescription).join('\\n')}`\n ].join('\\n\\n')\n\nexport const makeTaskToolRegistration = <Context>(\n options: TaskToolOptions<Context>\n): ToolRegistration<Context> => makeTool({\n name: taskToolName,\n description: taskToolDescription(options.subagents),\n parameters: TaskToolParams,\n access: 'read',\n isEnabled: options.isEnabled,\n invalidParamsMessage: error => `Invalid task arguments: ${error instanceof Error ? error.message : String(error)}`,\n execute: ({ call, context, params }) =>\n Effect.gen(function* () {\n if (call.name !== taskToolName) {\n return yield* Effect.fail(taskToolError(`Tool is not configured: ${call.name}`, 'not_found'))\n }\n\n const normalizedParams = yield* validateTaskParams(params)\n yield* requireKnownSubagent(options.subagents, normalizedParams.subagent_type)\n\n return yield* options.execute({ call, context, params: normalizedParams })\n })\n})\n\nexport const makeTaskToolDef = (subagents: ReadonlyArray<TaskSubagentDefinition>) =>\n makeTaskToolRegistration({\n subagents,\n execute: ({ call }) => Effect.succeed(ToolResult.make({ toolCallId: call.id, content: '' }))\n }).def\n\nexport const makeTaskToolModule = <Context>(options: TaskToolOptions<Context>): ToolModule<Context> => ({\n id: 'task',\n tools: [makeTaskToolRegistration(options)]\n})\n\nexport const makeNonRecursiveTaskToolModule = <Context extends TaskSubagentContext>(\n options: TaskToolOptions<Context>\n): ToolModule<Context> => makeTaskToolModule({\n ...options,\n isEnabled: context => context.subagent === true\n ? Effect.succeed(false)\n : options.isEnabled === undefined\n ? Effect.succeed(true)\n : options.isEnabled(context)\n})\n\nexport const formatTaskResult = (output: string) => ['<task_result>', output, '</task_result>'].join('\\n')\n\nexport const taskSubagentRunId = makeSubagentRunId\n\nconst latestAssistantText = (messages: ReadonlyArray<AgentMessage>) => {\n const assistant = [...messages].reverse().find(message => message._tag === 'Assistant')\n\n return assistant === undefined ? '' : contentText(assistantContent(assistant))\n}\n\nexport const subagentResultText = (events: ReadonlyArray<AgentEvent>) => {\n const messages = [...events].reverse().find(event => event._tag === 'AgentEnd')?.messages ?? []\n const text = latestAssistantText(messages).trim()\n\n return text.length === 0 ? 'Subagent completed without a final text response.' : text\n}\n\nexport const makeTaskToolResult = (input: TaskToolResultInput) => ToolResult.make({\n toolCallId: input.callId,\n content: formatTaskResult(input.output),\n isError: input.isError,\n structuredContent: {\n subagent_run_id: input.subagentRunId,\n subagent_type: input.subagentType,\n description: input.description,\n started_at_ms: input.startedAtMs,\n ended_at_ms: input.endedAtMs,\n duration_ms: Math.max(0, input.endedAtMs - input.startedAtMs),\n status: input.isError === true ? 'error' : 'completed',\n model: input.model\n }\n})\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yolk-sdk/agent",
3
- "version": "0.1.0-canary.16",
3
+ "version": "0.1.0-canary.17",
4
4
  "description": "Protocol, loop, runtime, client, compaction, tools, React, providers, OAuth, skillset, and voice primitives for building Yolk agents.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -117,6 +117,7 @@ export {
117
117
  plainQuestionResponse,
118
118
  plainToolApprovalResponse,
119
119
  questionResponseStructuredContent,
120
+ makeErrorToolResult,
120
121
  ToolApprovalDecision,
121
122
  ToolApprovalMode,
122
123
  ToolApprovalPolicy,
@@ -127,6 +128,7 @@ export {
127
128
  ToolResult
128
129
  } from './tool.ts'
129
130
  export type {
131
+ ErrorToolResultInput,
130
132
  PlainHitlResponse,
131
133
  PlainQuestionAnswer,
132
134
  PlainQuestionResponse,
@@ -37,6 +37,22 @@ export class ToolResult extends Schema.Class<ToolResult>('ToolResult')({
37
37
  structuredContent: Schema.optional(Schema.Unknown)
38
38
  }) {}
39
39
 
40
+ export type ErrorToolResultInput = {
41
+ readonly toolCallId: string
42
+ readonly content: Content
43
+ readonly structuredContent?: unknown
44
+ }
45
+
46
+ export const makeErrorToolResult = (input: ErrorToolResultInput) =>
47
+ ToolResult.make({
48
+ toolCallId: input.toolCallId,
49
+ content: input.content,
50
+ isError: true,
51
+ ...(input.structuredContent === undefined
52
+ ? {}
53
+ : { structuredContent: input.structuredContent })
54
+ })
55
+
40
56
  export class ToolApprovalRequest extends Schema.TaggedClass<ToolApprovalRequest>()(
41
57
  'ToolApprovalRequest',
42
58
  {
@@ -10,6 +10,7 @@ Generic host tool registration and resolution.
10
10
  - Adapter from resolved tools to `@yolk-sdk/agent/loop` `ToolExecutor`.
11
11
  - Package-owned `task` and `question` tool contracts.
12
12
  - Helpers for task subagent result metadata and non-recursive task tool exposure.
13
+ - `ModelVisibleToolError` helpers for recoverable, model-visible tool failures.
13
14
 
14
15
  ## Use it when
15
16
 
@@ -22,6 +23,27 @@ Generic host tool registration and resolution.
22
23
  - No provider SDKs.
23
24
  - Tool access/approval is metadata; host apps enforce product policy.
24
25
 
26
+ ## Recoverable tool failures
27
+
28
+ Use `modelVisibleToolError(...)` for expected failures the model can recover from: validation,
29
+ invalid input, denied policy, not-found resources, unavailable upstream data, or timeouts. `makeTool`
30
+ converts these into `ToolResult.isError = true` with structured content:
31
+
32
+ ```ts
33
+ import { Effect } from 'effect'
34
+ import { modelVisibleToolError } from '@yolk-sdk/agent/tools'
35
+
36
+ return Effect.fail(modelVisibleToolError({
37
+ tool: 'search_docs',
38
+ reason: 'not_found',
39
+ message: 'Document not found',
40
+ details: { documentId: 'doc_123' }
41
+ }))
42
+ ```
43
+
44
+ Use `ToolError` for fatal runtime/tool infrastructure failures such as broken wiring, auth/config,
45
+ storage outages, or implementation bugs.
46
+
25
47
  ## Task subagents
26
48
 
27
49
  `task` is the standard tool for delegating focused work to a subagent. The SDK owns the
@@ -1,4 +1,17 @@
1
- export { EmptyToolParams, makeTool, makeToolExecutorLayer, resolveTools, ToolAccess, ToolRegistryError } from './registry.ts'
1
+ export {
2
+ EmptyToolParams,
3
+ makeTool,
4
+ makeToolExecutorLayer,
5
+ modelVisibleToolError,
6
+ modelVisibleToolErrorResult,
7
+ modelVisibleToolErrorStructuredContent,
8
+ ModelVisibleToolError,
9
+ ModelVisibleToolErrorReason,
10
+ ModelVisibleToolErrorStructuredContentSchema,
11
+ resolveTools,
12
+ ToolAccess,
13
+ ToolRegistryError
14
+ } from './registry.ts'
2
15
  export {
3
16
  makeQuestionToolDef,
4
17
  makeQuestionToolModule,
@@ -19,6 +32,8 @@ export {
19
32
  export type {
20
33
  ResolvedToolSet,
21
34
  SchemaToolExecutionInput,
35
+ ModelVisibleToolErrorInput,
36
+ ModelVisibleToolErrorStructuredContent,
22
37
  ToolExecutionInput,
23
38
  ToolMetadata,
24
39
  ToolModule,
@@ -1,7 +1,13 @@
1
1
  import { Array as Arr, Effect, Layer, Option } from 'effect'
2
2
  import * as Schema from 'effect/Schema'
3
3
  import { ToolError, ToolExecutor } from '@yolk-sdk/agent/loop'
4
- import { ToolDef, type ToolApprovalPolicy, type ToolCall, type ToolResult } from '@yolk-sdk/agent/protocol'
4
+ import {
5
+ makeErrorToolResult,
6
+ ToolDef,
7
+ type ToolApprovalPolicy,
8
+ type ToolCall,
9
+ type ToolResult
10
+ } from '@yolk-sdk/agent/protocol'
5
11
 
6
12
  export const ToolAccess = Schema.Literals(['read', 'write', 'destructive'])
7
13
  export type ToolAccess = typeof ToolAccess.Type
@@ -14,6 +20,66 @@ export class ToolRegistryError extends Schema.TaggedErrorClass<ToolRegistryError
14
20
  }
15
21
  ) {}
16
22
 
23
+ export const ModelVisibleToolErrorReason = Schema.Literals([
24
+ 'validation',
25
+ 'invalid_input',
26
+ 'permission',
27
+ 'denied',
28
+ 'not_found',
29
+ 'unavailable',
30
+ 'timeout'
31
+ ])
32
+ export type ModelVisibleToolErrorReason = typeof ModelVisibleToolErrorReason.Type
33
+
34
+ export class ModelVisibleToolError extends Schema.TaggedErrorClass<ModelVisibleToolError>()(
35
+ 'ModelVisibleToolError',
36
+ {
37
+ tool: Schema.String,
38
+ message: Schema.String,
39
+ reason: ModelVisibleToolErrorReason,
40
+ details: Schema.optional(Schema.Unknown)
41
+ }
42
+ ) {}
43
+
44
+ export const ModelVisibleToolErrorStructuredContentSchema = Schema.Struct({
45
+ type: Schema.Literal('model_visible_tool_error'),
46
+ tool: Schema.String,
47
+ reason: ModelVisibleToolErrorReason,
48
+ message: Schema.String,
49
+ details: Schema.optional(Schema.Unknown)
50
+ })
51
+ export type ModelVisibleToolErrorStructuredContent =
52
+ typeof ModelVisibleToolErrorStructuredContentSchema.Type
53
+
54
+ export type ModelVisibleToolErrorInput = {
55
+ readonly tool: string
56
+ readonly message: string
57
+ readonly reason: ModelVisibleToolErrorReason
58
+ readonly details?: unknown
59
+ }
60
+
61
+ export const modelVisibleToolError = (input: ModelVisibleToolErrorInput) =>
62
+ new ModelVisibleToolError(input)
63
+
64
+ export const modelVisibleToolErrorStructuredContent = (
65
+ error: ModelVisibleToolError
66
+ ): ModelVisibleToolErrorStructuredContent => ({
67
+ type: 'model_visible_tool_error',
68
+ tool: error.tool,
69
+ reason: error.reason,
70
+ message: error.message,
71
+ ...(error.details === undefined ? {} : { details: error.details })
72
+ })
73
+
74
+ export const modelVisibleToolErrorResult = (
75
+ call: ToolCall,
76
+ error: ModelVisibleToolError
77
+ ) => makeErrorToolResult({
78
+ toolCallId: call.id,
79
+ content: error.message,
80
+ structuredContent: modelVisibleToolErrorStructuredContent(error)
81
+ })
82
+
17
83
  export type ToolExecutionInput<Context> = {
18
84
  readonly call: ToolCall
19
85
  readonly context: Context
@@ -45,7 +111,7 @@ export type MakeToolOptions<Context, ParamsSchema extends ToolParamsSchema> = {
45
111
  readonly invalidParamsMessage?: (error: unknown) => string
46
112
  readonly execute: (
47
113
  input: SchemaToolExecutionInput<Context, ParamsSchema['Type']>
48
- ) => Effect.Effect<ToolResult, ToolError>
114
+ ) => Effect.Effect<ToolResult, ToolError | ModelVisibleToolError>
49
115
  }
50
116
 
51
117
  export type ToolModule<Context> = {
@@ -173,14 +239,28 @@ export const makeTool = <Context, ParamsSchema extends ToolParamsSchema>(
173
239
  isEnabled: options.isEnabled,
174
240
  execute: ({ call, context }) =>
175
241
  Schema.decodeUnknownEffect(options.parameters)(call.params).pipe(
176
- Effect.mapError(error =>
177
- new ToolError({
178
- tool: options.name,
179
- message: options.invalidParamsMessage?.(error) ?? `Invalid ${options.name} arguments: ${unknownToMessage(error)}`,
180
- cause: 'validation'
181
- })
182
- ),
183
- Effect.flatMap(params => options.execute({ call, context, params }))
242
+ Effect.matchEffect({
243
+ onFailure: error => {
244
+ const message = options.invalidParamsMessage?.(error) ??
245
+ `Invalid ${options.name} arguments: ${unknownToMessage(error)}`
246
+
247
+ return Effect.succeed(
248
+ modelVisibleToolErrorResult(
249
+ call,
250
+ modelVisibleToolError({
251
+ tool: options.name,
252
+ message,
253
+ reason: 'validation'
254
+ })
255
+ )
256
+ )
257
+ },
258
+ onSuccess: params => options.execute({ call, context, params }).pipe(
259
+ Effect.catchTag('ModelVisibleToolError', error =>
260
+ Effect.succeed(modelVisibleToolErrorResult(call, error))
261
+ )
262
+ )
263
+ })
184
264
  )
185
265
  })
186
266
 
package/src/tools/task.ts CHANGED
@@ -10,7 +10,14 @@ import {
10
10
  type AgentMessage,
11
11
  type ToolCall
12
12
  } from '@yolk-sdk/agent/protocol'
13
- import { makeTool, type ToolModule, type ToolRegistration, type ToolRegistryError } from './registry.ts'
13
+ import {
14
+ makeTool,
15
+ modelVisibleToolError,
16
+ type ModelVisibleToolError,
17
+ type ToolModule,
18
+ type ToolRegistration,
19
+ type ToolRegistryError
20
+ } from './registry.ts'
14
21
 
15
22
  export const taskToolName = 'task'
16
23
 
@@ -68,25 +75,36 @@ const taskToolError = (message: string, cause: ToolError['cause']) =>
68
75
  cause
69
76
  })
70
77
 
78
+ const taskModelVisibleError = (message: string) =>
79
+ modelVisibleToolError({
80
+ tool: taskToolName,
81
+ message,
82
+ reason: 'validation'
83
+ })
84
+
71
85
  const trimmedTaskParams = (params: TaskToolParams) => ({
72
86
  description: params.description.trim(),
73
87
  prompt: params.prompt.trim(),
74
88
  subagent_type: params.subagent_type.trim()
75
89
  })
76
90
 
77
- const validateTaskParams = (params: TaskToolParams) => {
91
+ const validateTaskParams = (params: TaskToolParams): Effect.Effect<{
92
+ readonly description: string
93
+ readonly prompt: string
94
+ readonly subagent_type: string
95
+ }, ModelVisibleToolError> => {
78
96
  const trimmed = trimmedTaskParams(params)
79
97
 
80
98
  if (trimmed.description.length === 0) {
81
- return Effect.fail(taskToolError('description must not be empty', 'validation'))
99
+ return Effect.fail(taskModelVisibleError('description must not be empty'))
82
100
  }
83
101
 
84
102
  if (trimmed.prompt.length === 0) {
85
- return Effect.fail(taskToolError('prompt must not be empty', 'validation'))
103
+ return Effect.fail(taskModelVisibleError('prompt must not be empty'))
86
104
  }
87
105
 
88
106
  if (trimmed.subagent_type.length === 0) {
89
- return Effect.fail(taskToolError('subagent_type must not be empty', 'validation'))
107
+ return Effect.fail(taskModelVisibleError('subagent_type must not be empty'))
90
108
  }
91
109
 
92
110
  return Effect.succeed(trimmed)
@@ -98,11 +116,11 @@ const findSubagent = (subagents: ReadonlyArray<TaskSubagentDefinition>, name: st
98
116
  const requireKnownSubagent = (
99
117
  subagents: ReadonlyArray<TaskSubagentDefinition>,
100
118
  name: string
101
- ) => {
119
+ ): Effect.Effect<TaskSubagentDefinition, ModelVisibleToolError> => {
102
120
  const subagent = findSubagent(subagents, name)
103
121
 
104
122
  return subagent === undefined
105
- ? Effect.fail(taskToolError(`Unknown subagent type: ${name}`, 'validation'))
123
+ ? Effect.fail(taskModelVisibleError(`Unknown subagent type: ${name}`))
106
124
  : Effect.succeed(subagent)
107
125
  }
108
126