CallToolParams.Arguments is any.
Clients can send whatever they want.
Tool authors who create their own ToolHandler (bypassing NewTool)
will receive the arguments as a map[string]any which has been
validated against the input schema.
Tool authors who call NewTool can choose the type that the arguments
unmarshal into.
There is no double-unmarshaling and no downcasting.
There is no way for tool authors to avoid the unmarshal, and no way to
avoid the validation unless the omit an input schema, which is probably
bad for LLMs. If tool authors want this optimization, we can provide
it later.
Change-Id: Ieb201e56c7fb8a23bb1a93b27e946630ec9e79ad
Reviewed-on: https://go-review.googlesource.com/c/tools/+/679595
TryBot-Bypass: Jonathan Amsterdam <jba@google.com>
Auto-Submit: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Add Client.ResourceTemplates
Test forthcoming.
Change-Id: I35e8ee8fabdf8fa216456ab3fcd0c8a7de9287c8
Reviewed-on: https://go-review.googlesource.com/c/tools/+/680255
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Provide support for resource templates on the client and server.
Adding, removing and listing resource templates looks just like those
operations on resources.
Although the spec provides no guidance on the unique ID for resource
templates, we follow most existing SDKs, as well as the parallel with
resources, and index on the URI template rather than the name.
As the spec recommends, the server verifies an incoming URI in a
ReadResource request against its list of resources and resource
templates, to make sure the URI came from one of them. The main
technical challenge here is the need to check that a URI template could
have produced a particular URI.
I wrote a very simplified version of this check. At some point
we should switch to github.com/yosida95/uritemplate/v3.
Change-Id: I1e34dd01c8f2171123c68c045ad62f5e85c05e7c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/680158
Auto-Submit: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Add Wrapf, a function that helps with error wrapping.
Change-Id: I102695f75e4d217e09f828f4723cbfcbbe83f887
Reviewed-on: https://go-review.googlesource.com/c/tools/+/679177
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This CL simplifies the paginateList function in server.go to use a
generic helper for tools, resources, and prompts.
Change-Id: Ide0d2a90d715374280067e094d8870882e6bddfa
Reviewed-on: https://go-review.googlesource.com/c/tools/+/678055
Auto-Submit: Sam Thanawalla <samthanawalla@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Do a thorough job of parsing json struct tags.
Move the code to a place where both mcp and jsonschema can use it.
Change-Id: I6c86308834706b12a1e22cd96ae120590f49d3f4
Reviewed-on: https://go-review.googlesource.com/c/tools/+/678757
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Unexport our nice root-respecting local-filesystem resource handler.
It's unclear how roots should interact with a resource handler that
uses the local filesystem. All we know from the spec is that servers
should "respect root boundaries during operations," but it's not
clear how they can do that reliably if root changes are notifications,
meaning there is no causality between a client changing a root and then
asking the server for a file. (Maybe the server sees the new roots,
maybe it doesn't.)
The spec is loose about all this: it feels more like a sketch. No other
SDK seems to devote much to providing a local helper, and those that do
(Python) don't look at roots.
Change-Id: Ia4d9abb9bc1a6450e1fc8e607df5d7bc6aa227e3
Reviewed-on: https://go-review.googlesource.com/c/tools/+/678855
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
A tool now validates its input with its InputSchema.
Change schema inference to allow explicit nulls for fields of
pointer type.
We assume the schema has no external references. For example, the
following schema cannot be handled:
{
"$ref": "https://example.com/other.json"
}
Schemas with internal references, like to a "$defs", are fine.
Change-Id: I6ee7c18c2c5cb609df0b22a66da986f7ea64bbe4
Reviewed-on: https://go-review.googlesource.com/c/tools/+/670676
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Implement sending middleware.
Sending middleware is useful for adding tracing, progress tokens,
and so on.
Change-Id: I0acab2550f0212d549c4adbcf1ebf425a9486df6
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676355
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Write a separate constraint for ClientSession | ServerSession,
and change the pointerness of the type parameter.
There is still a dynamic cast, but overall I think this is a bit
simpler:
- The exported types have the more readable constraint "Session"
instead of "ClientSession | ServerSession".
- We can put the unexported methods in Session instead of needing a
separate interface (previously "session").
- This CL enables a simplified treatment of sending middleware, in
the next CL.
Change-Id: I41184fe93ea201d1da29dbfba26ac59f93771277
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676175
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Unbreak our WASM tests by correctly marking a test as testenv.NeedsExec.
Change-Id: Ib976657e9b09acc6fc563f6fc26d6066fd64acf5
Reviewed-on: https://go-review.googlesource.com/c/tools/+/678035
Reviewed-by: Alan Donovan <adonovan@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Add a test to verify that the toWireParams helper maps all fields of
CallToolParams.
Change-Id: I81c28791734d60c793c76809c6b93d27e78c3c36
Reviewed-on: https://go-review.googlesource.com/c/tools/+/677975
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Add a section the the MCP SDK design discussing governance and community
engagement.
Change-Id: I554d8d5623201053a17a17c21dc596c4cdd0878c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/677540
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Make Tool APIs future-proof by pushing generics into CallToolParams, and
using CallToolParams throughout. This has several advantages:
- We no longer need the awkward CallToolOptions type, which is almost
but not quite like CallToolParams.
- NewTool no longer needs to define its own handler type: it accepts a
ToolHandler[TArgs]. This also means its signature is future-proof.
Additionally, provide a `CallTool` helper (the analog of NewTool) to
serve as a more strongly typed variant of `ClientSession.CallTool`.
+ design, protocol generation
Change-Id: I80172a25bc50734dae84a541aa4776ed9161694e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676495
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This CL streamlines the client side pagination logic by adding a generic
helper that handles pagination. This also simplifies the existing tools
iterator method.
Change-Id: If4304deda1ccd22d0c4580d76deaefc64e5dfeb9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676975
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Sam Thanawalla <samthanawalla@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Modify the conformance test driver to support outgoing responses.
They are returned for incoming requests in order.
Add a test that returns a file resource, which involves the server
sending a roots/list request to the client.
Change-Id: Ie7eb69a8c99ccbf11721518cfffb21244c03e532
Reviewed-on: https://go-review.googlesource.com/c/tools/+/677475
Commit-Queue: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
This uncovered a problem in how we represent resource results:
contents is a slice, not a single value.
I tried to use a file resource, but the server->client ListRoots
call didn't work because synthetic responses aren't supported.
Left a TODO.
I enhanced the hello example so I that could use the MCP Inspector to
work with resources.
The falseSchema change fixes a potential bug where schemas are
re-used, which is disallowed.
Change-Id: I1f0198043cb6221c2a03f4f83aa0bafbc71167f4
Reviewed-on: https://go-review.googlesource.com/c/tools/+/677136
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Jonathan Amsterdam <jba@google.com>
Support the conformance tests on 1.24, if the user has set
GOEXPERIMENT=synctest
The API is different, but other than that it works fine.
Change-Id: I08ffbe094b39a73cd1fc26e7dcf6f22158b2df1d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/677015
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
This CL handles only the limited case of defaults on properties.
This is just a start: I need to think more about defaults on other
schema keywords, and I need to set defaults recursively.
As part of this work, I realized that the Schema.Default field is
more usable when represented as a json.RawMessage instead of a *any.
Change-Id: Iedcedb405b52607a312dbd895fa61e7f7f94c6bc
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676938
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Auto-Submit: Jonathan Amsterdam <jba@google.com>
Schemas must form a tree. This is important for Schema.Resolve, and
also for modifying parts of the schema before resolution, as with
mcp SchemaOptions.
Remove the `seen` argument from inference, creating all schemas
afresh.
Change-Id: Ief8295e8470f3f575ef51cc2ba697901250bbe6f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676937
Auto-Submit: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Hongxiang Jiang <hxjiang@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Add the beginnings of some testdata-driven conformance tests that check
JSON-level compatibility of SDK messages, and fix some bugs in our JSON
message handling:
- "params" can be missing
- "_meta" should not be null
- lists of tools/prompts/resources should not be null
In order to implement this, we need to be able to know when the server
is done processing messages. In general, this is a hard problem; for
gopls we do this with a complicated system of progress reporting and
accounting. However, the new synctest package makes this trivial, as we
can call synctest.Wait to detect when the server is idle. Therefore,
this test requires 1.25 (it uses synctest.Test, added in 1.25, and so
can't run at 1.24 with GOEXPERIMENT=synctest).
Change-Id: I97fa28b56868340ece266a58e1eb3c3bf8cfe0e9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676538
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
Optionally validate a schema's defaults when resolving it.
We simply walk the tree of schemas, validating each locally. This can't
handle dynamic references, which require maintaing the stack from the
root. It seems unlikely that a default would require one, however.
Since there may be other options to Resolve, use an options struct
to future-proof it.
Also, fix a bug: you can't resolve a schema twice.
Change-Id: I374c582d9cc49d66d4ed56233d1070b8b3263bdf
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676395
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Redo iteration. It was too subtle.
Write a separate recursive check for whether the schemas form a tree and
have any invalid nils.
While doing that, assign paths to schemas for better error messages,
even as we check structure. This also lets us detect re-occurring
schemas without a separate map.
Everything else, including the iterators, can now assume valid structure
and populated paths.
Change-Id: I90ec93d79d1d95c92258ad7afc94ef068fdf123f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676376
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Auto-Submit: Jonathan Amsterdam <jba@google.com>
Add a wrapf function to simplify defers that wrap errors.
Change-Id: If4bedec7d3f56f609d3ca4620aebe7637a59f6bf
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676475
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Validation errors now more clearly indicate the path from the root
schema.
- Enhance schema iteration to yield the path, and generalize it by using
reflection.
- Store each schema's path inside the schema.
- Remove the path arg from validate: we don't need it anymore.
- Improve the test for the iterators and add one for validation
errors.
Change-Id: Ief55133ef4ae2eac0736208a3b9f78ed69933b31
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676375
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Jonathan Amsterdam <jba@google.com>
Meta is a struct that contains a map[string]any, and a ProgressToken
field.
Each Params and Result type has a Meta as a value field.
Meta marshals and unmarshals specially, so the ProgressToken field
becomes part of the map. The marshalling code is generalized in
anticipation of every Params and Result growing a map of additional
properties.
Change-Id: I6d2f34270d33501c96437f24f91ef3e51d20d955
Reviewed-on: https://go-review.googlesource.com/c/tools/+/674956
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Validating a struct is ambiguous, because a zero field could be
considered missing or present.
Interpret a zero optional struct field in whichever way results in
success.
Change-Id: I6a9474e6f6558d2a8522bc5ba0451967367e467d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/675956
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Change-Id: I8066b22cb87e09fb160de3b8ff2d8fdde6ec3dcf
Reviewed-on: https://go-review.googlesource.com/c/tools/+/675815
Reviewed-by: David Chase <drchase@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This CL adds paginating functionality for tools. It uses the gob encoder
for creating opaque cursors. More CLs to follow for paginating other features.
Change-Id: I1443c0213ceb6238d844a8eee9a0be52934f5cab
Reviewed-on: https://go-review.googlesource.com/c/tools/+/675055
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Pass GetPromptParams as needed, in case that type ever gets additional
properties.
Change-Id: I83fa37bb2af5633a8c2bcdc47a85c3030dfe70fb
Reviewed-on: https://go-review.googlesource.com/c/tools/+/674895
Auto-Submit: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Provide a ServerSession method that directly implements the spec
method.
Also provide a custom slog.Handler that writes a notification on each
log call. It uses a slog.JSONHandler to format the message as JSON, then
adds the additional fields of LoggingMessageParams.
I decided that the direct method should handle levels, since that is
in the spec, but that rate-limiting is an extra feature, so is only
provided in the slog handler.
Change-Id: I1190ca124e992e61fb633ac52ee3492c8e6d99c9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/674498
Auto-Submit: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Document the package.
Change-Id: I770c14d6339b75ea6827280c23171c3584dc1071
Reviewed-on: https://go-review.googlesource.com/c/tools/+/674977
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Auto-Submit: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Add additional fields to Schema which are mentioned in the spec but
do not affect validation.
Change-Id: I89488261a00c207d01cd7fc59d782f43692fe528
Reviewed-on: https://go-review.googlesource.com/c/tools/+/674976
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Jonathan Amsterdam <jba@google.com>
Use the weave program from golang.org/x/example to weave together
the README text with buildable programs. This ensures the code in the
README compiles.
Change-Id: Ib5e10c8f808cc6d1ed4addbee784607e910ba30b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/673796
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Add notification logic for intialization and list changes.
Change-Id: I1d392bb49d5995f2046c400da955a033ab2715ce
Reviewed-on: https://go-review.googlesource.com/c/tools/+/673775
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Fix some typos found during the Google import of x/tools.
Change-Id: I8ea38d3e1bd09bedbc98ed8c8146e88e84aa051f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/674975
Auto-Submit: Robert Findley <rfindley@google.com>
Reviewed-by: Hongxiang Jiang <hxjiang@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
A dynamic reference is like a dynamic variable in a programming
language, with two twists:
- There must be a dynamic anchor in lexical scope for the ref to
resolve. (Think of it as declaring the dynamic variable.)
- The ref resolves to the schema highest on the stack, not lowest.
That feels odd, but it turns out to work for the intended purpose,
which is to provide extension points for additional features.
There is some distracting code motion and refactoring in this CL:
resolveRefs was moved down in the file, and resolution of a single
ref was split off.
Change-Id: I17da6052e0782fc540d14b8a41b06a2645923872
Reviewed-on: https://go-review.googlesource.com/c/tools/+/674155
Auto-Submit: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This change is necessary to support pagination which will be implemented
in subsequent CLs.
Change-Id: I8bc616a57463ea569dc7cadf1d4f06c69602ddd5
Reviewed-on: https://go-review.googlesource.com/c/tools/+/674135
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Remove a TODO that was in package doc position.
Change-Id: Ib98dbcd7d733fdf0059bc3ced1fd6a1008b91a26
Reviewed-on: https://go-review.googlesource.com/c/tools/+/674257
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Augment the generator to create constants for all method names.
Change-Id: I858e516b1afec0aa3cf3b9852cbdfc16aec4c553
Reviewed-on: https://go-review.googlesource.com/c/tools/+/673177
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Implement middleware for clients.
Make the middleware types generic so we can factor out code
from both peers.
I was able to make the request handler generic, with one weird trick
(see handleRequest).
The first three declarations of shared.go, and a few others as well,
are copied unchanged from middleware.go.
Change-Id: Ib3239d8fcfda022ddb5b554c38cff4cdbc3704c1
Reviewed-on: https://go-review.googlesource.com/c/tools/+/673635
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Provide secure reading of files on the local filesystem.
There are subtleties in path manipulation on Windows that I don't fully
understand, so I defer that work for now.
Change-Id: Ic11f4617dde4ac0b31ccd5b0a772bb2f56db026f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/673196
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Implement the dispatcher middleware framework, allowing users to
wrap method dispatching with their own code.
The Dispatcher functions have an untyped params arg, but expect its
value to be a typed, unmarshaled XXXParams struct. That required
splitting the elegant dispatch[P, R] function into two parts, one
to do the unmarshaling and one to call the method. The nicest way
I could find to do that was to map from method names to a pair
of functions, one to unmarshal and one to call. We could also write
it as two switches on method name, which would require less machinery
but would duplicate the list of method names, already a tad fragile
because they are literal strings.
I also exported the initialize params and result, so user Dispatchers
could access them. All Params and Result types will have to be exported
for that reason.
Change-Id: Ie2c95cc17b4ef3d3d095dccdadb294e5f1590796
Reviewed-on: https://go-review.googlesource.com/c/tools/+/673515
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Due to the irregularities of github-flavored markdown, I had to join all
paragraphs before posting the public design. Additionally, I made a few
wording tweaks.
If we want to continue editing the design here, we should keep it in
sync with the public design discussion. Therefore, copy back those
changes.
Change-Id: Ie6ab3b3f59b923bb58540e86bbb1451ce0b4815d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/673199
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>