deepseek-computer-use 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/native/Program.cs CHANGED
@@ -1,163 +1,163 @@
1
-
2
- using System;
3
- using System.Collections.Generic;
4
- using System.Globalization;
5
- using System.IO;
6
- using System.Text;
7
- using System.Threading;
8
-
9
- // ---------------------------------------------------------------------------
10
- // stdio JSON-lines bridge: one request object per line in, one response object
11
- // per line out. The DSH plugin owns the process lifetime; this helper owns the
12
- // UI Automation / SendInput / capture state so element indexes stay valid.
13
- // ---------------------------------------------------------------------------
14
- public static class Program
15
- {
16
- static IPlatformDriver _driver;
17
- /// Set by the close RPC: the loop stops after flushing the response.
18
- public static bool CloseRequested;
19
- /// 130 mirrors Codex's "the user pressed Esc" exit code.
20
- public static int RequestedExitCode;
21
-
22
- public static int Main(string[] args)
23
- {
24
- try
25
- {
26
- Console.OutputEncoding = new UTF8Encoding(false);
27
- Console.InputEncoding = new UTF8Encoding(false);
28
- }
29
- catch { }
30
-
31
- _driver = CreateDriver();
32
-
33
- if (args.Length > 0 && args[0] == "--self-test")
34
- {
35
- return SelfTest();
36
- }
37
-
38
- string line;
39
- while (true)
40
- {
41
- try { line = Console.ReadLine(); }
42
- catch (Exception) { break; }
43
- if (line == null) break;
44
- if (line.Trim().Length == 0) continue;
45
- string response = Handle(line);
46
- Console.Out.Write(response);
47
- Console.Out.Write('\n');
1
+
2
+ using System;
3
+ using System.Collections.Generic;
4
+ using System.Globalization;
5
+ using System.IO;
6
+ using System.Text;
7
+ using System.Threading;
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // stdio JSON-lines bridge: one request object per line in, one response object
11
+ // per line out. The DSH plugin owns the process lifetime; this helper owns the
12
+ // UI Automation / SendInput / capture state so element indexes stay valid.
13
+ // ---------------------------------------------------------------------------
14
+ public static class Program
15
+ {
16
+ static IPlatformDriver _driver;
17
+ /// Set by the close RPC: the loop stops after flushing the response.
18
+ public static bool CloseRequested;
19
+ /// 130 mirrors Codex's "the user pressed Esc" exit code.
20
+ public static int RequestedExitCode;
21
+
22
+ public static int Main(string[] args)
23
+ {
24
+ try
25
+ {
26
+ Console.OutputEncoding = new UTF8Encoding(false);
27
+ Console.InputEncoding = new UTF8Encoding(false);
28
+ }
29
+ catch { }
30
+
31
+ _driver = CreateDriver();
32
+
33
+ if (args.Length > 0 && args[0] == "--self-test")
34
+ {
35
+ return SelfTest();
36
+ }
37
+
38
+ string line;
39
+ while (true)
40
+ {
41
+ try { line = Console.ReadLine(); }
42
+ catch (Exception) { break; }
43
+ if (line == null) break;
44
+ if (line.Trim().Length == 0) continue;
45
+ string response = Handle(line);
46
+ Console.Out.Write(response);
47
+ Console.Out.Write('\n');
48
48
  Console.Out.Flush();
49
49
  if (CloseRequested || RequestedExitCode != 0) break;
50
50
  }
51
- try { if (_driver != null) _driver.Dispose(); } catch { }
52
- return RequestedExitCode;
53
- }
54
-
55
- static IPlatformDriver CreateDriver()
56
- {
57
- string forced = Environment.GetEnvironmentVariable("DSH_CU_PLATFORM");
58
- if (!string.IsNullOrEmpty(forced) && forced != "windows")
59
- throw new NotSupportedException("platform '" + forced + "' has no driver implementation yet; only windows is available");
60
- return new WindowsDriver();
61
- }
62
-
63
- static int SelfTest()
64
- {
65
- Dictionary<string, object> ping = _driver.Ping(new Dictionary<string, object>());
66
- Dictionary<string, object> wins = _driver.ListWindows(new Dictionary<string, object>());
67
- Dictionary<string, object> report = new Dictionary<string, object>();
68
- report["ok"] = true;
69
- report["platform"] = _driver.PlatformName;
70
- report["windowCount"] = wins["count"];
71
- report["driver"] = ping;
72
- Console.Out.Write(Json.ToJson(report));
73
- Console.Out.Write('\n');
74
- Console.Out.Flush();
75
- return 0;
76
- }
77
-
78
- static string Handle(string line)
79
- {
80
- long id = 0;
81
- try
82
- {
83
- Dictionary<string, object> req = Json.AsObject(Json.Parse(line));
84
- if (req == null) throw new ToolError("bad_request", "request must be a JSON object");
85
- id = Json.GetLong(req, "id", 0);
86
- string method = Json.GetString(req, "method");
87
- Dictionary<string, object> p = Json.AsObject(Json.Get(req, "params"));
88
- if (p == null) p = new Dictionary<string, object>();
89
- // Codex ships the budget with every call (x-oai-cua-request-budget-ms) and the
90
- // helper honours it; here it bounds capture waits and marks overruns.
91
- Budget.Begin(Json.GetLong(p, "__budgetMs", 0), Json.GetString(p, "__cancelFile"));
92
- try { if (_driver != null) _driver.Maintenance(); } catch { }
93
- object result = Dispatch(method, p);
94
- return Ok(id, result);
95
- }
96
- catch (ToolError te)
97
- {
98
- try { _driver.InvalidateState(new Dictionary<string, object>()); } catch { }
99
- return Fail(id, te.Code, te.Message);
100
- }
101
- catch (Exception ex)
102
- {
103
- try { _driver.InvalidateState(new Dictionary<string, object>()); } catch { }
104
- return Fail(id, "internal_error", ex.GetType().Name + ": " + ex.Message);
105
- }
106
- }
107
-
108
- static object Dispatch(string method, Dictionary<string, object> p)
109
- {
110
- if (string.IsNullOrEmpty(method)) throw new ToolError("bad_request", "request.method is required");
111
- switch (method)
112
- {
113
- case "ping": return _driver.Ping(p);
114
- case "hello": return _driver.Hello(p);
115
- case "restore_cursor": return _driver.RestoreCursor(p);
116
- case "close": return _driver.Close(p);
117
- case "list_windows": return _driver.ListWindows(p);
118
- case "list_apps": return _driver.ListApps(p);
119
- case "get_window": return _driver.GetWindow(p);
120
- case "launch_app": return _driver.LaunchApp(p);
121
- case "get_window_state": return _driver.GetWindowState(p);
122
- case "click": return _driver.Click(p);
123
- case "press_key": return _driver.PressKey(p);
124
- case "type_text": return _driver.TypeText(p);
125
- case "scroll": return _driver.Scroll(p);
126
- case "drag": return _driver.Drag(p);
127
- case "set_value": return _driver.SetValue(p);
128
- case "perform_secondary_action": return _driver.PerformSecondaryAction(p);
129
- case "activate_window": return _driver.ActivateWindow(p);
130
- case "overlay_show": return _driver.OverlayShow(p);
131
- case "overlay_hide": return _driver.OverlayHide(p);
132
- case "configure": return _driver.Configure(p);
133
- case "approve_app": return _driver.ApproveApp(p);
134
- case "end_turn": return _driver.EndTurn(p);
135
- case "invalidate_state": return _driver.InvalidateState(p);
136
- case "start_audio_recording": return _driver.StartAudioRecording(p);
137
- case "stop_audio_recording": return _driver.StopAudioRecording(p);
138
- case "shutdown": return new Dictionary<string, object> { { "bye", true } };
139
- default: throw new ToolError("unknown_method", "unknown method '" + method + "'");
140
- }
141
- }
142
-
143
- static string Ok(long id, object result)
144
- {
145
- Dictionary<string, object> d = new Dictionary<string, object>();
146
- d["id"] = id;
147
- d["ok"] = true;
148
- d["result"] = result;
149
- return Json.ToJson(d);
150
- }
151
-
152
- static string Fail(long id, string code, string message)
153
- {
154
- Dictionary<string, object> err = new Dictionary<string, object>();
155
- err["code"] = code;
156
- err["message"] = message;
157
- Dictionary<string, object> d = new Dictionary<string, object>();
158
- d["id"] = id;
159
- d["ok"] = false;
160
- d["error"] = err;
161
- return Json.ToJson(d);
162
- }
163
- }
51
+ try { if (_driver != null) _driver.Dispose(); } catch { }
52
+ return RequestedExitCode;
53
+ }
54
+
55
+ static IPlatformDriver CreateDriver()
56
+ {
57
+ string forced = Environment.GetEnvironmentVariable("DSH_CU_PLATFORM");
58
+ if (!string.IsNullOrEmpty(forced) && forced != "windows")
59
+ throw new NotSupportedException("platform '" + forced + "' has no driver implementation yet; only windows is available");
60
+ return new WindowsDriver();
61
+ }
62
+
63
+ static int SelfTest()
64
+ {
65
+ Dictionary<string, object> ping = _driver.Ping(new Dictionary<string, object>());
66
+ Dictionary<string, object> wins = _driver.ListWindows(new Dictionary<string, object>());
67
+ Dictionary<string, object> report = new Dictionary<string, object>();
68
+ report["ok"] = true;
69
+ report["platform"] = _driver.PlatformName;
70
+ report["windowCount"] = wins["count"];
71
+ report["driver"] = ping;
72
+ Console.Out.Write(Json.ToJson(report));
73
+ Console.Out.Write('\n');
74
+ Console.Out.Flush();
75
+ return 0;
76
+ }
77
+
78
+ static string Handle(string line)
79
+ {
80
+ long id = 0;
81
+ try
82
+ {
83
+ Dictionary<string, object> req = Json.AsObject(Json.Parse(line));
84
+ if (req == null) throw new ToolError("bad_request", "request must be a JSON object");
85
+ id = Json.GetLong(req, "id", 0);
86
+ string method = Json.GetString(req, "method");
87
+ Dictionary<string, object> p = Json.AsObject(Json.Get(req, "params"));
88
+ if (p == null) p = new Dictionary<string, object>();
89
+ // Codex ships the budget with every call (x-oai-cua-request-budget-ms) and the
90
+ // helper honours it; here it bounds capture waits and marks overruns.
91
+ Budget.Begin(Json.GetLong(p, "__budgetMs", 0), Json.GetString(p, "__cancelFile"));
92
+ try { if (_driver != null) _driver.Maintenance(); } catch { }
93
+ object result = Dispatch(method, p);
94
+ return Ok(id, result);
95
+ }
96
+ catch (ToolError te)
97
+ {
98
+ try { _driver.InvalidateState(new Dictionary<string, object>()); } catch { }
99
+ return Fail(id, te.Code, te.Message);
100
+ }
101
+ catch (Exception ex)
102
+ {
103
+ try { _driver.InvalidateState(new Dictionary<string, object>()); } catch { }
104
+ return Fail(id, "internal_error", ex.GetType().Name + ": " + ex.Message);
105
+ }
106
+ }
107
+
108
+ static object Dispatch(string method, Dictionary<string, object> p)
109
+ {
110
+ if (string.IsNullOrEmpty(method)) throw new ToolError("bad_request", "request.method is required");
111
+ switch (method)
112
+ {
113
+ case "ping": return _driver.Ping(p);
114
+ case "hello": return _driver.Hello(p);
115
+ case "restore_cursor": return _driver.RestoreCursor(p);
116
+ case "close": return _driver.Close(p);
117
+ case "list_windows": return _driver.ListWindows(p);
118
+ case "list_apps": return _driver.ListApps(p);
119
+ case "get_window": return _driver.GetWindow(p);
120
+ case "launch_app": return _driver.LaunchApp(p);
121
+ case "get_window_state": return _driver.GetWindowState(p);
122
+ case "click": return _driver.Click(p);
123
+ case "press_key": return _driver.PressKey(p);
124
+ case "type_text": return _driver.TypeText(p);
125
+ case "scroll": return _driver.Scroll(p);
126
+ case "drag": return _driver.Drag(p);
127
+ case "set_value": return _driver.SetValue(p);
128
+ case "perform_secondary_action": return _driver.PerformSecondaryAction(p);
129
+ case "activate_window": return _driver.ActivateWindow(p);
130
+ case "overlay_show": return _driver.OverlayShow(p);
131
+ case "overlay_hide": return _driver.OverlayHide(p);
132
+ case "configure": return _driver.Configure(p);
133
+ case "approve_app": return _driver.ApproveApp(p);
134
+ case "end_turn": return _driver.EndTurn(p);
135
+ case "invalidate_state": return _driver.InvalidateState(p);
136
+ case "start_audio_recording": return _driver.StartAudioRecording(p);
137
+ case "stop_audio_recording": return _driver.StopAudioRecording(p);
138
+ case "shutdown": return new Dictionary<string, object> { { "bye", true } };
139
+ default: throw new ToolError("unknown_method", "unknown method '" + method + "'");
140
+ }
141
+ }
142
+
143
+ static string Ok(long id, object result)
144
+ {
145
+ Dictionary<string, object> d = new Dictionary<string, object>();
146
+ d["id"] = id;
147
+ d["ok"] = true;
148
+ d["result"] = result;
149
+ return Json.ToJson(d);
150
+ }
151
+
152
+ static string Fail(long id, string code, string message)
153
+ {
154
+ Dictionary<string, object> err = new Dictionary<string, object>();
155
+ err["code"] = code;
156
+ err["message"] = message;
157
+ Dictionary<string, object> d = new Dictionary<string, object>();
158
+ d["id"] = id;
159
+ d["ok"] = false;
160
+ d["error"] = err;
161
+ return Json.ToJson(d);
162
+ }
163
+ }
@@ -1,95 +1,95 @@
1
- using System;
2
- using System.IO;
3
- using System.Threading;
4
- using NAudio.Wave;
5
- using NAudio.Wave.SampleProviders;
6
-
7
- namespace DshCuAudio
8
- {
9
- /// WASAPI loopback recorder: captures whatever the machine is playing, which is
10
- /// what Codex's start/stop_audio_recording expose (gated behind SKY_ENABLE_AUDIO).
11
- /// Stops on max duration, on the helper's stop file, or on Ctrl+C.
12
- internal static class Program
13
- {
14
- private static int Main(string[] args)
15
- {
16
- string output = Path.Combine(Path.GetTempPath(), "dsh-cu-audio.wav");
17
- int maxMs = 60000;
18
- string stopFile = null;
19
- for (int i = 0; i < args.Length - 1; i++)
20
- {
21
- if (args[i] == "--out") output = args[i + 1];
22
- else if (args[i] == "--max-ms") int.TryParse(args[i + 1], out maxMs);
23
- else if (args[i] == "--stop-file") stopFile = args[i + 1];
24
- }
25
- if (maxMs < 500) maxMs = 500;
26
-
27
- try
28
- {
29
- // Record at the device mix format first, then normalise to the 24 kHz
30
- // stereo 16-bit WAV that Codex returns.
31
- string devicePath = output + ".device.wav";
32
- try { if (File.Exists(devicePath)) File.Delete(devicePath); } catch { }
33
- using (var capture = new WasapiLoopbackCapture())
34
- using (var writer = new WaveFileWriter(devicePath, capture.WaveFormat))
35
- {
36
- var stopped = new ManualResetEventSlim(false);
37
- Exception failure = null;
38
- capture.DataAvailable += (sender, e) =>
39
- {
40
- try
41
- {
42
- if (e.BytesRecorded > 0) writer.Write(e.Buffer, 0, e.BytesRecorded);
43
- }
44
- catch (Exception ex) { failure = ex; stopped.Set(); }
45
- };
46
- capture.RecordingStopped += (sender, e) => { stopped.Set(); };
47
-
48
- capture.StartRecording();
49
- Console.WriteLine("recording started: " + capture.WaveFormat.SampleRate + "Hz " +
50
- capture.WaveFormat.Channels + "ch -> " + output);
51
-
52
- var deadline = DateTime.UtcNow.AddMilliseconds(maxMs);
53
- while (DateTime.UtcNow < deadline && !stopped.IsSet)
54
- {
55
- if (stopFile != null && File.Exists(stopFile)) break;
56
- Thread.Sleep(150);
57
- }
58
-
59
- capture.StopRecording();
60
- stopped.Wait(3000);
61
- writer.Flush();
62
-
63
- if (failure != null) { Console.Error.WriteLine(failure.GetType().Name + ": " + failure.Message); return 6; }
64
-
65
- writer.Dispose();
66
- Normalize(devicePath, output);
67
- try { File.Delete(devicePath); } catch { }
68
- long bytes = new FileInfo(output).Length;
69
- Console.WriteLine("recorded 24kHz stereo, " + bytes + " bytes -> " + output);
70
- return 0;
71
- }
72
- }
73
- catch (Exception ex)
74
- {
75
- Console.Error.WriteLine(ex.GetType().Name + ": " + ex.Message);
76
- return 5;
77
- }
78
- }
79
-
80
- /// Resample/convert the device-format capture into 24 kHz stereo 16-bit PCM.
81
- static void Normalize(string source, string destination)
82
- {
83
- using (var reader = new WaveFileReader(source))
84
- {
85
- ISampleProvider samples = reader.ToSampleProvider();
86
- if (samples.WaveFormat.Channels == 1)
87
- samples = new MonoToStereoSampleProvider(samples);
88
- ISampleProvider resampled = samples.WaveFormat.SampleRate == 24000
89
- ? samples
90
- : new WdlResamplingSampleProvider(samples, 24000);
91
- WaveFileWriter.CreateWaveFile16(destination, resampled);
92
- }
93
- }
94
- }
95
- }
1
+ using System;
2
+ using System.IO;
3
+ using System.Threading;
4
+ using NAudio.Wave;
5
+ using NAudio.Wave.SampleProviders;
6
+
7
+ namespace DshCuAudio
8
+ {
9
+ /// WASAPI loopback recorder: captures whatever the machine is playing, which is
10
+ /// what Codex's start/stop_audio_recording expose (gated behind SKY_ENABLE_AUDIO).
11
+ /// Stops on max duration, on the helper's stop file, or on Ctrl+C.
12
+ internal static class Program
13
+ {
14
+ private static int Main(string[] args)
15
+ {
16
+ string output = Path.Combine(Path.GetTempPath(), "dsh-cu-audio.wav");
17
+ int maxMs = 60000;
18
+ string stopFile = null;
19
+ for (int i = 0; i < args.Length - 1; i++)
20
+ {
21
+ if (args[i] == "--out") output = args[i + 1];
22
+ else if (args[i] == "--max-ms") int.TryParse(args[i + 1], out maxMs);
23
+ else if (args[i] == "--stop-file") stopFile = args[i + 1];
24
+ }
25
+ if (maxMs < 500) maxMs = 500;
26
+
27
+ try
28
+ {
29
+ // Record at the device mix format first, then normalise to the 24 kHz
30
+ // stereo 16-bit WAV that Codex returns.
31
+ string devicePath = output + ".device.wav";
32
+ try { if (File.Exists(devicePath)) File.Delete(devicePath); } catch { }
33
+ using (var capture = new WasapiLoopbackCapture())
34
+ using (var writer = new WaveFileWriter(devicePath, capture.WaveFormat))
35
+ {
36
+ var stopped = new ManualResetEventSlim(false);
37
+ Exception failure = null;
38
+ capture.DataAvailable += (sender, e) =>
39
+ {
40
+ try
41
+ {
42
+ if (e.BytesRecorded > 0) writer.Write(e.Buffer, 0, e.BytesRecorded);
43
+ }
44
+ catch (Exception ex) { failure = ex; stopped.Set(); }
45
+ };
46
+ capture.RecordingStopped += (sender, e) => { stopped.Set(); };
47
+
48
+ capture.StartRecording();
49
+ Console.WriteLine("recording started: " + capture.WaveFormat.SampleRate + "Hz " +
50
+ capture.WaveFormat.Channels + "ch -> " + output);
51
+
52
+ var deadline = DateTime.UtcNow.AddMilliseconds(maxMs);
53
+ while (DateTime.UtcNow < deadline && !stopped.IsSet)
54
+ {
55
+ if (stopFile != null && File.Exists(stopFile)) break;
56
+ Thread.Sleep(150);
57
+ }
58
+
59
+ capture.StopRecording();
60
+ stopped.Wait(3000);
61
+ writer.Flush();
62
+
63
+ if (failure != null) { Console.Error.WriteLine(failure.GetType().Name + ": " + failure.Message); return 6; }
64
+
65
+ writer.Dispose();
66
+ Normalize(devicePath, output);
67
+ try { File.Delete(devicePath); } catch { }
68
+ long bytes = new FileInfo(output).Length;
69
+ Console.WriteLine("recorded 24kHz stereo, " + bytes + " bytes -> " + output);
70
+ return 0;
71
+ }
72
+ }
73
+ catch (Exception ex)
74
+ {
75
+ Console.Error.WriteLine(ex.GetType().Name + ": " + ex.Message);
76
+ return 5;
77
+ }
78
+ }
79
+
80
+ /// Resample/convert the device-format capture into 24 kHz stereo 16-bit PCM.
81
+ static void Normalize(string source, string destination)
82
+ {
83
+ using (var reader = new WaveFileReader(source))
84
+ {
85
+ ISampleProvider samples = reader.ToSampleProvider();
86
+ if (samples.WaveFormat.Channels == 1)
87
+ samples = new MonoToStereoSampleProvider(samples);
88
+ ISampleProvider resampled = samples.WaveFormat.SampleRate == 24000
89
+ ? samples
90
+ : new WdlResamplingSampleProvider(samples, 24000);
91
+ WaveFileWriter.CreateWaveFile16(destination, resampled);
92
+ }
93
+ }
94
+ }
95
+ }