effect 4.0.4 → 4.0.5
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/ai-docs/src/52_graphql/10_basics.ts +19 -13
- package/ai-docs/src/52_graphql/30_batching.ts +6 -4
- package/ai-docs/src/52_graphql/40_aliased-batching.ts +6 -4
- package/dist/Array.d.ts +90 -6
- package/dist/Array.d.ts.map +1 -1
- package/dist/Array.js +4 -2
- package/dist/Array.js.map +1 -1
- package/dist/Channel.d.ts +6 -1
- package/dist/Channel.d.ts.map +1 -1
- package/dist/Channel.js +17 -3
- package/dist/Channel.js.map +1 -1
- package/dist/ConfigProvider.d.ts.map +1 -1
- package/dist/ConfigProvider.js +33 -32
- package/dist/ConfigProvider.js.map +1 -1
- package/dist/Duration.d.ts.map +1 -1
- package/dist/Duration.js +2 -5
- package/dist/Duration.js.map +1 -1
- package/dist/Effect.d.ts +61 -19
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +58 -39
- package/dist/Effect.js.map +1 -1
- package/dist/FileSystem.d.ts +23 -9
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js.map +1 -1
- package/dist/Match.d.ts +20 -6
- package/dist/Match.d.ts.map +1 -1
- package/dist/Match.js +2 -2
- package/dist/Match.js.map +1 -1
- package/dist/Path.d.ts +37 -5
- package/dist/Path.d.ts.map +1 -1
- package/dist/Path.js +36 -5
- package/dist/Path.js.map +1 -1
- package/dist/Schema.d.ts +7 -2
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +9 -2
- package/dist/Schema.js.map +1 -1
- package/dist/String.d.ts +12 -0
- package/dist/String.d.ts.map +1 -1
- package/dist/String.js +17 -4
- package/dist/String.js.map +1 -1
- package/dist/TxRef.d.ts.map +1 -1
- package/dist/TxRef.js +3 -2
- package/dist/TxRef.js.map +1 -1
- package/dist/ai/AiError.d.ts +10 -10
- package/dist/ai/AiError.d.ts.map +1 -1
- package/dist/ai/AiError.js +1 -1
- package/dist/ai/AiError.js.map +1 -1
- package/dist/ai/Decision.d.ts +70 -19
- package/dist/ai/Decision.d.ts.map +1 -1
- package/dist/ai/Decision.js +37 -3
- package/dist/ai/Decision.js.map +1 -1
- package/dist/ai/DecisionModel.js +1 -1
- package/dist/ai/DecisionModel.js.map +1 -1
- package/dist/ai/LanguageModel.d.ts.map +1 -1
- package/dist/ai/LanguageModel.js +47 -35
- package/dist/ai/LanguageModel.js.map +1 -1
- package/dist/ai/McpServer.d.ts +6 -52
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +2 -28
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/Response.d.ts +1 -1
- package/dist/cli/Completions.d.ts +5 -0
- package/dist/cli/Completions.d.ts.map +1 -1
- package/dist/cli/Completions.js.map +1 -1
- package/dist/cli/Flag.d.ts +100 -0
- package/dist/cli/Flag.d.ts.map +1 -1
- package/dist/cli/Flag.js +33 -0
- package/dist/cli/Flag.js.map +1 -1
- package/dist/cli/Param.d.ts +87 -0
- package/dist/cli/Param.d.ts.map +1 -1
- package/dist/cli/Param.js +30 -0
- package/dist/cli/Param.js.map +1 -1
- package/dist/cli/internal/command.d.ts.map +1 -1
- package/dist/cli/internal/command.js +2 -1
- package/dist/cli/internal/command.js.map +1 -1
- package/dist/cli/internal/completions/bash.js +4 -3
- package/dist/cli/internal/completions/bash.js.map +1 -1
- package/dist/cli/internal/completions/descriptor.js +8 -1
- package/dist/cli/internal/completions/descriptor.js.map +1 -1
- package/dist/cli/internal/completions/fish.js +4 -4
- package/dist/cli/internal/completions/fish.js.map +1 -1
- package/dist/cli/internal/completions/powershell.js +3 -2
- package/dist/cli/internal/completions/powershell.js.map +1 -1
- package/dist/cli/internal/completions/zsh.js +7 -3
- package/dist/cli/internal/completions/zsh.js.map +1 -1
- package/dist/cli/internal/parser.js +11 -3
- package/dist/cli/internal/parser.js.map +1 -1
- package/dist/cli/internal/wizard.d.ts.map +1 -1
- package/dist/cli/internal/wizard.js +2 -1
- package/dist/cli/internal/wizard.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts +1 -0
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +67 -13
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/cluster/MessageStorage.js +20 -12
- package/dist/cluster/MessageStorage.js.map +1 -1
- package/dist/cluster/Runners.d.ts.map +1 -1
- package/dist/cluster/Runners.js +54 -34
- package/dist/cluster/Runners.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +1 -1
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/encoding/Sse.js +1 -1
- package/dist/encoding/Sse.js.map +1 -1
- package/dist/graphql/GraphQLClient.d.ts.map +1 -1
- package/dist/graphql/GraphQLClient.js +12 -5
- package/dist/graphql/GraphQLClient.js.map +1 -1
- package/dist/graphql/GraphQLProtocol.d.ts +249 -11
- package/dist/graphql/GraphQLProtocol.d.ts.map +1 -1
- package/dist/graphql/GraphQLProtocol.js +98 -8
- package/dist/graphql/GraphQLProtocol.js.map +1 -1
- package/dist/graphql/GraphQLResolver.d.ts +1 -1
- package/dist/graphql/GraphQLResolver.d.ts.map +1 -1
- package/dist/graphql/GraphQLResolver.js +46 -16
- package/dist/graphql/GraphQLResolver.js.map +1 -1
- package/dist/http/FetchHttpClient.d.ts +6 -3
- package/dist/http/FetchHttpClient.d.ts.map +1 -1
- package/dist/http/FetchHttpClient.js +6 -3
- package/dist/http/FetchHttpClient.js.map +1 -1
- package/dist/http/FindMyWay/internal/router.js +2 -1
- package/dist/http/FindMyWay/internal/router.js.map +1 -1
- package/dist/http/Headers.d.ts +3 -3
- package/dist/http/Headers.d.ts.map +1 -1
- package/dist/http/Headers.js +6 -5
- package/dist/http/Headers.js.map +1 -1
- package/dist/http/HttpClient.d.ts +12 -0
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +14 -1
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/HttpClientError.d.ts.map +1 -1
- package/dist/http/HttpClientError.js +8 -6
- package/dist/http/HttpClientError.js.map +1 -1
- package/dist/http/HttpClientRequest.d.ts +147 -4
- package/dist/http/HttpClientRequest.d.ts.map +1 -1
- package/dist/http/HttpClientRequest.js +47 -1
- package/dist/http/HttpClientRequest.js.map +1 -1
- package/dist/http/HttpMiddleware.d.ts +60 -0
- package/dist/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/http/HttpMiddleware.js +67 -5
- package/dist/http/HttpMiddleware.js.map +1 -1
- package/dist/http/HttpRouter.d.ts.map +1 -1
- package/dist/http/HttpRouter.js +52 -13
- package/dist/http/HttpRouter.js.map +1 -1
- package/dist/http/HttpServerError.d.ts.map +1 -1
- package/dist/http/HttpServerError.js +6 -4
- package/dist/http/HttpServerError.js.map +1 -1
- package/dist/http/HttpServerRequest.js +2 -2
- package/dist/http/HttpServerRequest.js.map +1 -1
- package/dist/http/HttpStaticServer.d.ts.map +1 -1
- package/dist/http/HttpStaticServer.js +4 -10
- package/dist/http/HttpStaticServer.js.map +1 -1
- package/dist/http/HttpTraceContext.js +1 -1
- package/dist/http/HttpTraceContext.js.map +1 -1
- package/dist/http/Url.d.ts.map +1 -1
- package/dist/http/Url.js +2 -1
- package/dist/http/Url.js.map +1 -1
- package/dist/http/UrlParams.d.ts +112 -8
- package/dist/http/UrlParams.d.ts.map +1 -1
- package/dist/http/UrlParams.js +141 -14
- package/dist/http/UrlParams.js.map +1 -1
- package/dist/http/internal/compression.d.ts +1 -1
- package/dist/http/internal/compression.d.ts.map +1 -1
- package/dist/http/internal/compression.js +2 -10
- package/dist/http/internal/compression.js.map +1 -1
- package/dist/http/internal/compressionBody.d.ts +2 -0
- package/dist/http/internal/compressionBody.d.ts.map +1 -0
- package/dist/http/internal/compressionBody.js +36 -0
- package/dist/http/internal/compressionBody.js.map +1 -0
- package/dist/http/internal/decompression.d.ts +2 -0
- package/dist/http/internal/decompression.d.ts.map +1 -0
- package/dist/http/internal/decompression.js +162 -0
- package/dist/http/internal/decompression.js.map +1 -0
- package/dist/http/internal/tracing.js +14 -4
- package/dist/http/internal/tracing.js.map +1 -1
- package/dist/http/internal/urlParams.d.ts +2 -0
- package/dist/http/internal/urlParams.d.ts.map +1 -0
- package/dist/http/internal/urlParams.js +4 -0
- package/dist/http/internal/urlParams.js.map +1 -0
- package/dist/http-api/HttpApiClient.d.ts.map +1 -1
- package/dist/http-api/HttpApiClient.js +2 -1
- package/dist/http-api/HttpApiClient.js.map +1 -1
- package/dist/internal/core.js +17 -1
- package/dist/internal/core.js.map +1 -1
- package/dist/internal/effect.js +5 -3
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/graphql.js +12 -2
- package/dist/internal/graphql.js.map +1 -1
- package/dist/internal/version.js +1 -1
- package/dist/observability/Otlp.d.ts +15 -0
- package/dist/observability/Otlp.d.ts.map +1 -1
- package/dist/observability/Otlp.js +3 -0
- package/dist/observability/Otlp.js.map +1 -1
- package/dist/observability/OtlpExporter.d.ts +8 -0
- package/dist/observability/OtlpExporter.d.ts.map +1 -1
- package/dist/observability/OtlpExporter.js +10 -1
- package/dist/observability/OtlpExporter.js.map +1 -1
- package/dist/observability/OtlpLogger.d.ts +17 -0
- package/dist/observability/OtlpLogger.d.ts.map +1 -1
- package/dist/observability/OtlpLogger.js +14 -1
- package/dist/observability/OtlpLogger.js.map +1 -1
- package/dist/observability/OtlpMetrics.d.ts +17 -0
- package/dist/observability/OtlpMetrics.d.ts.map +1 -1
- package/dist/observability/OtlpMetrics.js +13 -0
- package/dist/observability/OtlpMetrics.js.map +1 -1
- package/dist/observability/OtlpTracer.d.ts +17 -0
- package/dist/observability/OtlpTracer.d.ts.map +1 -1
- package/dist/observability/OtlpTracer.js +15 -2
- package/dist/observability/OtlpTracer.js.map +1 -1
- package/dist/reactivity/AsyncResult.d.ts +6 -0
- package/dist/reactivity/AsyncResult.d.ts.map +1 -1
- package/dist/reactivity/AsyncResult.js +27 -0
- package/dist/reactivity/AsyncResult.js.map +1 -1
- package/dist/reactivity/AtomRegistry.js +3 -1
- package/dist/reactivity/AtomRegistry.js.map +1 -1
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +6 -1
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/sql/SqlClient.d.ts +8 -7
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +8 -7
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/testing/TestClock.d.ts +16 -3
- package/dist/testing/TestClock.d.ts.map +1 -1
- package/dist/testing/TestClock.js +112 -22
- package/dist/testing/TestClock.js.map +1 -1
- package/dist/workflow/Activity.js +1 -0
- package/dist/workflow/Activity.js.map +1 -1
- package/dist/workflow/Workflow.d.ts +22 -0
- package/dist/workflow/Workflow.d.ts.map +1 -1
- package/dist/workflow/Workflow.js +15 -3
- package/dist/workflow/Workflow.js.map +1 -1
- package/dist/workflow/WorkflowEngine.d.ts +20 -1
- package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
- package/dist/workflow/WorkflowEngine.js +35 -21
- package/dist/workflow/WorkflowEngine.js.map +1 -1
- package/package.json +1 -1
- package/src/Array.ts +95 -6
- package/src/Channel.ts +24 -3
- package/src/ConfigProvider.ts +40 -44
- package/src/Duration.ts +4 -5
- package/src/Effect.ts +140 -53
- package/src/FileSystem.ts +23 -9
- package/src/Match.ts +65 -12
- package/src/Path.ts +52 -7
- package/src/Schema.ts +17 -4
- package/src/String.ts +17 -4
- package/src/TxRef.ts +4 -2
- package/src/ai/AiError.ts +3 -1
- package/src/ai/Decision.ts +70 -21
- package/src/ai/DecisionModel.ts +1 -1
- package/src/ai/LanguageModel.ts +57 -51
- package/src/ai/McpServer.ts +15 -55
- package/src/cli/Completions.ts +5 -0
- package/src/cli/Flag.ts +101 -0
- package/src/cli/Param.ts +96 -0
- package/src/cli/internal/command.ts +2 -1
- package/src/cli/internal/completions/bash.ts +4 -3
- package/src/cli/internal/completions/descriptor.ts +10 -1
- package/src/cli/internal/completions/fish.ts +4 -4
- package/src/cli/internal/completions/powershell.ts +5 -2
- package/src/cli/internal/completions/zsh.ts +7 -3
- package/src/cli/internal/parser.ts +12 -3
- package/src/cli/internal/wizard.ts +2 -1
- package/src/cluster/ClusterWorkflowEngine.ts +92 -24
- package/src/cluster/MessageStorage.ts +14 -3
- package/src/cluster/Runners.ts +88 -66
- package/src/cluster/internal/entityManager.ts +1 -1
- package/src/encoding/Sse.ts +1 -1
- package/src/graphql/GraphQLClient.ts +17 -5
- package/src/graphql/GraphQLProtocol.ts +274 -20
- package/src/graphql/GraphQLResolver.ts +45 -17
- package/src/http/FetchHttpClient.ts +6 -3
- package/src/http/FindMyWay/internal/router.ts +2 -1
- package/src/http/Headers.ts +6 -9
- package/src/http/HttpClient.ts +18 -1
- package/src/http/HttpClientError.ts +10 -6
- package/src/http/HttpClientRequest.ts +173 -7
- package/src/http/HttpMiddleware.ts +85 -5
- package/src/http/HttpRouter.ts +60 -13
- package/src/http/HttpServerError.ts +8 -4
- package/src/http/HttpServerRequest.ts +2 -2
- package/src/http/HttpStaticServer.ts +4 -10
- package/src/http/HttpTraceContext.ts +1 -1
- package/src/http/Url.ts +2 -1
- package/src/http/UrlParams.ts +225 -26
- package/src/http/internal/compression.ts +3 -17
- package/src/http/internal/compressionBody.ts +56 -0
- package/src/http/internal/decompression.ts +226 -0
- package/src/http/internal/tracing.ts +21 -4
- package/src/http/internal/urlParams.ts +5 -0
- package/src/http-api/HttpApiClient.ts +2 -1
- package/src/internal/core.ts +21 -1
- package/src/internal/effect.ts +5 -4
- package/src/internal/graphql.ts +30 -7
- package/src/internal/version.ts +1 -1
- package/src/observability/Otlp.ts +18 -0
- package/src/observability/OtlpExporter.ts +14 -3
- package/src/observability/OtlpLogger.ts +31 -2
- package/src/observability/OtlpMetrics.ts +30 -1
- package/src/observability/OtlpTracer.ts +32 -3
- package/src/reactivity/AsyncResult.ts +31 -0
- package/src/reactivity/AtomRegistry.ts +3 -1
- package/src/rpc/RpcClient.ts +6 -1
- package/src/sql/SqlClient.ts +9 -7
- package/src/testing/TestClock.ts +144 -29
- package/src/workflow/Activity.ts +1 -0
- package/src/workflow/Workflow.ts +31 -5
- package/src/workflow/WorkflowEngine.ts +60 -22
package/src/ai/LanguageModel.ts
CHANGED
|
@@ -893,6 +893,13 @@ export const make: (params: {
|
|
|
893
893
|
Effect.map(Option.getOrElse(() => defaultIdGenerator))
|
|
894
894
|
)
|
|
895
895
|
|
|
896
|
+
const contentDecoderFor = makeResponseDecoder((toolkit, deferred) =>
|
|
897
|
+
Schema.decodeEffect(Schema.mutable(Schema.Array(withUndeclaredToolCalls(Response.Part(toolkit), deferred))))
|
|
898
|
+
)
|
|
899
|
+
const streamDecoderFor = makeResponseDecoder((toolkit, deferred) =>
|
|
900
|
+
Schema.decodeEffect(Schema.NonEmptyArray(withUndeclaredToolCalls(Response.StreamPart(toolkit), deferred)))
|
|
901
|
+
)
|
|
902
|
+
|
|
896
903
|
const generateText = <
|
|
897
904
|
Options extends NoExcessProperties<GenerateTextOptions<any>, Options>,
|
|
898
905
|
Tools extends Record<string, Tool.Any> = {}
|
|
@@ -1132,10 +1139,8 @@ export const make: (params: {
|
|
|
1132
1139
|
}
|
|
1133
1140
|
|
|
1134
1141
|
// Check for pending approvals that need resolution
|
|
1135
|
-
const { approved, denied } =
|
|
1136
|
-
providerOptions.prompt.content
|
|
1137
|
-
{ excludeResolved: true }
|
|
1138
|
-
)
|
|
1142
|
+
const { approved: allResolved, denied: allDenied, pendingApproved: approved, pendingDenied: denied } =
|
|
1143
|
+
collectToolApprovals(providerOptions.prompt.content)
|
|
1139
1144
|
const hasPendingApprovals = approved.length > 0 || denied.length > 0
|
|
1140
1145
|
|
|
1141
1146
|
// If there is no toolkit, the generated content can be returned immediately
|
|
@@ -1245,17 +1250,12 @@ export const make: (params: {
|
|
|
1245
1250
|
|
|
1246
1251
|
// Strip all resolved approval artifacts (both current and from previous
|
|
1247
1252
|
// rounds) in a single pass before sending to the provider.
|
|
1248
|
-
{
|
|
1249
|
-
|
|
1250
|
-
providerOptions.prompt
|
|
1253
|
+
if (allResolved.length > 0 || allDenied.length > 0) {
|
|
1254
|
+
providerOptions.prompt = stripResolvedApprovals(
|
|
1255
|
+
providerOptions.prompt,
|
|
1256
|
+
allResolved,
|
|
1257
|
+
allDenied
|
|
1251
1258
|
)
|
|
1252
|
-
if (allResolved.length > 0 || allDenied.length > 0) {
|
|
1253
|
-
providerOptions.prompt = stripResolvedApprovals(
|
|
1254
|
-
providerOptions.prompt,
|
|
1255
|
-
allResolved,
|
|
1256
|
-
allDenied
|
|
1257
|
-
)
|
|
1258
|
-
}
|
|
1259
1259
|
}
|
|
1260
1260
|
|
|
1261
1261
|
const tools = typeof toolChoice === "object" && "oneOf" in toolChoice
|
|
@@ -1272,20 +1272,17 @@ export const make: (params: {
|
|
|
1272
1272
|
}
|
|
1273
1273
|
}
|
|
1274
1274
|
|
|
1275
|
-
const
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
? makeToolkitWithEncodedParameters(toolkit)
|
|
1279
|
-
: makeToolkitWithOpaqueParameters(toolkit)
|
|
1280
|
-
),
|
|
1275
|
+
const decodeContent = contentDecoderFor(
|
|
1276
|
+
toolkit,
|
|
1277
|
+
options.disableToolCallResolution === true && !deferToolCallValidation,
|
|
1281
1278
|
deferToolCallValidation
|
|
1282
|
-
)
|
|
1279
|
+
)
|
|
1283
1280
|
|
|
1284
1281
|
// If tool call resolution is disabled, return the response without
|
|
1285
1282
|
// resolving the tool calls that were generated
|
|
1286
1283
|
if (options.disableToolCallResolution === true) {
|
|
1287
1284
|
const rawContent = yield* generateWithNonIncrementalFallback()
|
|
1288
|
-
const content = yield*
|
|
1285
|
+
const content = yield* decodeContent(rawContent)
|
|
1289
1286
|
if (deferToolCallValidation) {
|
|
1290
1287
|
yield* validateProviderExecutedToolCalls(makeToolkitWithEncodedParameters(toolkit), rawContent)
|
|
1291
1288
|
}
|
|
@@ -1301,7 +1298,7 @@ export const make: (params: {
|
|
|
1301
1298
|
const rawContent = yield* generateWithNonIncrementalFallback()
|
|
1302
1299
|
|
|
1303
1300
|
// Validate before running tool handlers.
|
|
1304
|
-
const content = yield*
|
|
1301
|
+
const content = yield* decodeContent(rawContent)
|
|
1305
1302
|
yield* validateProviderExecutedToolCalls(toolkit, rawContent)
|
|
1306
1303
|
|
|
1307
1304
|
// Resolve the generated tool calls. When the finish reason indicates an
|
|
@@ -1407,9 +1404,9 @@ export const make: (params: {
|
|
|
1407
1404
|
}
|
|
1408
1405
|
|
|
1409
1406
|
// Check for pending approvals that need resolution
|
|
1410
|
-
const { approved:
|
|
1411
|
-
|
|
1412
|
-
|
|
1407
|
+
const { approved: allResolved, denied: allDenied, pendingApproved, pendingDenied } = collectToolApprovals(
|
|
1408
|
+
providerOptions.prompt.content
|
|
1409
|
+
)
|
|
1413
1410
|
const hasPendingApprovals = pendingApproved.length > 0 || pendingDenied.length > 0
|
|
1414
1411
|
|
|
1415
1412
|
// If there is no toolkit, return immediately
|
|
@@ -1564,9 +1561,6 @@ export const make: (params: {
|
|
|
1564
1561
|
|
|
1565
1562
|
// Strip all resolved approval artifacts (both current and from previous
|
|
1566
1563
|
// rounds) in a single pass before sending to the provider.
|
|
1567
|
-
const { approved: allResolved, denied: allDenied } = collectToolApprovals(
|
|
1568
|
-
providerOptions.prompt.content
|
|
1569
|
-
)
|
|
1570
1564
|
if (allResolved.length > 0 || allDenied.length > 0) {
|
|
1571
1565
|
providerOptions.prompt = stripResolvedApprovals(
|
|
1572
1566
|
providerOptions.prompt,
|
|
@@ -1589,15 +1583,11 @@ export const make: (params: {
|
|
|
1589
1583
|
}
|
|
1590
1584
|
}
|
|
1591
1585
|
|
|
1592
|
-
const
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
? makeToolkitWithEncodedParameters(toolkit)
|
|
1596
|
-
: makeToolkitWithOpaqueParameters(toolkit)
|
|
1597
|
-
),
|
|
1586
|
+
const decodeParts = streamDecoderFor(
|
|
1587
|
+
toolkit,
|
|
1588
|
+
options.disableToolCallResolution === true && !deferToolCallValidation,
|
|
1598
1589
|
deferToolCallValidation
|
|
1599
|
-
)
|
|
1600
|
-
const decodeParts = Schema.decodeEffect(ResponseSchema)
|
|
1590
|
+
)
|
|
1601
1591
|
|
|
1602
1592
|
// If tool call resolution is disabled, return the response without
|
|
1603
1593
|
// resolving the tool calls that were generated
|
|
@@ -1638,8 +1628,7 @@ export const make: (params: {
|
|
|
1638
1628
|
const deferredFinishParts: Array<Response.StreamPart<Tools>> = []
|
|
1639
1629
|
|
|
1640
1630
|
// Emit pre-resolved tool results so Chat.streamText persists them to
|
|
1641
|
-
// history
|
|
1642
|
-
// find the corresponding tool-results on future rounds.
|
|
1631
|
+
// history, where collectToolApprovals finds them on future rounds.
|
|
1643
1632
|
if (preResolvedStreamParts.length > 0) {
|
|
1644
1633
|
yield* Queue.offerAll(queue, preResolvedStreamParts)
|
|
1645
1634
|
}
|
|
@@ -2072,16 +2061,13 @@ interface ApprovalResult {
|
|
|
2072
2061
|
readonly toolCall?: Prompt.ToolCallPart | undefined
|
|
2073
2062
|
}
|
|
2074
2063
|
|
|
2075
|
-
interface CollectToolApprovalsOptions {
|
|
2076
|
-
readonly excludeResolved?: boolean
|
|
2077
|
-
}
|
|
2078
|
-
|
|
2079
2064
|
const collectToolApprovals = (
|
|
2080
|
-
messages: ReadonlyArray<Prompt.Message
|
|
2081
|
-
options?: CollectToolApprovalsOptions
|
|
2065
|
+
messages: ReadonlyArray<Prompt.Message>
|
|
2082
2066
|
): {
|
|
2083
2067
|
readonly approved: Array<ApprovalResult>
|
|
2084
2068
|
readonly denied: Array<ApprovalResult>
|
|
2069
|
+
readonly pendingApproved: Array<ApprovalResult>
|
|
2070
|
+
readonly pendingDenied: Array<ApprovalResult>
|
|
2085
2071
|
} => {
|
|
2086
2072
|
const requests = new Map<
|
|
2087
2073
|
string,
|
|
@@ -2124,15 +2110,12 @@ const collectToolApprovals = (
|
|
|
2124
2110
|
|
|
2125
2111
|
const approved: Array<ApprovalResult> = []
|
|
2126
2112
|
const denied: Array<ApprovalResult> = []
|
|
2113
|
+
const pendingApproved: Array<ApprovalResult> = []
|
|
2114
|
+
const pendingDenied: Array<ApprovalResult> = []
|
|
2127
2115
|
|
|
2128
2116
|
for (const response of responses) {
|
|
2129
2117
|
const request = requests.get(response.approvalId)
|
|
2130
2118
|
if (Predicate.isNotUndefined(request)) {
|
|
2131
|
-
// Skip if already resolved
|
|
2132
|
-
if (options?.excludeResolved && toolResultIds.has(request.toolCallId)) {
|
|
2133
|
-
continue
|
|
2134
|
-
}
|
|
2135
|
-
|
|
2136
2119
|
const result: ApprovalResult = {
|
|
2137
2120
|
...response,
|
|
2138
2121
|
toolCallId: request.toolCallId,
|
|
@@ -2141,13 +2124,15 @@ const collectToolApprovals = (
|
|
|
2141
2124
|
|
|
2142
2125
|
if (response.approved) {
|
|
2143
2126
|
approved.push(result)
|
|
2127
|
+
if (!toolResultIds.has(request.toolCallId)) pendingApproved.push(result)
|
|
2144
2128
|
} else {
|
|
2145
2129
|
denied.push(result)
|
|
2130
|
+
if (!toolResultIds.has(request.toolCallId)) pendingDenied.push(result)
|
|
2146
2131
|
}
|
|
2147
2132
|
}
|
|
2148
2133
|
}
|
|
2149
2134
|
|
|
2150
|
-
return { approved, denied }
|
|
2135
|
+
return { approved, denied, pendingApproved, pendingDenied }
|
|
2151
2136
|
}
|
|
2152
2137
|
|
|
2153
2138
|
/**
|
|
@@ -2476,6 +2461,27 @@ const resolveToolCalls = <Tools extends Record<string, Tool.Any>>(
|
|
|
2476
2461
|
// Utilities
|
|
2477
2462
|
// =============================================================================
|
|
2478
2463
|
|
|
2464
|
+
// Cache one decoder per model and response kind, keyed by validation mode
|
|
2465
|
+
// and tool names and schema identities in insertion order.
|
|
2466
|
+
const makeResponseDecoder = <Decode>(make: (toolkit: Toolkit.Any, deferred: boolean) => Decode) => {
|
|
2467
|
+
let cached: { readonly key: ReadonlyArray<unknown>; readonly decode: Decode } | undefined
|
|
2468
|
+
return (toolkit: Toolkit.WithHandler<any>, encoded: boolean, deferred: boolean): Decode => {
|
|
2469
|
+
const key: Array<unknown> = [encoded, deferred]
|
|
2470
|
+
for (const tool of Object.values(toolkit.tools as Record<string, Tool.Any>)) {
|
|
2471
|
+
key.push(tool.name, tool.parametersSchema, tool.successSchema, tool.failureSchema)
|
|
2472
|
+
}
|
|
2473
|
+
if (cached !== undefined && cached.key.length === key.length && cached.key.every((part, i) => part === key[i])) {
|
|
2474
|
+
return cached.decode
|
|
2475
|
+
}
|
|
2476
|
+
const decode = make(
|
|
2477
|
+
encoded ? makeToolkitWithEncodedParameters(toolkit) : makeToolkitWithOpaqueParameters(toolkit),
|
|
2478
|
+
deferred
|
|
2479
|
+
)
|
|
2480
|
+
cached = { key, decode }
|
|
2481
|
+
return decode
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
|
|
2479
2485
|
// Stable parameter-mode copies let Response reuse each tool's part schemas.
|
|
2480
2486
|
const parameterModeTools = new WeakMap<Tool.Any, { encoded?: Tool.Any; opaque?: Tool.Any }>()
|
|
2481
2487
|
|
package/src/ai/McpServer.ts
CHANGED
|
@@ -2277,12 +2277,6 @@ export type ResourceCompletions<Schemas extends ReadonlyArray<Schema.Constraint>
|
|
|
2277
2277
|
/**
|
|
2278
2278
|
* Registers an MCP resource or resource template from an Effect program.
|
|
2279
2279
|
*
|
|
2280
|
-
* **When to use**
|
|
2281
|
-
*
|
|
2282
|
-
* Use when you are already inside an Effect program with an `McpServer`
|
|
2283
|
-
* service and need to add a concrete resource or URI-template resource
|
|
2284
|
-
* directly.
|
|
2285
|
-
*
|
|
2286
2280
|
* @see {@link resource} for the layer-based resource registration wrapper
|
|
2287
2281
|
*
|
|
2288
2282
|
* @stability unstable
|
|
@@ -2293,12 +2287,6 @@ export const registerResource: {
|
|
|
2293
2287
|
/**
|
|
2294
2288
|
* Registers an MCP resource or resource template from an Effect program.
|
|
2295
2289
|
*
|
|
2296
|
-
* **When to use**
|
|
2297
|
-
*
|
|
2298
|
-
* Use when you are already inside an Effect program with an `McpServer`
|
|
2299
|
-
* service and need to add a concrete resource or URI-template resource
|
|
2300
|
-
* directly.
|
|
2301
|
-
*
|
|
2302
2290
|
* @see {@link resource} for the layer-based resource registration wrapper
|
|
2303
2291
|
*
|
|
2304
2292
|
* @stability unstable
|
|
@@ -2324,12 +2312,6 @@ export const registerResource: {
|
|
|
2324
2312
|
/**
|
|
2325
2313
|
* Registers an MCP resource or resource template from an Effect program.
|
|
2326
2314
|
*
|
|
2327
|
-
* **When to use**
|
|
2328
|
-
*
|
|
2329
|
-
* Use when you are already inside an Effect program with an `McpServer`
|
|
2330
|
-
* service and need to add a concrete resource or URI-template resource
|
|
2331
|
-
* directly.
|
|
2332
|
-
*
|
|
2333
2315
|
* @see {@link resource} for the layer-based resource registration wrapper
|
|
2334
2316
|
*
|
|
2335
2317
|
* @stability unstable
|
|
@@ -2360,9 +2342,7 @@ export const registerResource: {
|
|
|
2360
2342
|
| Schemas[number]["DecodingServices"]
|
|
2361
2343
|
| Schemas[number]["EncodingServices"]
|
|
2362
2344
|
| R
|
|
2363
|
-
|
|
|
2364
|
-
Ret extends Effect.Effect<infer _A, infer _E, infer _R> ? _R : never
|
|
2365
|
-
: never),
|
|
2345
|
+
| CompletionServices<Completions>,
|
|
2366
2346
|
McpRequestContext
|
|
2367
2347
|
>
|
|
2368
2348
|
| McpServer
|
|
@@ -2491,10 +2471,6 @@ export const registerResource: {
|
|
|
2491
2471
|
/**
|
|
2492
2472
|
* Creates a layer that registers an MCP resource or resource template.
|
|
2493
2473
|
*
|
|
2494
|
-
* **When to use**
|
|
2495
|
-
*
|
|
2496
|
-
* Use to compose resource registration into an MCP server layer.
|
|
2497
|
-
*
|
|
2498
2474
|
* @see {@link registerResource} for the Effect-level resource registration API
|
|
2499
2475
|
*
|
|
2500
2476
|
* @stability unstable
|
|
@@ -2505,10 +2481,6 @@ export const resource: {
|
|
|
2505
2481
|
/**
|
|
2506
2482
|
* Creates a layer that registers an MCP resource or resource template.
|
|
2507
2483
|
*
|
|
2508
|
-
* **When to use**
|
|
2509
|
-
*
|
|
2510
|
-
* Use to compose resource registration into an MCP server layer.
|
|
2511
|
-
*
|
|
2512
2484
|
* @see {@link registerResource} for the Effect-level resource registration API
|
|
2513
2485
|
*
|
|
2514
2486
|
* @stability unstable
|
|
@@ -2533,10 +2505,6 @@ export const resource: {
|
|
|
2533
2505
|
/**
|
|
2534
2506
|
* Creates a layer that registers an MCP resource or resource template.
|
|
2535
2507
|
*
|
|
2536
|
-
* **When to use**
|
|
2537
|
-
*
|
|
2538
|
-
* Use to compose resource registration into an MCP server layer.
|
|
2539
|
-
*
|
|
2540
2508
|
* @see {@link registerResource} for the Effect-level resource registration API
|
|
2541
2509
|
*
|
|
2542
2510
|
* @stability unstable
|
|
@@ -2563,10 +2531,10 @@ export const resource: {
|
|
|
2563
2531
|
never,
|
|
2564
2532
|
never,
|
|
2565
2533
|
Exclude<
|
|
2534
|
+
| Schemas[number]["DecodingServices"]
|
|
2535
|
+
| Schemas[number]["EncodingServices"]
|
|
2566
2536
|
| R
|
|
2567
|
-
|
|
|
2568
|
-
Ret extends Effect.Effect<infer _A, infer _E, infer _R> ? _R : never
|
|
2569
|
-
: never),
|
|
2537
|
+
| CompletionServices<Completions>,
|
|
2570
2538
|
McpRequestContext
|
|
2571
2539
|
>
|
|
2572
2540
|
>
|
|
@@ -2586,16 +2554,10 @@ export const resource: {
|
|
|
2586
2554
|
/**
|
|
2587
2555
|
* Registers an MCP prompt from an Effect program.
|
|
2588
2556
|
*
|
|
2589
|
-
* **When to use**
|
|
2590
|
-
*
|
|
2591
|
-
* Use when you are already inside an Effect program with an `McpServer`
|
|
2592
|
-
* service and need to add a prompt handler directly.
|
|
2593
|
-
*
|
|
2594
2557
|
* **Details**
|
|
2595
2558
|
*
|
|
2596
|
-
*
|
|
2597
|
-
*
|
|
2598
|
-
* text message.
|
|
2559
|
+
* Decodes parameters and encodes completion suggestions using their schemas.
|
|
2560
|
+
* String content becomes a user text message.
|
|
2599
2561
|
*
|
|
2600
2562
|
* @see {@link prompt} for the layer-based prompt registration wrapper
|
|
2601
2563
|
*
|
|
@@ -2630,6 +2592,7 @@ export const registerPrompt = <
|
|
|
2630
2592
|
never,
|
|
2631
2593
|
| Exclude<
|
|
2632
2594
|
| Schema.Struct.DecodingServices<Params>
|
|
2595
|
+
| Params[Extract<keyof Completions, keyof Params>]["EncodingServices"]
|
|
2633
2596
|
| R
|
|
2634
2597
|
| CompletionServices<Completions>,
|
|
2635
2598
|
McpRequestContext
|
|
@@ -2665,7 +2628,13 @@ export const registerPrompt = <
|
|
|
2665
2628
|
const registry = yield* McpServer
|
|
2666
2629
|
const services = omitRequestServices(
|
|
2667
2630
|
yield* Effect.context<
|
|
2668
|
-
Exclude<
|
|
2631
|
+
Exclude<
|
|
2632
|
+
| R
|
|
2633
|
+
| Schema.Struct.DecodingServices<Params>
|
|
2634
|
+
| Params[Extract<keyof Completions, keyof Params>]["EncodingServices"]
|
|
2635
|
+
| CompletionServices<Completions>,
|
|
2636
|
+
McpRequestContext
|
|
2637
|
+
>
|
|
2669
2638
|
>()
|
|
2670
2639
|
)
|
|
2671
2640
|
const completions: Record<
|
|
@@ -2731,16 +2700,6 @@ export const registerPrompt = <
|
|
|
2731
2700
|
/**
|
|
2732
2701
|
* Creates a layer that registers an MCP prompt.
|
|
2733
2702
|
*
|
|
2734
|
-
* **When to use**
|
|
2735
|
-
*
|
|
2736
|
-
* Use to compose prompt registration into an MCP server layer.
|
|
2737
|
-
*
|
|
2738
|
-
* **Details**
|
|
2739
|
-
*
|
|
2740
|
-
* Parameters are decoded with the supplied schema, completion handlers encode
|
|
2741
|
-
* per-parameter suggestions, and string prompt content is converted into a user
|
|
2742
|
-
* text message.
|
|
2743
|
-
*
|
|
2744
2703
|
* @see {@link registerPrompt} for the Effect-level prompt registration API
|
|
2745
2704
|
*
|
|
2746
2705
|
* @stability unstable
|
|
@@ -2774,6 +2733,7 @@ export const prompt = <
|
|
|
2774
2733
|
never,
|
|
2775
2734
|
Exclude<
|
|
2776
2735
|
| Schema.Struct.DecodingServices<Params>
|
|
2736
|
+
| Params[Extract<keyof Completions, keyof Params>]["EncodingServices"]
|
|
2777
2737
|
| R
|
|
2778
2738
|
| CompletionServices<Completions>,
|
|
2779
2739
|
McpRequestContext
|
package/src/cli/Completions.ts
CHANGED
|
@@ -48,6 +48,11 @@ export interface FlagDescriptor {
|
|
|
48
48
|
readonly aliases: ReadonlyArray<string>
|
|
49
49
|
readonly description: string | undefined
|
|
50
50
|
readonly type: FlagType
|
|
51
|
+
/**
|
|
52
|
+
* Whether the flag's value is optional. Its value can only be attached with
|
|
53
|
+
* `=` (`--name=value`), never given as the next word.
|
|
54
|
+
*/
|
|
55
|
+
readonly optionalValue?: boolean | undefined
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
/**
|
package/src/cli/Flag.ts
CHANGED
|
@@ -611,6 +611,107 @@ export const withDescription: {
|
|
|
611
611
|
<A>(self: Flag<A>, description: string): Flag<A>
|
|
612
612
|
} = dual(2, <A>(self: Flag<A>, description: string) => Param.withDescription(self, description))
|
|
613
613
|
|
|
614
|
+
/**
|
|
615
|
+
* Lets a flag be given without a value, in which case `value` is used.
|
|
616
|
+
*
|
|
617
|
+
* **Details**
|
|
618
|
+
*
|
|
619
|
+
* Follows GNU-style optional values, like `--color[=WHEN]`. An explicit value
|
|
620
|
+
* must be attached with `=` (`--watch=until-done` or `-w=until-done`). A bare
|
|
621
|
+
* `--watch` is parsed as `--watch=<value>`, so `value` is validated like any
|
|
622
|
+
* other input. The flag never consumes the next token, so in `--watch build`,
|
|
623
|
+
* `build` stays a positional argument or subcommand. The flag is still
|
|
624
|
+
* required unless it is made optional or given a default.
|
|
625
|
+
*
|
|
626
|
+
* **Example** (Flag with an optional value)
|
|
627
|
+
*
|
|
628
|
+
* ```ts import.meta.vitest
|
|
629
|
+
* import { Flag } from "effect/cli"
|
|
630
|
+
*
|
|
631
|
+
* const watch = Flag.Literals("watch", ["first-failure", "until-done"]).pipe(
|
|
632
|
+
* Flag.withOptionalValue("first-failure"),
|
|
633
|
+
* Flag.optional
|
|
634
|
+
* )
|
|
635
|
+
* // --watch => Option.some("first-failure")
|
|
636
|
+
* // --watch=until-done => Option.some("until-done")
|
|
637
|
+
* // (absent) => Option.none()
|
|
638
|
+
* // In help: --watch [=choice]
|
|
639
|
+
* watch.kind // => "flag"
|
|
640
|
+
* ```
|
|
641
|
+
*
|
|
642
|
+
* @stability unstable
|
|
643
|
+
* @category combinators
|
|
644
|
+
* @since 4.1.0
|
|
645
|
+
*/
|
|
646
|
+
export const withOptionalValue: {
|
|
647
|
+
/**
|
|
648
|
+
* Lets a flag be given without a value, in which case `value` is used.
|
|
649
|
+
*
|
|
650
|
+
* **Details**
|
|
651
|
+
*
|
|
652
|
+
* Follows GNU-style optional values, like `--color[=WHEN]`. An explicit value
|
|
653
|
+
* must be attached with `=` (`--watch=until-done` or `-w=until-done`). A bare
|
|
654
|
+
* `--watch` is parsed as `--watch=<value>`, so `value` is validated like any
|
|
655
|
+
* other input. The flag never consumes the next token, so in `--watch build`,
|
|
656
|
+
* `build` stays a positional argument or subcommand. The flag is still
|
|
657
|
+
* required unless it is made optional or given a default.
|
|
658
|
+
*
|
|
659
|
+
* **Example** (Flag with an optional value)
|
|
660
|
+
*
|
|
661
|
+
* ```ts import.meta.vitest
|
|
662
|
+
* import { Flag } from "effect/cli"
|
|
663
|
+
*
|
|
664
|
+
* const watch = Flag.Literals("watch", ["first-failure", "until-done"]).pipe(
|
|
665
|
+
* Flag.withOptionalValue("first-failure"),
|
|
666
|
+
* Flag.optional
|
|
667
|
+
* )
|
|
668
|
+
* // --watch => Option.some("first-failure")
|
|
669
|
+
* // --watch=until-done => Option.some("until-done")
|
|
670
|
+
* // (absent) => Option.none()
|
|
671
|
+
* // In help: --watch [=choice]
|
|
672
|
+
* watch.kind // => "flag"
|
|
673
|
+
* ```
|
|
674
|
+
*
|
|
675
|
+
* @stability unstable
|
|
676
|
+
* @category combinators
|
|
677
|
+
* @since 4.1.0
|
|
678
|
+
*/
|
|
679
|
+
(value: string): <A>(self: Flag<A>) => Flag<A>
|
|
680
|
+
/**
|
|
681
|
+
* Lets a flag be given without a value, in which case `value` is used.
|
|
682
|
+
*
|
|
683
|
+
* **Details**
|
|
684
|
+
*
|
|
685
|
+
* Follows GNU-style optional values, like `--color[=WHEN]`. An explicit value
|
|
686
|
+
* must be attached with `=` (`--watch=until-done` or `-w=until-done`). A bare
|
|
687
|
+
* `--watch` is parsed as `--watch=<value>`, so `value` is validated like any
|
|
688
|
+
* other input. The flag never consumes the next token, so in `--watch build`,
|
|
689
|
+
* `build` stays a positional argument or subcommand. The flag is still
|
|
690
|
+
* required unless it is made optional or given a default.
|
|
691
|
+
*
|
|
692
|
+
* **Example** (Flag with an optional value)
|
|
693
|
+
*
|
|
694
|
+
* ```ts import.meta.vitest
|
|
695
|
+
* import { Flag } from "effect/cli"
|
|
696
|
+
*
|
|
697
|
+
* const watch = Flag.Literals("watch", ["first-failure", "until-done"]).pipe(
|
|
698
|
+
* Flag.withOptionalValue("first-failure"),
|
|
699
|
+
* Flag.optional
|
|
700
|
+
* )
|
|
701
|
+
* // --watch => Option.some("first-failure")
|
|
702
|
+
* // --watch=until-done => Option.some("until-done")
|
|
703
|
+
* // (absent) => Option.none()
|
|
704
|
+
* // In help: --watch [=choice]
|
|
705
|
+
* watch.kind // => "flag"
|
|
706
|
+
* ```
|
|
707
|
+
*
|
|
708
|
+
* @stability unstable
|
|
709
|
+
* @category combinators
|
|
710
|
+
* @since 4.1.0
|
|
711
|
+
*/
|
|
712
|
+
<A>(self: Flag<A>, value: string): Flag<A>
|
|
713
|
+
} = dual(2, <A>(self: Flag<A>, value: string) => Param.withOptionalValue(self, value))
|
|
714
|
+
|
|
614
715
|
// -------------------------------------------------------------------------------------
|
|
615
716
|
// metadata
|
|
616
717
|
// -------------------------------------------------------------------------------------
|
package/src/cli/Param.ts
CHANGED
|
@@ -213,6 +213,10 @@ export interface Single<Kind extends ParamKind, out A> extends Param<Kind, A> {
|
|
|
213
213
|
readonly primitiveType: Primitive.Primitive<A>
|
|
214
214
|
readonly typeName?: string | undefined
|
|
215
215
|
readonly hidden: boolean
|
|
216
|
+
/**
|
|
217
|
+
* Raw value used for a bare flag. See `withOptionalValue`.
|
|
218
|
+
*/
|
|
219
|
+
readonly optionalValue?: string | undefined
|
|
216
220
|
}
|
|
217
221
|
|
|
218
222
|
/**
|
|
@@ -362,6 +366,7 @@ export const makeSingle = <const Kind extends ParamKind, A>(params: {
|
|
|
362
366
|
readonly description?: Option.Option<string> | undefined
|
|
363
367
|
readonly aliases?: ReadonlyArray<string> | undefined
|
|
364
368
|
readonly hidden?: boolean | undefined
|
|
369
|
+
readonly optionalValue?: string | undefined
|
|
365
370
|
}): Single<Kind, A> => {
|
|
366
371
|
const parse: Parse<A> = (args) =>
|
|
367
372
|
params.kind === argumentKind
|
|
@@ -2664,6 +2669,97 @@ export const withMetavar: {
|
|
|
2664
2669
|
typeName: metavar
|
|
2665
2670
|
})))
|
|
2666
2671
|
|
|
2672
|
+
/**
|
|
2673
|
+
* Lets a flag be given without a value, in which case `value` is used.
|
|
2674
|
+
*
|
|
2675
|
+
* **Details**
|
|
2676
|
+
*
|
|
2677
|
+
* Follows GNU-style optional values. An explicit value must be attached with
|
|
2678
|
+
* `=` (`--watch=until-done`), and a bare `--watch` is parsed as
|
|
2679
|
+
* `--watch=<value>`. The flag never consumes the next token. It is still
|
|
2680
|
+
* required unless it is made optional or given a default.
|
|
2681
|
+
*
|
|
2682
|
+
* **Example** (Flag with an optional value)
|
|
2683
|
+
*
|
|
2684
|
+
* ```ts import.meta.vitest
|
|
2685
|
+
* import { Param } from "effect/cli"
|
|
2686
|
+
*
|
|
2687
|
+
* const watch = Param.String(Param.flagKind, "watch").pipe(
|
|
2688
|
+
* Param.withOptionalValue("first-failure"),
|
|
2689
|
+
* Param.optional
|
|
2690
|
+
* )
|
|
2691
|
+
* watch.kind // => "flag"
|
|
2692
|
+
* ```
|
|
2693
|
+
*
|
|
2694
|
+
* @stability unstable
|
|
2695
|
+
* @category combinators
|
|
2696
|
+
* @since 4.1.0
|
|
2697
|
+
*/
|
|
2698
|
+
export const withOptionalValue: {
|
|
2699
|
+
/**
|
|
2700
|
+
* Lets a flag be given without a value, in which case `value` is used.
|
|
2701
|
+
*
|
|
2702
|
+
* **Details**
|
|
2703
|
+
*
|
|
2704
|
+
* Follows GNU-style optional values. An explicit value must be attached with
|
|
2705
|
+
* `=` (`--watch=until-done`), and a bare `--watch` is parsed as
|
|
2706
|
+
* `--watch=<value>`. The flag never consumes the next token. It is still
|
|
2707
|
+
* required unless it is made optional or given a default.
|
|
2708
|
+
*
|
|
2709
|
+
* **Example** (Flag with an optional value)
|
|
2710
|
+
*
|
|
2711
|
+
* ```ts import.meta.vitest
|
|
2712
|
+
* import { Param } from "effect/cli"
|
|
2713
|
+
*
|
|
2714
|
+
* const watch = Param.String(Param.flagKind, "watch").pipe(
|
|
2715
|
+
* Param.withOptionalValue("first-failure"),
|
|
2716
|
+
* Param.optional
|
|
2717
|
+
* )
|
|
2718
|
+
* watch.kind // => "flag"
|
|
2719
|
+
* ```
|
|
2720
|
+
*
|
|
2721
|
+
* @stability unstable
|
|
2722
|
+
* @category combinators
|
|
2723
|
+
* @since 4.1.0
|
|
2724
|
+
*/
|
|
2725
|
+
(value: string): <A>(self: Param<typeof flagKind, A>) => Param<typeof flagKind, A>
|
|
2726
|
+
/**
|
|
2727
|
+
* Lets a flag be given without a value, in which case `value` is used.
|
|
2728
|
+
*
|
|
2729
|
+
* **Details**
|
|
2730
|
+
*
|
|
2731
|
+
* Follows GNU-style optional values. An explicit value must be attached with
|
|
2732
|
+
* `=` (`--watch=until-done`), and a bare `--watch` is parsed as
|
|
2733
|
+
* `--watch=<value>`. The flag never consumes the next token. It is still
|
|
2734
|
+
* required unless it is made optional or given a default.
|
|
2735
|
+
*
|
|
2736
|
+
* **Example** (Flag with an optional value)
|
|
2737
|
+
*
|
|
2738
|
+
* ```ts import.meta.vitest
|
|
2739
|
+
* import { Param } from "effect/cli"
|
|
2740
|
+
*
|
|
2741
|
+
* const watch = Param.String(Param.flagKind, "watch").pipe(
|
|
2742
|
+
* Param.withOptionalValue("first-failure"),
|
|
2743
|
+
* Param.optional
|
|
2744
|
+
* )
|
|
2745
|
+
* watch.kind // => "flag"
|
|
2746
|
+
* ```
|
|
2747
|
+
*
|
|
2748
|
+
* @stability unstable
|
|
2749
|
+
* @category combinators
|
|
2750
|
+
* @since 4.1.0
|
|
2751
|
+
*/
|
|
2752
|
+
<A>(self: Param<typeof flagKind, A>, value: string): Param<typeof flagKind, A>
|
|
2753
|
+
} = dual(2, <A>(
|
|
2754
|
+
self: Param<typeof flagKind, A>,
|
|
2755
|
+
value: string
|
|
2756
|
+
) =>
|
|
2757
|
+
transformSingle(self, (single) =>
|
|
2758
|
+
makeSingle({
|
|
2759
|
+
...single,
|
|
2760
|
+
optionalValue: value
|
|
2761
|
+
})))
|
|
2762
|
+
|
|
2667
2763
|
/**
|
|
2668
2764
|
* Validates parsed values against a Schema, providing detailed error messages.
|
|
2669
2765
|
*
|
|
@@ -242,10 +242,11 @@ export const toFlagDoc = (
|
|
|
242
242
|
metadata: ReturnType<typeof Param.getParamMetadata>
|
|
243
243
|
): FlagDoc => {
|
|
244
244
|
const formattedAliases = single.aliases.map((alias) => alias.length === 1 ? `-${alias}` : `--${alias}`)
|
|
245
|
+
const type = single.typeName ?? Primitive.getTypeName(single.primitiveType)
|
|
245
246
|
return {
|
|
246
247
|
name: single.name,
|
|
247
248
|
aliases: formattedAliases,
|
|
248
|
-
type: single.
|
|
249
|
+
type: single.optionalValue === undefined ? type : `[=${type}]`,
|
|
249
250
|
description: appendChoiceKeys(single.description, Primitive.getChoiceKeys(single.primitiveType)),
|
|
250
251
|
required: single.primitiveType._tag !== "Boolean" && !metadata.isOptional
|
|
251
252
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* @internal
|
|
8
8
|
*/
|
|
9
9
|
import type * as Completions from "../../Completions.ts"
|
|
10
|
+
import { takesSeparateValue } from "./descriptor.ts"
|
|
10
11
|
|
|
11
12
|
// ---------------------------------------------------------------------------
|
|
12
13
|
// Helpers
|
|
@@ -164,7 +165,7 @@ const generateFunction = (
|
|
|
164
165
|
lines.push(``)
|
|
165
166
|
|
|
166
167
|
// Build flag-value dispatch
|
|
167
|
-
const flagsWithValues = descriptor.flags.filter(
|
|
168
|
+
const flagsWithValues = descriptor.flags.filter(takesSeparateValue)
|
|
168
169
|
if (flagsWithValues.length > 0) {
|
|
169
170
|
lines.push(` # Flag value completions`)
|
|
170
171
|
lines.push(` case "$prev" in`)
|
|
@@ -196,7 +197,7 @@ const generateFunction = (
|
|
|
196
197
|
lines.push(` fi`)
|
|
197
198
|
lines.push(` case "\${words[i]}" in`)
|
|
198
199
|
for (const flag of descriptor.flags) {
|
|
199
|
-
if (flag
|
|
200
|
+
if (!takesSeparateValue(flag)) continue
|
|
200
201
|
const forms = flagNamesForWordlist(flag)
|
|
201
202
|
lines.push(` ${forms.join("|")}) _skip_next=1 ;;`)
|
|
202
203
|
lines.push(` ${forms.map((form) => `${form}=*`).join("|")}) ;;`)
|
|
@@ -248,7 +249,7 @@ const generateFunction = (
|
|
|
248
249
|
lines.push(` --) _end_of_options=1 ;;`)
|
|
249
250
|
for (const flag of descriptor.flags) {
|
|
250
251
|
const forms = flagNamesForWordlist(flag)
|
|
251
|
-
if (flag
|
|
252
|
+
if (!takesSeparateValue(flag)) {
|
|
252
253
|
lines.push(` ${forms.join("|")}) ;;`)
|
|
253
254
|
} else {
|
|
254
255
|
lines.push(` ${forms.join("|")}) _skip_next=1 ;;`)
|
|
@@ -95,7 +95,8 @@ export const fromCommand = (
|
|
|
95
95
|
name: single.name,
|
|
96
96
|
aliases: single.aliases,
|
|
97
97
|
description: Option.getOrUndefined(single.description),
|
|
98
|
-
type: toFlagType(single as Param.Single<"flag", unknown>)
|
|
98
|
+
type: toFlagType(single as Param.Single<"flag", unknown>),
|
|
99
|
+
optionalValue: single.optionalValue !== undefined
|
|
99
100
|
})
|
|
100
101
|
}
|
|
101
102
|
}
|
|
@@ -139,3 +140,11 @@ export const fromCommand = (
|
|
|
139
140
|
subcommands
|
|
140
141
|
}
|
|
141
142
|
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Whether the flag reads its value from the next word.
|
|
146
|
+
*
|
|
147
|
+
* @internal
|
|
148
|
+
*/
|
|
149
|
+
export const takesSeparateValue = (flag: Completions.FlagDescriptor): boolean =>
|
|
150
|
+
flag.type._tag !== "Boolean" && flag.optionalValue !== true
|