返回 DeepSeek-Reasonix
serve_multisession.go
根目录 / internal / cli / serve_multisession.go
1 package cli
2
3 import (
4 "context"
5 "flag"
6 "os"
7
8 "reasonix/internal/boot"
9 "reasonix/internal/config"
10 "reasonix/internal/control"
11 "reasonix/internal/remote/bootstrap"
12 "reasonix/internal/serve"
13 )
14
15 func registerServeCapabilityFlags(fs *flag.FlagSet) {
16 _ = fs.Bool("session-events", false, "tag session events and finish switched-away turns in background ("+bootstrap.ServeCapsToken+")")
17 _ = fs.Bool("detached-heal", false, "retire background sessions after provider credential-channel repair")
18 // browser-broker is the capability marker a desktop bootstrap greps for;
19 // the broker itself is configured through the environment only.
20 _ = fs.Bool("browser-broker", false, "use the desktop browser broker from "+bootstrap.BrowserBrokerEnv+"/"+bootstrap.BrowserTokenEnv+" when set ("+bootstrap.ServeBrowserBrokerMarker+")")
21 }
22
23 func newServeBootstrap() (*serve.Broadcaster, *serve.SessionTagSink, *config.Config) {
24 bc := serve.NewBroadcaster()
25 cfg, _ := config.Load()
26 return bc, serve.NewSessionTagSink(bc), cfg
27 }
28
29 func setupCLIMultiSessionProfile(ctx context.Context, model string, maxSteps int, preset string, tag *serve.SessionTagSink, leases *control.SessionLeaseKeeper) (*control.Controller, boot.Options, error) {
30 migrateMCPConfigForCLIWorkspace()
31 broker, err := serveBrowserBrokerFromEnv(os.Getenv)
32 if err != nil {
33 return nil, boot.Options{}, err
34 }
35 opts := cliProfileBuildOptions(model, maxSteps, false, tag, cliBuildOverrides{
36 Preset: preset, OnSessionRecovered: cliSessionRecoveredHandler(leases),
37 })
38 // A chat fork is a user-visible child conversation. Keep it in its own
39 // transcript so remote project listings can show both the source and child,
40 // matching the desktop and DeepSeek Harness behavior.
41 opts.FileBranchesOnly = true
42 if broker != nil {
43 // The initial controller's tools go through the session-scoped view;
44 // the raw broker is what SetControllerBuildOptions keeps so later
45 // controllers get their own session scope.
46 opts.BrowserExecutor = broker.ForSession(tag)
47 }
48 ctrl, err := boot.Build(ctx, opts)
49 if broker != nil {
50 opts.BrowserExecutor = broker
51 }
52 return ctrl, opts, err
53 }
54
55 func newCLIMultiSessionServer(ctrl *control.Controller, bc *serve.Broadcaster, tag *serve.SessionTagSink, cfg config.ServeConfig, leases *control.SessionLeaseKeeper, buildOpts boot.Options) *serve.Server {
56 // Exclusive identities have no legacy path; without the session id the
57 // boot tag stamps live frames path-less and identity-routed subscribers
58 // cannot attribute them after the first rebind.
59 if ref, bound := ctrl.SessionRef(); bound {
60 tag.SetIdentity("", ref.SessionID)
61 } else {
62 tag.SetPath(ctrl.SessionPath())
63 }
64 srv := serve.New(ctrl, bc, cfg)
65 srv.SetControllerBuildOptions(buildOpts)
66 srv.RegisterSessionTag(ctrl, tag)
67 _ = srv.SetSessionLeases(leases)
68 return srv
69 }
70
70 lines GO