@markusylisiurunen/tau 0.3.80 → 0.3.81
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/dist/code_mode/command.js +4 -16
- package/dist/code_mode/command.js.map +1 -1
- package/dist/code_mode/images.js +5 -6
- package/dist/code_mode/images.js.map +1 -1
- package/dist/code_mode/index.d.ts +1 -3
- package/dist/code_mode/index.js +1 -2
- package/dist/code_mode/index.js.map +1 -1
- package/dist/code_mode/runtime.d.ts +8 -4
- package/dist/code_mode/runtime.js +52 -63
- package/dist/code_mode/runtime.js.map +1 -1
- package/dist/core/code_mode/bash.js +269 -0
- package/dist/core/code_mode/bash.js.map +1 -0
- package/dist/core/code_mode/capability.js +2 -0
- package/dist/core/code_mode/capability.js.map +1 -0
- package/dist/core/code_mode/history.js +62 -0
- package/dist/core/code_mode/history.js.map +1 -0
- package/dist/core/code_mode/mcp.js +121 -0
- package/dist/core/code_mode/mcp.js.map +1 -0
- package/dist/core/code_mode/models.js +256 -0
- package/dist/core/code_mode/models.js.map +1 -0
- package/dist/core/{tools → code_mode}/nook.js +13 -77
- package/dist/core/code_mode/nook.js.map +1 -0
- package/dist/core/code_mode/sdk.js +97 -0
- package/dist/core/code_mode/sdk.js.map +1 -0
- package/dist/core/{tools → code_mode}/web.js +31 -90
- package/dist/core/code_mode/web.js.map +1 -0
- package/dist/core/config/content_loader.js +3 -1
- package/dist/core/config/content_loader.js.map +1 -1
- package/dist/core/debug.js +1 -1
- package/dist/core/debug.js.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/models/openrouter.js +171 -0
- package/dist/core/models/openrouter.js.map +1 -0
- package/dist/core/{tool → models}/openrouter_decisions.js +6 -7
- package/dist/core/models/openrouter_decisions.js.map +1 -0
- package/dist/core/models/openrouter_media.js +128 -0
- package/dist/core/models/openrouter_media.js.map +1 -0
- package/dist/core/personas.js +2 -1
- package/dist/core/personas.js.map +1 -1
- package/dist/core/session/compaction.js +5 -3
- package/dist/core/session/compaction.js.map +1 -1
- package/dist/core/static/code_mode/history/documentation.md +95 -167
- package/dist/core/static/code_mode/mcp/documentation.md +144 -67
- package/dist/core/static/code_mode/nook/documentation.md +108 -169
- package/dist/core/static/code_mode/sandbox_runner.mjs +37 -20
- package/dist/core/static/code_mode/web/documentation.md +115 -213
- package/dist/core/static/tau_docs/client-tools.md +3 -3
- package/dist/core/static/tau_docs/history.md +2 -2
- package/dist/core/static/tau_docs/node-sdk.md +5 -3
- package/dist/core/static/tau_docs/nook.md +2 -2
- package/dist/core/static/tau_docs/personas.md +2 -2
- package/dist/core/static/tau_docs/security.md +3 -3
- package/dist/core/static/tau_docs/sessions.md +2 -0
- package/dist/core/static/tau_docs/subagents.md +2 -1
- package/dist/core/static/tau_docs/tools.md +36 -33
- package/dist/core/static/tau_docs/tui.md +5 -3
- package/dist/core/subagents/registry.js +2 -1
- package/dist/core/subagents/registry.js.map +1 -1
- package/dist/core/subagents/types.js +2 -1
- package/dist/core/subagents/types.js.map +1 -1
- package/dist/core/tool/image_generate.js +2 -1
- package/dist/core/tool/image_generate.js.map +1 -1
- package/dist/core/tool/media.js +1 -49
- package/dist/core/tool/media.js.map +1 -1
- package/dist/core/tool/openrouter.js +24 -156
- package/dist/core/tool/openrouter.js.map +1 -1
- package/dist/core/tool/openrouter_input.js +77 -0
- package/dist/core/tool/openrouter_input.js.map +1 -0
- package/dist/core/tool/speech_generate.js +2 -1
- package/dist/core/tool/speech_generate.js.map +1 -1
- package/dist/core/tools/bash.js +2 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/bash_jobs.js +34 -5
- package/dist/core/tools/bash_jobs.js.map +1 -1
- package/dist/core/tools/catalog.js +18 -33
- package/dist/core/tools/catalog.js.map +1 -1
- package/dist/core/tools/code.js +100 -0
- package/dist/core/tools/code.js.map +1 -0
- package/dist/core/tools/code_mode.js +9 -30
- package/dist/core/tools/code_mode.js.map +1 -1
- package/dist/core/tools/code_mode_worker.js +2 -2
- package/dist/core/tools/presentation.js +2 -1
- package/dist/core/tools/presentation.js.map +1 -1
- package/dist/core/tools/tool_names.js +5 -1
- package/dist/core/tools/tool_names.js.map +1 -1
- package/dist/core/utils/gemini_transcription.js +14 -15
- package/dist/core/utils/gemini_transcription.js.map +1 -1
- package/dist/core/utils/media_validation.js +50 -0
- package/dist/core/utils/media_validation.js.map +1 -0
- package/dist/core/version.js +1 -1
- package/dist/nook/README.md +1 -1
- package/dist/sdk/code_mode.js +11 -17
- package/dist/sdk/code_mode.js.map +1 -1
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +1 -1
- package/dist/sdk/index.js.map +1 -1
- package/dist/tui/session_chat_controller.js +95 -55
- package/dist/tui/session_chat_controller.js.map +1 -1
- package/package.json +4 -4
- package/dist/code_mode/files.d.ts +0 -47
- package/dist/code_mode/files.js +0 -296
- package/dist/code_mode/files.js.map +0 -1
- package/dist/core/tool/openrouter_decisions.js.map +0 -1
- package/dist/core/tool/openrouter_media.js +0 -180
- package/dist/core/tool/openrouter_media.js.map +0 -1
- package/dist/core/tools/history.js +0 -118
- package/dist/core/tools/history.js.map +0 -1
- package/dist/core/tools/mcp.js +0 -167
- package/dist/core/tools/mcp.js.map +0 -1
- package/dist/core/tools/nook.js.map +0 -1
- package/dist/core/tools/web.js.map +0 -1
package/dist/sdk/code_mode.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CODE_MODE_MAX_OUTPUT_TOKENS_DESCRIPTION, executeTauCodeMode, parseCodeModeArguments, TAU_CODE_MODE_MAX_OUTPUT_TOKENS, validateTauCodeModeDefinition, } from "../code_mode/runtime.js";
|
|
2
2
|
import { truncateTauClientToolText } from "./client_tool_presentation.js";
|
|
3
3
|
export function createTauCodeModeClientTool(options) {
|
|
4
4
|
const definition = {
|
|
@@ -19,9 +19,15 @@ export function createTauCodeModeClientTool(options) {
|
|
|
19
19
|
parameters: {
|
|
20
20
|
type: "object",
|
|
21
21
|
properties: {
|
|
22
|
+
maxOutputTokens: {
|
|
23
|
+
type: "integer",
|
|
24
|
+
minimum: 1,
|
|
25
|
+
maximum: TAU_CODE_MODE_MAX_OUTPUT_TOKENS,
|
|
26
|
+
description: CODE_MODE_MAX_OUTPUT_TOKENS_DESCRIPTION,
|
|
27
|
+
},
|
|
22
28
|
code: {
|
|
23
29
|
type: "string",
|
|
24
|
-
description: "JavaScript source to execute. Use
|
|
30
|
+
description: "JavaScript source to execute. Use printText(text) for text and await printImage(block) to return images.",
|
|
25
31
|
},
|
|
26
32
|
},
|
|
27
33
|
required: ["code"],
|
|
@@ -29,12 +35,13 @@ export function createTauCodeModeClientTool(options) {
|
|
|
29
35
|
},
|
|
30
36
|
...(options.timeoutMs === undefined ? {} : { executionTimeoutMs: options.timeoutMs }),
|
|
31
37
|
},
|
|
32
|
-
describe: (args) => createCodeModePresentation(
|
|
38
|
+
describe: (args) => createCodeModePresentation(parseCodeModeArguments(args).code),
|
|
33
39
|
execute: async (args, context) => {
|
|
34
|
-
const code =
|
|
40
|
+
const { code, maxOutputTokens } = parseCodeModeArguments(args);
|
|
35
41
|
const result = await executeTauCodeMode({
|
|
36
42
|
...definition,
|
|
37
43
|
code,
|
|
44
|
+
maxOutputTokens,
|
|
38
45
|
signal: context.signal,
|
|
39
46
|
invocation: {
|
|
40
47
|
sessionId: context.sessionId,
|
|
@@ -42,7 +49,6 @@ export function createTauCodeModeClientTool(options) {
|
|
|
42
49
|
callId: context.callId,
|
|
43
50
|
},
|
|
44
51
|
executionEnvironment: context.executionEnvironment,
|
|
45
|
-
files: createTauCodeModeExecutionEnvironmentFiles(context.agentId, context.executionEnvironment),
|
|
46
52
|
});
|
|
47
53
|
return { ...result, presentation: createCodeModePresentation(code) };
|
|
48
54
|
},
|
|
@@ -54,16 +60,4 @@ function createCodeModePresentation(code) {
|
|
|
54
60
|
subjectWrap: "character",
|
|
55
61
|
};
|
|
56
62
|
}
|
|
57
|
-
function parseCodeArguments(value) {
|
|
58
|
-
if (typeof value !== "object" || value === null) {
|
|
59
|
-
throw new Error("code-mode client tool arguments must be an object");
|
|
60
|
-
}
|
|
61
|
-
const args = value;
|
|
62
|
-
if (typeof args.code !== "string" ||
|
|
63
|
-
!args.code.trim() ||
|
|
64
|
-
Object.keys(args).some((key) => key !== "code")) {
|
|
65
|
-
throw new Error("code-mode client tool arguments must contain exactly one non-empty 'code' string");
|
|
66
|
-
}
|
|
67
|
-
return args.code;
|
|
68
|
-
}
|
|
69
63
|
//# sourceMappingURL=code_mode.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code_mode.js","sourceRoot":"","sources":["../../src/sdk/code_mode.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"code_mode.js","sourceRoot":"","sources":["../../src/sdk/code_mode.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uCAAuC,EACvC,kBAAkB,EAClB,sBAAsB,EACtB,+BAA+B,EAE/B,6BAA6B,GAC9B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAO1E,MAAM,UAAU,2BAA2B,CACzC,OAAwC;IAExC,MAAM,UAAU,GAA0B;QACxC,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;QAC5E,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;KACzF,CAAC;IACF,6BAA6B,CAAC,UAAU,CAAC,CAAC;IAC1C,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,OAAO;QACL,MAAM,EAAE;YACN,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,eAAe,EAAE;wBACf,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,CAAC;wBACV,OAAO,EAAE,+BAA+B;wBACxC,WAAW,EAAE,uCAAuC;qBACrD;oBACD,IAAI,EAAE;wBACJ,IAAI,EAAE,QAAQ;wBACd,WAAW,EACT,0GAA0G;qBAC7G;iBACF;gBACD,QAAQ,EAAE,CAAC,MAAM,CAAC;gBAClB,oBAAoB,EAAE,KAAK;aAC5B;YACD,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;SACtF;QACD,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,0BAA0B,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;QACjF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;YAC/B,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;gBACtC,GAAG,UAAU;gBACb,IAAI;gBACJ,eAAe;gBACf,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,UAAU,EAAE;oBACV,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,MAAM,EAAE,OAAO,CAAC,MAAM;iBACvB;gBACD,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;aACnD,CAAC,CAAC;YACH,OAAO,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC;QACvE,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CAAC,IAAY;IAC9C,OAAO;QACL,OAAO,EAAE,yBAAyB,CAAC,IAAI,CAAC;QACxC,WAAW,EAAE,WAAoB;KAClC,CAAC;AACJ,CAAC"}
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { BuildTauCodeModeToolDescriptionOptions, ExecuteTauCodeModeOptions, TauCodeModeApi, TauCodeModeDefinition, TauCodeModeExecutionStatus, TauCodeModeHandler, TauCodeModeHandlerContext, TauCodeModeInvocation, TauCodeModeJsonValue, TauCodeModePersistOutput, TauCodeModeResult, } from "../code_mode/runtime.js";
|
|
2
|
-
export { buildTauCodeModeToolDescription, executeTauCodeMode, TAU_CODE_MODE_DEFAULT_TIMEOUT_MS, TAU_CODE_MODE_MAX_OUTPUT_TOKENS, } from "../code_mode/runtime.js";
|
|
2
|
+
export { buildTauCodeModeToolDescription, executeTauCodeMode, TAU_CODE_MODE_DEFAULT_MAX_OUTPUT_TOKENS, TAU_CODE_MODE_DEFAULT_TIMEOUT_MS, TAU_CODE_MODE_MAX_OUTPUT_TOKENS, } from "../code_mode/runtime.js";
|
|
3
3
|
export type { SessionProtocolDelta, SessionProtocolFeedbackEvent, SessionProtocolFeedbackTone, SessionProtocolPendingUserMessage, SessionProtocolPendingUserMessagesMessage, SessionProtocolPendingUserMessagesState, SessionProtocolSnapshot, SessionProtocolSubagentActivitiesAgentState, SessionProtocolSubagentActivitiesChange, SessionProtocolSubagentActivitiesMessage, SessionProtocolSubagentActivitiesState, SessionProtocolSubagentActivity, SessionProtocolTurnRecord, } from "../protocol/index.js";
|
|
4
4
|
export { applySessionProtocolDelta, applySessionProtocolSubagentActivitiesMessage, } from "../protocol/index.js";
|
|
5
5
|
export type { SessionProtocolDeltaListener, SessionProtocolEphemeralListener, SessionProtocolFailureListener, SessionProtocolPendingUserMessagesListener, SessionProtocolSubagentActivitiesListener, SessionProtocolTransport, TauSessionProtocolError, TauSessionProtocolErrorCode, WebSocketSessionProtocolTransportOptions, } from "../transport/index.js";
|
package/dist/sdk/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { buildTauCodeModeToolDescription, executeTauCodeMode, TAU_CODE_MODE_DEFAULT_TIMEOUT_MS, TAU_CODE_MODE_MAX_OUTPUT_TOKENS, } from "../code_mode/runtime.js";
|
|
1
|
+
export { buildTauCodeModeToolDescription, executeTauCodeMode, TAU_CODE_MODE_DEFAULT_MAX_OUTPUT_TOKENS, TAU_CODE_MODE_DEFAULT_TIMEOUT_MS, TAU_CODE_MODE_MAX_OUTPUT_TOKENS, } from "../code_mode/runtime.js";
|
|
2
2
|
export { applySessionProtocolDelta, applySessionProtocolSubagentActivitiesMessage, } from "../protocol/index.js";
|
|
3
3
|
export { TauSessionClientError, TauSessionProtocolResponseError, TauTransportError, WebSocketSessionProtocolTransport, } from "../transport/index.js";
|
|
4
4
|
export { createTauSdkClient, createTauSdkWebSocketClient } from "./client.js";
|
package/dist/sdk/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sdk/index.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,+BAA+B,EAC/B,kBAAkB,EAClB,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AAgBjC,OAAO,EACL,yBAAyB,EACzB,6CAA6C,GAC9C,MAAM,sBAAsB,CAAC;AAY9B,OAAO,EACL,qBAAqB,EACrB,+BAA+B,EAC/B,iBAAiB,EACjB,iCAAiC,GAClC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EACL,uBAAuB,EACvB,wCAAwC,GAIzC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,2BAA2B,GAE5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAGL,qBAAqB,GAKtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC;AAgE/D,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEhG,MAAM,UAAU,0BAA0B,CACxC,QAAgE,EAChE,kBAA0B;IAE1B,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;QACtD,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC;QACpC,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,QAAgE,EAChE,kBAA0B;IAE1B,MAAM,MAAM,GAAG,0BAA0B,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;IACxE,OAAO,MAAM,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAClE,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sdk/index.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,+BAA+B,EAC/B,kBAAkB,EAClB,uCAAuC,EACvC,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AAgBjC,OAAO,EACL,yBAAyB,EACzB,6CAA6C,GAC9C,MAAM,sBAAsB,CAAC;AAY9B,OAAO,EACL,qBAAqB,EACrB,+BAA+B,EAC/B,iBAAiB,EACjB,iCAAiC,GAClC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EACL,uBAAuB,EACvB,wCAAwC,GAIzC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,2BAA2B,GAE5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAGL,qBAAqB,GAKtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC;AAgE/D,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEhG,MAAM,UAAU,0BAA0B,CACxC,QAAgE,EAChE,kBAA0B;IAE1B,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;QACtD,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC;QACpC,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,QAAgE,EAChE,kBAA0B;IAE1B,MAAM,MAAM,GAAG,0BAA0B,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;IACxE,OAAO,MAAM,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAClE,CAAC"}
|
|
@@ -586,13 +586,18 @@ export class SessionChatController {
|
|
|
586
586
|
this.view.showFooterNotice("interrupted", "default");
|
|
587
587
|
return;
|
|
588
588
|
}
|
|
589
|
-
if (this.listenStartupAbortController
|
|
590
|
-
this.
|
|
591
|
-
this.
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
589
|
+
if (this.listenStartupAbortController ||
|
|
590
|
+
this.listenRecording ||
|
|
591
|
+
this.listenTransition ||
|
|
592
|
+
this.listenPreview) {
|
|
593
|
+
this.listenStartupAbortController?.abort(LISTEN_CAPTURE_START_CANCELLED);
|
|
594
|
+
this.activeListenTranscription?.abort();
|
|
595
|
+
this.endListenPreview();
|
|
596
|
+
this.listenActivityLabel = undefined;
|
|
597
|
+
if (this.listenRecording) {
|
|
598
|
+
void this.runListenTransition(() => this.cancelListenCapture());
|
|
599
|
+
}
|
|
600
|
+
this.refreshStatus();
|
|
596
601
|
return;
|
|
597
602
|
}
|
|
598
603
|
if (this.speakTask) {
|
|
@@ -668,14 +673,24 @@ export class SessionChatController {
|
|
|
668
673
|
return;
|
|
669
674
|
}
|
|
670
675
|
this.pendingAutoSpeak = undefined;
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
676
|
+
const abortController = new AbortController();
|
|
677
|
+
this.listenStartupAbortController = abortController;
|
|
678
|
+
try {
|
|
679
|
+
await this.runListenTransition(async () => {
|
|
680
|
+
if (this.speakTask) {
|
|
681
|
+
this.speakTask.abortController.abort();
|
|
682
|
+
await this.speakTask.completion.catch(() => { });
|
|
683
|
+
}
|
|
684
|
+
if (!this.disposed && !abortController.signal.aborted) {
|
|
685
|
+
await this.startListenCapture(abortController);
|
|
686
|
+
}
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
finally {
|
|
690
|
+
if (this.listenStartupAbortController === abortController) {
|
|
691
|
+
this.listenStartupAbortController = undefined;
|
|
675
692
|
}
|
|
676
|
-
|
|
677
|
-
await this.startListenCapture();
|
|
678
|
-
});
|
|
693
|
+
}
|
|
679
694
|
}
|
|
680
695
|
async runListenTransition(task) {
|
|
681
696
|
if (this.listenTransition) {
|
|
@@ -692,7 +707,7 @@ export class SessionChatController {
|
|
|
692
707
|
}
|
|
693
708
|
}
|
|
694
709
|
}
|
|
695
|
-
async startListenCapture() {
|
|
710
|
+
async startListenCapture(abortController) {
|
|
696
711
|
if (this.deps.env.platform() !== "darwin") {
|
|
697
712
|
this.view.showFooterNotice("/listen is currently supported only on macOS.", "default");
|
|
698
713
|
return;
|
|
@@ -708,15 +723,14 @@ export class SessionChatController {
|
|
|
708
723
|
const retainedAudio = this.retainedListenAudio;
|
|
709
724
|
let audioPath;
|
|
710
725
|
let transcription;
|
|
711
|
-
let abortController;
|
|
712
726
|
let completion;
|
|
713
727
|
try {
|
|
714
728
|
audioPath = await createListenTempFilePath(this.deps);
|
|
715
729
|
if (this.disposed)
|
|
716
730
|
throw new Error("speech recording startup cancelled");
|
|
731
|
+
abortController.signal.throwIfAborted();
|
|
717
732
|
transcription = this.createSpeechTranscription("streaming");
|
|
718
|
-
|
|
719
|
-
this.listenStartupAbortController = abortController;
|
|
733
|
+
this.activeListenTranscription = transcription;
|
|
720
734
|
const capture = startListenAudioCapture({
|
|
721
735
|
deps: this.deps,
|
|
722
736
|
audioPath,
|
|
@@ -726,12 +740,7 @@ export class SessionChatController {
|
|
|
726
740
|
});
|
|
727
741
|
completion = capture.completion;
|
|
728
742
|
await this.waitForListenCaptureStart(capture.started, abortController);
|
|
729
|
-
|
|
730
|
-
throw abortController.signal.reason;
|
|
731
|
-
}
|
|
732
|
-
if (this.listenStartupAbortController === abortController) {
|
|
733
|
-
this.listenStartupAbortController = undefined;
|
|
734
|
-
}
|
|
743
|
+
abortController.signal.throwIfAborted();
|
|
735
744
|
if (retainedAudio) {
|
|
736
745
|
try {
|
|
737
746
|
await deleteListenTempFile(retainedAudio.audioPath);
|
|
@@ -744,13 +753,16 @@ export class SessionChatController {
|
|
|
744
753
|
transcription.abort();
|
|
745
754
|
await completion.catch(() => undefined);
|
|
746
755
|
await cleanupListenTempFile(audioPath);
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
756
|
+
if (abortController.signal.reason !== LISTEN_CAPTURE_START_CANCELLED && !this.disposed) {
|
|
757
|
+
this.view.addTranscriptNotice("failed to replace retained recording", "error", [
|
|
758
|
+
error.message,
|
|
759
|
+
`recording retained at ${retainedAudio.audioPath}`,
|
|
760
|
+
]);
|
|
761
|
+
}
|
|
751
762
|
return;
|
|
752
763
|
}
|
|
753
764
|
}
|
|
765
|
+
abortController.signal.throwIfAborted();
|
|
754
766
|
const recording = {
|
|
755
767
|
audioPath,
|
|
756
768
|
startedAt: Date.now(),
|
|
@@ -769,8 +781,8 @@ export class SessionChatController {
|
|
|
769
781
|
void this.watchListenRecording(recording);
|
|
770
782
|
}
|
|
771
783
|
catch (err) {
|
|
772
|
-
const cancelled = this.disposed || abortController
|
|
773
|
-
abortController
|
|
784
|
+
const cancelled = this.disposed || abortController.signal.reason === LISTEN_CAPTURE_START_CANCELLED;
|
|
785
|
+
abortController.abort();
|
|
774
786
|
transcription?.abort();
|
|
775
787
|
await completion?.catch(() => undefined);
|
|
776
788
|
if (audioPath) {
|
|
@@ -783,11 +795,9 @@ export class SessionChatController {
|
|
|
783
795
|
}
|
|
784
796
|
}
|
|
785
797
|
finally {
|
|
798
|
+
this.activeListenTranscription = undefined;
|
|
786
799
|
if (!this.listenRecording)
|
|
787
800
|
this.endListenPreview();
|
|
788
|
-
if (this.listenStartupAbortController === abortController) {
|
|
789
|
-
this.listenStartupAbortController = undefined;
|
|
790
|
-
}
|
|
791
801
|
}
|
|
792
802
|
}
|
|
793
803
|
async waitForListenCaptureStart(started, abortController) {
|
|
@@ -814,25 +824,41 @@ export class SessionChatController {
|
|
|
814
824
|
const recording = this.listenRecording;
|
|
815
825
|
if (!recording)
|
|
816
826
|
return;
|
|
827
|
+
const preview = this.listenPreview;
|
|
817
828
|
recording.stopRequested = true;
|
|
818
829
|
this.clearListenRecordingMaxDurationTimeout(recording);
|
|
819
830
|
this.listenRecording = undefined;
|
|
831
|
+
this.activeListenTranscription = recording.transcription;
|
|
820
832
|
this.refreshStatus();
|
|
821
833
|
recording.abortController.abort();
|
|
822
834
|
try {
|
|
823
|
-
|
|
835
|
+
try {
|
|
836
|
+
await recording.completion;
|
|
837
|
+
}
|
|
838
|
+
catch (err) {
|
|
839
|
+
if (this.listenPreview === preview) {
|
|
840
|
+
this.view.addTranscriptNotice("failed to record audio", "error", [
|
|
841
|
+
err.message,
|
|
842
|
+
]);
|
|
843
|
+
}
|
|
844
|
+
recording.transcription.abort();
|
|
845
|
+
this.endListenPreview();
|
|
846
|
+
await cleanupListenTempFile(recording.audioPath);
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
if (this.listenPreview !== preview || this.disposed) {
|
|
850
|
+
recording.transcription.abort();
|
|
851
|
+
await cleanupListenTempFile(recording.audioPath);
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
const durationMs = Math.min(Math.max(Date.now() - recording.startedAt, 0), SPEECH_TO_TEXT_CLIENT_MAX_DURATION_MS);
|
|
855
|
+
const transcribed = await this.transcribeListenAudioFile(recording.audioPath, durationMs, recording.transcription);
|
|
856
|
+
if (mode && transcribed && !this.disposed)
|
|
857
|
+
this.view.submitEditor(mode);
|
|
824
858
|
}
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
this.endListenPreview();
|
|
828
|
-
this.view.addTranscriptNotice("failed to record audio", "error", [err.message]);
|
|
829
|
-
await cleanupListenTempFile(recording.audioPath);
|
|
830
|
-
return;
|
|
859
|
+
finally {
|
|
860
|
+
this.activeListenTranscription = undefined;
|
|
831
861
|
}
|
|
832
|
-
const durationMs = Math.min(Math.max(Date.now() - recording.startedAt, 0), SPEECH_TO_TEXT_CLIENT_MAX_DURATION_MS);
|
|
833
|
-
const transcribed = await this.transcribeListenAudioFile(recording.audioPath, durationMs, recording.transcription);
|
|
834
|
-
if (mode && transcribed && !this.disposed)
|
|
835
|
-
this.view.submitEditor(mode);
|
|
836
862
|
}
|
|
837
863
|
async retryRetainedListenAudio() {
|
|
838
864
|
if (this.pendingEditorMutations > 0) {
|
|
@@ -929,26 +955,28 @@ export class SessionChatController {
|
|
|
929
955
|
}
|
|
930
956
|
catch (error) {
|
|
931
957
|
transcription?.abort();
|
|
932
|
-
this.
|
|
933
|
-
|
|
934
|
-
|
|
958
|
+
if (this.listenPreview === preview) {
|
|
959
|
+
this.view.addTranscriptNotice("failed to read speech recording", "error", [
|
|
960
|
+
error.message,
|
|
961
|
+
]);
|
|
962
|
+
}
|
|
935
963
|
if (this.retainedListenAudio?.audioPath === audioPath) {
|
|
936
964
|
this.retainedListenAudio = undefined;
|
|
937
965
|
}
|
|
938
966
|
await cleanupListenTempFile(audioPath);
|
|
939
967
|
return false;
|
|
940
968
|
}
|
|
941
|
-
if (
|
|
969
|
+
if (this.disposed || this.listenPreview !== preview) {
|
|
942
970
|
transcription?.abort();
|
|
943
|
-
this.view.showFooterNotice("recording too short, try again", "default");
|
|
944
971
|
if (this.retainedListenAudio?.audioPath === audioPath) {
|
|
945
972
|
this.retainedListenAudio = undefined;
|
|
946
973
|
}
|
|
947
974
|
await cleanupListenTempFile(audioPath);
|
|
948
975
|
return false;
|
|
949
976
|
}
|
|
950
|
-
if (
|
|
977
|
+
if (audio.byteLength < LISTEN_RECORDING_MIN_BYTES) {
|
|
951
978
|
transcription?.abort();
|
|
979
|
+
this.view.showFooterNotice("recording too short, try again", "default");
|
|
952
980
|
if (this.retainedListenAudio?.audioPath === audioPath) {
|
|
953
981
|
this.retainedListenAudio = undefined;
|
|
954
982
|
}
|
|
@@ -967,10 +995,6 @@ export class SessionChatController {
|
|
|
967
995
|
});
|
|
968
996
|
if (this.listenPreview !== preview)
|
|
969
997
|
return false;
|
|
970
|
-
preview.commit(text);
|
|
971
|
-
if (text.trim() && !this.editorHiddenSystemMessages.includes(TRANSCRIPTION_GUIDANCE)) {
|
|
972
|
-
this.editorHiddenSystemMessages.push(TRANSCRIPTION_GUIDANCE);
|
|
973
|
-
}
|
|
974
998
|
this.retainedListenAudio = undefined;
|
|
975
999
|
try {
|
|
976
1000
|
await deleteListenTempFile(audioPath);
|
|
@@ -981,9 +1005,17 @@ export class SessionChatController {
|
|
|
981
1005
|
`recording remains at ${audioPath}; delete it manually`,
|
|
982
1006
|
]);
|
|
983
1007
|
}
|
|
1008
|
+
if (this.listenPreview !== preview)
|
|
1009
|
+
return false;
|
|
1010
|
+
preview.commit(text);
|
|
1011
|
+
if (text.trim() && !this.editorHiddenSystemMessages.includes(TRANSCRIPTION_GUIDANCE)) {
|
|
1012
|
+
this.editorHiddenSystemMessages.push(TRANSCRIPTION_GUIDANCE);
|
|
1013
|
+
}
|
|
984
1014
|
return Boolean(text.trim());
|
|
985
1015
|
}
|
|
986
1016
|
catch (error) {
|
|
1017
|
+
if (this.listenPreview !== preview)
|
|
1018
|
+
return false;
|
|
987
1019
|
this.retainedListenAudio = { audioPath, durationMs };
|
|
988
1020
|
this.view.addTranscriptNotice("failed to transcribe speech", "error", [
|
|
989
1021
|
error.message,
|
|
@@ -1002,7 +1034,15 @@ export class SessionChatController {
|
|
|
1002
1034
|
}
|
|
1003
1035
|
}
|
|
1004
1036
|
finally {
|
|
1005
|
-
this.
|
|
1037
|
+
if (this.listenPreview !== preview) {
|
|
1038
|
+
if (this.retainedListenAudio?.audioPath === audioPath) {
|
|
1039
|
+
this.retainedListenAudio = undefined;
|
|
1040
|
+
}
|
|
1041
|
+
await cleanupListenTempFile(audioPath);
|
|
1042
|
+
}
|
|
1043
|
+
else {
|
|
1044
|
+
this.endListenPreview();
|
|
1045
|
+
}
|
|
1006
1046
|
}
|
|
1007
1047
|
}
|
|
1008
1048
|
async cancelListenCapture() {
|