@openclaw/google-meet 2026.10.10 → 2026.11.5-beta.1

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.
Files changed (99) hide show
  1. package/assets/activity.svg +1 -1
  2. package/dist/.setup/{chrome-create-DIcW4QCh.mjs → chrome-create-BlDlV2YP.mjs} +11 -30
  3. package/dist/.setup/{cli-9linTFHb.mjs → cli-C-MrY7IZ.mjs} +275 -309
  4. package/dist/.setup/{cli-export-CaDYoSP8.mjs → cli-export-6eiywS3T.mjs} +16 -35
  5. package/dist/.setup/{cli-output-mode-BJSm88N9.mjs → cli-output-mode-DztqqVeZ.mjs} +5 -6
  6. package/dist/.setup/config-CMTw0Anh.mjs +110 -0
  7. package/dist/.setup/{create-D3fHR8uX.mjs → create-DMk4zbMq.mjs} +23 -9
  8. package/dist/.setup/{google-meet-platform-adapter-D7poqL1J.mjs → google-meet-platform-adapter-DgchqNLV.mjs} +52 -18
  9. package/dist/.setup/{node-host-B196lvNZ.mjs → node-host-BIZD9InM.mjs} +2 -2
  10. package/dist/.setup/{node-invoke-policy-BzRAe25r.mjs → node-invoke-policy-bg7p_BWB.mjs} +1 -1
  11. package/dist/.setup/oauth-DZkuGMs1.mjs +1 -0
  12. package/dist/.setup/{plugin-helpers-Buhixxsx.mjs → plugin-helpers-ChCBuyAl.mjs} +363 -69
  13. package/dist/.setup/{plugin-registration-B_nOxAym.mjs → plugin-registration-CAW7_zO_.mjs} +8 -8
  14. package/dist/.setup/{runtime-D-dwEsSW.mjs → runtime-Cyc6bv1i.mjs} +37 -38
  15. package/dist/.source-module-urls/c06239f68b6f4959b5d3db7e0cee004911d8eb43092f4135c729b507e37f6333.json +1 -1
  16. package/dist/cli-metadata.js +1 -1
  17. package/dist/doctor-contract-api.js +25 -21
  18. package/dist/index.js +14 -13
  19. package/node_modules/typebox/build/format/duration.d.mts +2 -2
  20. package/node_modules/typebox/build/format/duration.mjs +2 -2
  21. package/node_modules/typebox/build/format/idn_email.d.mts +1 -0
  22. package/node_modules/typebox/build/format/idn_email.mjs +1 -0
  23. package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -1
  24. package/node_modules/typebox/build/format/idn_hostname.mjs +1 -1
  25. package/node_modules/typebox/build/format/ipv4.d.mts +2 -2
  26. package/node_modules/typebox/build/format/ipv4.mjs +2 -2
  27. package/node_modules/typebox/build/format/ipv6.d.mts +1 -1
  28. package/node_modules/typebox/build/format/ipv6.mjs +1 -1
  29. package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
  30. package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
  31. package/node_modules/typebox/build/schema/build.mjs +1 -0
  32. package/node_modules/typebox/build/schema/engine/_unique.d.mts +4 -2
  33. package/node_modules/typebox/build/schema/engine/_unique.mjs +7 -3
  34. package/node_modules/typebox/build/schema/engine/additionalItems.mjs +3 -3
  35. package/node_modules/typebox/build/schema/engine/additionalProperties.d.mts +0 -3
  36. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +15 -17
  37. package/node_modules/typebox/build/schema/engine/contains.mjs +3 -3
  38. package/node_modules/typebox/build/schema/engine/index.d.mts +1 -0
  39. package/node_modules/typebox/build/schema/engine/index.mjs +1 -0
  40. package/node_modules/typebox/build/schema/engine/items.mjs +7 -4
  41. package/node_modules/typebox/build/schema/engine/maxContains.mjs +2 -2
  42. package/node_modules/typebox/build/schema/engine/minContains.mjs +3 -3
  43. package/node_modules/typebox/build/schema/engine/oneOf.mjs +2 -2
  44. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +2 -2
  45. package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -2
  46. package/node_modules/typebox/build/schema/engine/unevaluatedItems.mjs +2 -2
  47. package/node_modules/typebox/build/schema/engine/unevaluatedProperties.mjs +2 -2
  48. package/node_modules/typebox/build/system/hashing/hash.mjs +63 -34
  49. package/node_modules/typebox/build/system/locale/en_US.mjs +2 -1
  50. package/node_modules/typebox/build/system/memory/assign.d.mts +2 -8
  51. package/node_modules/typebox/build/system/memory/assign.mjs +13 -6
  52. package/node_modules/typebox/build/system/memory/clone.d.mts +4 -5
  53. package/node_modules/typebox/build/system/memory/clone.mjs +8 -96
  54. package/node_modules/typebox/build/system/memory/create.d.mts +1 -5
  55. package/node_modules/typebox/build/system/memory/create.mjs +18 -13
  56. package/node_modules/typebox/build/system/memory/deep.d.mts +2 -0
  57. package/node_modules/typebox/build/system/memory/deep.mjs +108 -0
  58. package/node_modules/typebox/build/system/memory/discard.d.mts +1 -1
  59. package/node_modules/typebox/build/system/memory/discard.mjs +9 -8
  60. package/node_modules/typebox/build/system/memory/finalize.d.mts +4 -0
  61. package/node_modules/typebox/build/system/memory/finalize.mjs +30 -0
  62. package/node_modules/typebox/build/system/memory/keys.d.mts +2 -0
  63. package/node_modules/typebox/build/system/memory/keys.mjs +8 -0
  64. package/node_modules/typebox/build/system/memory/update.d.mts +1 -4
  65. package/node_modules/typebox/build/system/memory/update.mjs +43 -16
  66. package/node_modules/typebox/build/type/engine/call/index.d.mts +1 -0
  67. package/node_modules/typebox/build/type/engine/call/index.mjs +1 -0
  68. package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +2 -24
  69. package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +2 -29
  70. package/node_modules/typebox/build/type/engine/evaluate/index.d.mts +1 -0
  71. package/node_modules/typebox/build/type/engine/evaluate/index.mjs +1 -0
  72. package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +5 -1
  73. package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +6 -1
  74. package/node_modules/typebox/build/type/engine/evaluate/property.d.mts +30 -0
  75. package/node_modules/typebox/build/type/engine/evaluate/property.mjs +29 -0
  76. package/node_modules/typebox/build/type/engine/immutable/instantiate_add.d.mts +1 -3
  77. package/node_modules/typebox/build/type/engine/immutable/instantiate_add.mjs +1 -4
  78. package/node_modules/typebox/build/type/engine/object/from_intersect.d.mts +2 -2
  79. package/node_modules/typebox/build/type/engine/object/from_intersect.mjs +2 -2
  80. package/node_modules/typebox/build/type/engine/object/from_union.d.mts +2 -2
  81. package/node_modules/typebox/build/type/engine/object/from_union.mjs +2 -2
  82. package/node_modules/typebox/build/type/engine/optional/instantiate_add.d.mts +1 -3
  83. package/node_modules/typebox/build/type/engine/optional/instantiate_add.mjs +1 -4
  84. package/node_modules/typebox/build/type/engine/readonly/instantiate_add.d.mts +1 -3
  85. package/node_modules/typebox/build/type/engine/readonly/instantiate_add.mjs +1 -4
  86. package/node_modules/typebox/build/type/engine/this/index.d.mts +1 -0
  87. package/node_modules/typebox/build/type/engine/this/index.mjs +1 -0
  88. package/node_modules/typebox/build/value/clone/clone.d.mts +4 -3
  89. package/node_modules/typebox/build/value/clone/clone.mjs +5 -7
  90. package/node_modules/typebox/build/value/repair/from_cyclic.d.mts +2 -0
  91. package/node_modules/typebox/build/value/repair/from_cyclic.mjs +6 -0
  92. package/node_modules/typebox/build/value/shared/union_priority_sort.mjs +25 -14
  93. package/node_modules/typebox/package.json +1 -1
  94. package/node_modules/typebox/readme.md +1 -1
  95. package/package.json +5 -5
  96. package/dist/.setup/config-Cu3zsl_3.mjs +0 -239
  97. package/dist/.setup/oauth-DGv28ZgA.mjs +0 -158
  98. package/node_modules/typebox/build/system/memory/freeze.d.mts +0 -4
  99. package/node_modules/typebox/build/system/memory/freeze.mjs +0 -6
@@ -1,11 +1,8 @@
1
1
  // deno-fmt-ignore-file
2
2
  import { Memory } from '../../../system/memory/index.mjs';
3
3
  import { InstantiateType } from '../instantiate.mjs';
4
- function AddReadonlyOperation(type) {
5
- return Memory.Update(type, { '~readonly': true }, {});
6
- }
7
4
  export function AddReadonlyAction(type, options) {
8
- const result = Memory.Update(AddReadonlyOperation(type), {}, options);
5
+ const result = Memory.Update(type, { '~readonly': true }, options);
9
6
  return result;
10
7
  }
11
8
  export function AddReadonlyInstantiate(context, state, type, options) {
@@ -0,0 +1 @@
1
+ export * from './expand_this.mjs';
@@ -0,0 +1 @@
1
+ export * from './expand_this.mjs';
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Returns a Clone of the given value. This function is similar to structuredClone()
3
- * but also supports deep cloning instances of Map, Set and TypeArray.
2
+ * Returns a deep Clone of the given value. This function is similar to `structuredClone()`,
3
+ * but also supports deep cloning `Map`, `Set`, and `TypeArray` instances. This function can also be used
4
+ * to clone TypeBox types while retaining their enumerable and non-enumerable properties.
4
5
  */
5
- export declare function Clone<Value extends unknown>(value: Value): Value;
6
+ export declare function Clone<Value extends unknown = unknown>(value: Value): Value;
@@ -1,12 +1,10 @@
1
1
  // deno-fmt-ignore-file
2
- import { Clone as SystemClone } from '../../system/memory/clone.mjs';
3
- // ------------------------------------------------------------------
4
- // Clone
5
- // ------------------------------------------------------------------
2
+ import { Deep } from '../../system/memory/deep.mjs';
6
3
  /**
7
- * Returns a Clone of the given value. This function is similar to structuredClone()
8
- * but also supports deep cloning instances of Map, Set and TypeArray.
4
+ * Returns a deep Clone of the given value. This function is similar to `structuredClone()`,
5
+ * but also supports deep cloning `Map`, `Set`, and `TypeArray` instances. This function can also be used
6
+ * to clone TypeBox types while retaining their enumerable and non-enumerable properties.
9
7
  */
10
8
  export function Clone(value) {
11
- return SystemClone(value);
9
+ return Deep(value);
12
10
  }
@@ -0,0 +1,2 @@
1
+ import { type TProperties, type TCyclic } from '../../type/index.mjs';
2
+ export declare function FromCyclic(context: TProperties, type: TCyclic, value: unknown): unknown;
@@ -0,0 +1,6 @@
1
+ // deno-fmt-ignore-file
2
+ import { Ref } from '../../type/index.mjs';
3
+ import { FromType } from './from_type.mjs';
4
+ export function FromCyclic(context, type, value) {
5
+ return FromType({ ...context, ...type.$defs }, Ref(type.$ref), value);
6
+ }
@@ -1,28 +1,27 @@
1
1
  // deno-fmt-ignore-file
2
2
  import Guard from '../../guard/index.mjs';
3
- import { IsArray, Array as _Array_, ArrayOptions } from '../../type/index.mjs';
4
- import { IsUnion, Union } from '../../type/index.mjs';
3
+ import { Memory } from '../../system/memory/index.mjs';
4
+ import { Array as _Array_, ArrayOptions, IsArray } from '../../type/index.mjs';
5
+ import { Intersect, IsIntersect } from '../../type/index.mjs';
5
6
  import { IsObject, Object as _Object_ } from '../../type/index.mjs';
6
- import { IsRecord, Record, RecordKey, RecordValue } from '../../type/index.mjs';
7
+ import { IsRecord, Record, RecordPattern, RecordValue } from '../../type/index.mjs';
8
+ import { String } from '../../type/index.mjs';
7
9
  import { IsTuple, Tuple } from '../../type/index.mjs';
8
- import { IsIntersect, Intersect } from '../../type/index.mjs';
10
+ import { IsUnion, Union } from '../../type/index.mjs';
9
11
  import { Priority } from '../../type/index.mjs';
10
12
  // ------------------------------------------------------------------
11
13
  // Modifiers (Mutable)
12
14
  //
13
15
  // Prioritized types lose `~modifier` properties and additional constraints
14
16
  // (e.g. additionalProperties) during the mapping phase and need to be
15
- // reassigned afterward. This is a fast mutable assignment to handle that,
16
- // but we should consider a more general solution. (review)
17
+ // reassigned afterward. We previously used a mutable assignment on this
18
+ // function, however `immutableTypes: true` caused errors. We use the
19
+ // Memory.Assign to ensure modifiers are retained and we preserve type
20
+ // configurations (review)
17
21
  //
18
22
  // ------------------------------------------------------------------
19
23
  function Modifiers(type, next) {
20
- for (const key of Guard.Keys(type)) {
21
- if (Guard.HasPropertyKey(next, key))
22
- continue;
23
- next[key] = type[key];
24
- }
25
- return next;
24
+ return Memory.Assign(type, next);
26
25
  }
27
26
  // ------------------------------------------------------------------
28
27
  // Properties
@@ -34,6 +33,18 @@ function FromProperties(properties) {
34
33
  return result;
35
34
  }
36
35
  // ------------------------------------------------------------------
36
+ // FromRecordKey
37
+ //
38
+ // This is required because RecordKey(...) returns a canonical
39
+ // decoded type derived from the pattern. When the pattern is an
40
+ // unrecognized user-defined one, the result falls through to
41
+ // TString (^.*$) and the user-defined pattern is lost. This
42
+ // function ensures the exact pattern is retained.
43
+ // ------------------------------------------------------------------
44
+ function FromRecordKey(type) {
45
+ return String({ pattern: RecordPattern(type) });
46
+ }
47
+ // ------------------------------------------------------------------
37
48
  // PriorityTypes
38
49
  // ------------------------------------------------------------------
39
50
  function FromPriorityTypes(types) {
@@ -43,7 +54,7 @@ function FromPriorityTypes(types) {
43
54
  // Types
44
55
  // ------------------------------------------------------------------
45
56
  function FromTypes(types) {
46
- return types.map(type => FromType(type));
57
+ return types.map((type) => FromType(type));
47
58
  }
48
59
  // ------------------------------------------------------------------
49
60
  // Type
@@ -53,7 +64,7 @@ function FromType(type) {
53
64
  IsIntersect(type) ? Intersect(FromTypes(type.allOf)) :
54
65
  IsUnion(type) ? Union(FromPriorityTypes(type.anyOf)) :
55
66
  IsObject(type) ? _Object_(FromProperties(type.properties)) :
56
- IsRecord(type) ? Record(RecordKey(type), FromType(RecordValue(type))) :
67
+ IsRecord(type) ? Record(FromRecordKey(type), FromType(RecordValue(type))) :
57
68
  IsTuple(type) ? Tuple(FromTypes(type.items)) :
58
69
  type);
59
70
  return Modifiers(type, next);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "typebox",
3
3
  "description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
4
- "version": "1.3.35",
4
+ "version": "1.4.2",
5
5
  "keywords": [
6
6
  "typescript",
7
7
  "jsonschema"
@@ -196,7 +196,7 @@ const result = Vector.Parse({ x: 1, y: 0, z: 0 }) // const result: {
196
196
 
197
197
  [JSON Schema Test Suite](https://github.com/json-schema-org/JSON-Schema-Test-Suite) | [JSON Schema Compliance Suite](https://github.com/sinclairzx81/json-schema-compliance-suite)
198
198
 
199
- TypeBox supports all versions of JSON Schema and is heavily tested against the official JSON Schema Test Suite. It prioritizes compatibility with modern specifications while also maintaining broad support for legacy versions provided their semantics are not in conflict with modern specifications.
199
+ TypeBox supports all versions of JSON Schema and is heavily tested against the official JSON Schema Test Suite. It has high compatibility with modern specifications while also offering broad support for legacy versions if their semantics are not in conflict with modern specifications.
200
200
 
201
201
  | Spec | 3 | 4 | 6 | 7 | 2019-09 | 2020-12 | v1 |
202
202
  |:-----|:--|:--|:--|:--|:--|:--|:--|
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/google-meet",
3
- "version": "2026.10.10",
3
+ "version": "2026.11.5-beta.1",
4
4
  "description": "OpenClaw Google Meet participant plugin for joining calls through Chrome or Twilio transports.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,10 +9,10 @@
9
9
  "type": "module",
10
10
  "dependencies": {
11
11
  "jszip": "3.10.2",
12
- "typebox": "1.3.35"
12
+ "typebox": "1.4.2"
13
13
  },
14
14
  "peerDependencies": {
15
- "openclaw": ">=2026.10.10"
15
+ "openclaw": ">=2026.11.5-beta.1"
16
16
  },
17
17
  "peerDependenciesMeta": {
18
18
  "openclaw": {
@@ -30,10 +30,10 @@
30
30
  "minHostVersion": ">=2026.4.20"
31
31
  },
32
32
  "compat": {
33
- "pluginApi": ">=2026.10.10"
33
+ "pluginApi": ">=2026.11.5-beta.1"
34
34
  },
35
35
  "build": {
36
- "openclawVersion": "2026.10.10"
36
+ "openclawVersion": "2026.11.5-beta.1"
37
37
  },
38
38
  "release": {
39
39
  "publishToClawHub": true,
@@ -1,239 +0,0 @@
1
- import { asBoolean, asRecord, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalTrimmedStringList, parseBooleanValue, readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
2
- import { addTimerTimeoutGraceMs, asPositiveFiniteNumber, resolvePositiveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
3
- import { REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME, resolveRealtimeVoiceAgentConsultToolPolicy } from "openclaw/plugin-sdk/realtime-voice";
4
- // extensions/google-meet/src/config.ts
5
- function resolveGoogleMeetGatewayOperationTimeoutMs(config) {
6
- return Math.max(6e4, addTimerTimeoutGraceMs(config.chrome.joinTimeoutMs, 3e4) ?? 1, addTimerTimeoutGraceMs(config.voiceCall.requestTimeoutMs, 1e4) ?? 1);
7
- }
8
- const SOX_DEFAULT_BUFFER_BYTES = 8192;
9
- const SOX_MIN_BUFFER_BYTES = 17;
10
- const DEFAULT_GOOGLE_MEET_AUDIO_BUFFER_BYTES = SOX_DEFAULT_BUFFER_BYTES / 2;
11
- const PLAIN_DECIMAL_NUMBER_RE = /^\d+(?:\.\d+)?$/;
12
- function buildGoogleMeetAudioCommands(backend, format, bufferBytes) {
13
- const pipeWire = backend === "pipewire-pulse" || backend === "auto" && process.platform === "linux";
14
- const sampleRate = format === "g711-ulaw-8khz" ? 8e3 : 24e3;
15
- const bits = format === "g711-ulaw-8khz" ? 8 : 16;
16
- if (pipeWire) {
17
- const pulseFormat = format === "g711-ulaw-8khz" ? "ulaw" : "s16le";
18
- const latencyMs = Math.max(1, Math.ceil(bufferBytes / (sampleRate * Math.ceil(bits / 8)) * 1e3));
19
- const common = [
20
- "--device=openclaw_meeting_audio",
21
- `--format=${pulseFormat}`,
22
- `--rate=${sampleRate}`,
23
- "--channels=1",
24
- `--latency-msec=${latencyMs}`
25
- ];
26
- return {
27
- inputCommand: [
28
- "parec",
29
- "--raw",
30
- ...common
31
- ],
32
- outputCommand: [
33
- "pacat",
34
- "--raw",
35
- "--playback",
36
- ...common
37
- ]
38
- };
39
- }
40
- const wire = format === "g711-ulaw-8khz" ? [
41
- "-t",
42
- "raw",
43
- "-r",
44
- "8000",
45
- "-c",
46
- "1",
47
- "-e",
48
- "mu-law",
49
- "-b",
50
- "8",
51
- "-"
52
- ] : [
53
- "-t",
54
- "raw",
55
- "-r",
56
- "24000",
57
- "-c",
58
- "1",
59
- "-e",
60
- "signed-integer",
61
- "-b",
62
- "16",
63
- "-L",
64
- "-"
65
- ];
66
- const withBuffer = (executable, args) => [
67
- executable,
68
- "-q",
69
- "--buffer",
70
- String(bufferBytes),
71
- ...args
72
- ];
73
- return {
74
- inputCommand: withBuffer("sox", [
75
- "-t",
76
- "coreaudio",
77
- "BlackHole 2ch",
78
- ...wire
79
- ]),
80
- outputCommand: withBuffer("sox", [
81
- ...wire,
82
- "-t",
83
- "coreaudio",
84
- "BlackHole 2ch"
85
- ])
86
- };
87
- }
88
- const DEFAULT_GOOGLE_MEET_AUDIO_COMMANDS = buildGoogleMeetAudioCommands("blackhole-2ch", "pcm16-24khz", DEFAULT_GOOGLE_MEET_AUDIO_BUFFER_BYTES);
89
- const DEFAULT_GOOGLE_MEET_AUDIO_INPUT_COMMAND = DEFAULT_GOOGLE_MEET_AUDIO_COMMANDS.inputCommand;
90
- const DEFAULT_GOOGLE_MEET_AUDIO_OUTPUT_COMMAND = DEFAULT_GOOGLE_MEET_AUDIO_COMMANDS.outputCommand;
91
- const DEFAULT_GOOGLE_MEET_REALTIME_INSTRUCTIONS = `You are joining a private Google Meet as an OpenClaw voice transport. Keep spoken replies brief and natural. In agent mode, wait for OpenClaw consult results and speak them exactly. In bidi mode, answer directly and call ${REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME} for deeper reasoning, current information, or tools.`;
92
- const DEFAULT_GOOGLE_MEET_REALTIME_INTRO_MESSAGE = "Say exactly: I'm here and listening.";
93
- function resolveOptionalNumber(value) {
94
- if (typeof value === "number" && Number.isFinite(value)) return value;
95
- if (typeof value === "string" && value.trim()) {
96
- const trimmed = value.trim();
97
- const parsed = PLAIN_DECIMAL_NUMBER_RE.test(trimmed) ? Number(trimmed) : NaN;
98
- return Number.isFinite(parsed) ? parsed : void 0;
99
- }
100
- }
101
- function readGoogleMeetEnv(env, name) {
102
- return normalizeOptionalString(env[name]) ?? normalizeOptionalString(env[name.slice(9)]);
103
- }
104
- function resolveProvidersConfig(value) {
105
- const raw = asRecord(value);
106
- const providers = {};
107
- for (const [key, entry] of Object.entries(raw)) {
108
- const providerId = normalizeOptionalLowercaseString(key);
109
- if (!providerId) continue;
110
- providers[providerId] = asRecord(entry);
111
- }
112
- return providers;
113
- }
114
- function resolveTransport(value, fallback) {
115
- const normalized = normalizeOptionalLowercaseString(value);
116
- return normalized === "chrome" || normalized === "chrome-node" || normalized === "twilio" ? normalized : fallback;
117
- }
118
- function resolveMode(value, fallback) {
119
- const normalized = normalizeOptionalLowercaseString(value);
120
- if (normalized === "realtime") return "agent";
121
- return normalized === "agent" || normalized === "bidi" || normalized === "transcribe" ? normalized : fallback;
122
- }
123
- function resolveRealtimeStrategy(value, fallback) {
124
- const normalized = normalizeOptionalLowercaseString(value);
125
- return normalized === "agent" || normalized === "bidi" ? normalized : fallback;
126
- }
127
- function resolveChromeAudioFormat(value) {
128
- switch (normalizeOptionalString(value)?.toLowerCase().replaceAll("_", "-")) {
129
- case "pcm16-24khz":
130
- case "pcm16-24k":
131
- case "pcm24":
132
- case "pcm": return "pcm16-24khz";
133
- case "g711-ulaw-8khz":
134
- case "g711-ulaw-8k":
135
- case "g711-ulaw":
136
- case "mulaw":
137
- case "mu-law": return "g711-ulaw-8khz";
138
- default: return;
139
- }
140
- }
141
- function resolveAudioBufferBytes(value, fallback) {
142
- return Math.max(SOX_MIN_BUFFER_BYTES, Math.trunc(asPositiveFiniteNumber(value) ?? fallback));
143
- }
144
- function resolveAudioBackend(value) {
145
- const normalized = normalizeOptionalLowercaseString(value)?.replaceAll("_", "-");
146
- return normalized === "blackhole-2ch" || normalized === "pipewire-pulse" ? normalized : "auto";
147
- }
148
- function resolveGoogleMeetConfig(input) {
149
- const env = process.env;
150
- const raw = asRecord(input);
151
- const defaults = asRecord(raw.defaults);
152
- const preview = asRecord(raw.preview);
153
- const chrome = asRecord(raw.chrome);
154
- const configuredAudioInputCommand = normalizeOptionalTrimmedStringList(chrome.audioInputCommand);
155
- const configuredAudioOutputCommand = normalizeOptionalTrimmedStringList(chrome.audioOutputCommand);
156
- const hasCustomAudioCommand = configuredAudioInputCommand !== void 0 || configuredAudioOutputCommand !== void 0;
157
- const audioFormat = resolveChromeAudioFormat(chrome.audioFormat) ?? (hasCustomAudioCommand ? "g711-ulaw-8khz" : "pcm16-24khz");
158
- const audioBufferBytes = resolveAudioBufferBytes(chrome.audioBufferBytes, DEFAULT_GOOGLE_MEET_AUDIO_BUFFER_BYTES);
159
- const audioBackend = resolveAudioBackend(chrome.audioBackend);
160
- const audioCommands = buildGoogleMeetAudioCommands(audioBackend, audioFormat, audioBufferBytes);
161
- const chromeNode = asRecord(raw.chromeNode);
162
- const twilio = asRecord(raw.twilio);
163
- const voiceCall = asRecord(raw.voiceCall);
164
- const realtime = asRecord(raw.realtime);
165
- const realtimeProvider = normalizeOptionalString(realtime.provider);
166
- const resolvedRealtimeProvider = realtimeProvider ?? "openai";
167
- const oauth = asRecord(raw.oauth);
168
- const auth = asRecord(raw.auth);
169
- return {
170
- enabled: asBoolean(raw.enabled) ?? true,
171
- defaults: { meeting: normalizeOptionalString(defaults.meeting) ?? readGoogleMeetEnv(env, "OPENCLAW_GOOGLE_MEET_DEFAULT_MEETING") },
172
- preview: { enrollmentAcknowledged: asBoolean(preview.enrollmentAcknowledged) ?? parseBooleanValue(readGoogleMeetEnv(env, "OPENCLAW_GOOGLE_MEET_PREVIEW_ACK")) ?? false },
173
- defaultTransport: resolveTransport(raw.defaultTransport, "chrome"),
174
- defaultMode: resolveMode(raw.defaultMode, "agent"),
175
- chrome: {
176
- audioBackend,
177
- audioFormat,
178
- audioBufferBytes,
179
- launch: asBoolean(chrome.launch) ?? true,
180
- browserProfile: normalizeOptionalString(chrome.browserProfile),
181
- guestName: normalizeOptionalString(chrome.guestName) ?? "OpenClaw Agent",
182
- reuseExistingTab: asBoolean(chrome.reuseExistingTab) ?? true,
183
- autoJoin: asBoolean(chrome.autoJoin) ?? true,
184
- joinTimeoutMs: resolvePositiveTimerTimeoutMs(chrome.joinTimeoutMs, 3e4),
185
- waitForInCallMs: resolvePositiveTimerTimeoutMs(chrome.waitForInCallMs, 2e4),
186
- audioInputCommand: configuredAudioInputCommand ?? audioCommands.inputCommand,
187
- audioOutputCommand: configuredAudioOutputCommand ?? audioCommands.outputCommand,
188
- audioInputCommandOverride: configuredAudioInputCommand,
189
- audioOutputCommandOverride: configuredAudioOutputCommand,
190
- bargeInInputCommand: normalizeOptionalTrimmedStringList(chrome.bargeInInputCommand),
191
- bargeInRmsThreshold: asPositiveFiniteNumber(chrome.bargeInRmsThreshold) ?? 650,
192
- bargeInPeakThreshold: asPositiveFiniteNumber(chrome.bargeInPeakThreshold) ?? 2500,
193
- bargeInCooldownMs: resolvePositiveTimerTimeoutMs(chrome.bargeInCooldownMs, 900),
194
- audioBridgeCommand: normalizeOptionalTrimmedStringList(chrome.audioBridgeCommand),
195
- audioBridgeHealthCommand: normalizeOptionalTrimmedStringList(chrome.audioBridgeHealthCommand)
196
- },
197
- chromeNode: { node: normalizeOptionalString(chromeNode.node) },
198
- twilio: {
199
- defaultDialInNumber: normalizeOptionalString(twilio.defaultDialInNumber),
200
- defaultPin: normalizeOptionalString(twilio.defaultPin),
201
- defaultDtmfSequence: normalizeOptionalString(twilio.defaultDtmfSequence)
202
- },
203
- voiceCall: {
204
- enabled: asBoolean(voiceCall.enabled) ?? true,
205
- gatewayUrl: normalizeOptionalString(voiceCall.gatewayUrl),
206
- token: normalizeOptionalString(voiceCall.token),
207
- requestTimeoutMs: resolvePositiveTimerTimeoutMs(voiceCall.requestTimeoutMs, 3e4),
208
- dtmfDelayMs: resolvePositiveTimerTimeoutMs(voiceCall.dtmfDelayMs, 12e3),
209
- postDtmfSpeechDelayMs: resolvePositiveTimerTimeoutMs(voiceCall.postDtmfSpeechDelayMs, 5e3),
210
- introMessage: normalizeOptionalString(voiceCall.introMessage)
211
- },
212
- realtime: {
213
- strategy: resolveRealtimeStrategy(realtime.strategy, "agent"),
214
- provider: resolvedRealtimeProvider,
215
- transcriptionProvider: normalizeOptionalString(realtime.transcriptionProvider) ?? (realtimeProvider && realtimeProvider !== "google" ? resolvedRealtimeProvider : "openai"),
216
- voiceProvider: normalizeOptionalString(realtime.voiceProvider),
217
- model: normalizeOptionalString(realtime.model),
218
- instructions: normalizeOptionalString(realtime.instructions) ?? DEFAULT_GOOGLE_MEET_REALTIME_INSTRUCTIONS,
219
- introMessage: readStringValue(realtime.introMessage)?.trim() ?? DEFAULT_GOOGLE_MEET_REALTIME_INTRO_MESSAGE,
220
- agentId: normalizeOptionalString(realtime.agentId),
221
- toolPolicy: resolveRealtimeVoiceAgentConsultToolPolicy(realtime.toolPolicy, "safe-read-only"),
222
- providers: resolveProvidersConfig(realtime.providers)
223
- },
224
- oauth: {
225
- clientId: normalizeOptionalString(oauth.clientId) ?? normalizeOptionalString(auth.clientId) ?? readGoogleMeetEnv(env, "OPENCLAW_GOOGLE_MEET_CLIENT_ID"),
226
- clientSecret: normalizeOptionalString(oauth.clientSecret) ?? normalizeOptionalString(auth.clientSecret) ?? readGoogleMeetEnv(env, "OPENCLAW_GOOGLE_MEET_CLIENT_SECRET"),
227
- refreshToken: normalizeOptionalString(oauth.refreshToken) ?? readGoogleMeetEnv(env, "OPENCLAW_GOOGLE_MEET_REFRESH_TOKEN"),
228
- accessToken: normalizeOptionalString(oauth.accessToken) ?? readGoogleMeetEnv(env, "OPENCLAW_GOOGLE_MEET_ACCESS_TOKEN"),
229
- expiresAt: resolveOptionalNumber(oauth.expiresAt) ?? resolveOptionalNumber(readGoogleMeetEnv(env, "OPENCLAW_GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT"))
230
- },
231
- auth: {
232
- provider: "google-oauth",
233
- clientId: normalizeOptionalString(auth.clientId),
234
- clientSecret: normalizeOptionalString(auth.clientSecret),
235
- tokenPath: normalizeOptionalString(auth.tokenPath)
236
- }
237
- };
238
- }
239
- export { resolveGoogleMeetGatewayOperationTimeoutMs as i, DEFAULT_GOOGLE_MEET_AUDIO_OUTPUT_COMMAND as n, resolveGoogleMeetConfig as r, DEFAULT_GOOGLE_MEET_AUDIO_INPUT_COMMAND as t };
@@ -1,158 +0,0 @@
1
- import { t as readGoogleApiErrorDetail } from "./google-api-B5FR9zy2.mjs";
2
- import { MAX_DATE_TIMESTAMP_MS, resolveDateTimestampMs, resolveExpiresAtMsFromDurationSeconds } from "openclaw/plugin-sdk/number-runtime";
3
- import { readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http";
4
- import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
5
- import { parseOAuthCallbackInput, waitForLocalOAuthCallback } from "openclaw/plugin-sdk/provider-auth-runtime";
6
- // extensions/google-meet/src/oauth.ts
7
- const GOOGLE_MEET_REDIRECT_URI = "http://localhost:8085/oauth2callback";
8
- const GOOGLE_MEET_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
9
- const GOOGLE_MEET_TOKEN_URL = "https://oauth2.googleapis.com/token";
10
- const GOOGLE_MEET_TOKEN_HOST = "oauth2.googleapis.com";
11
- const GOOGLE_MEET_DEFAULT_TOKEN_LIFETIME_SECONDS = 3600;
12
- const GOOGLE_OAUTH_TOKEN_JSON_MAX_BYTES = 262144;
13
- const GOOGLE_OAUTH_REQUEST_TIMEOUT_MS = 3e4;
14
- const GOOGLE_MEET_SCOPES = [
15
- "https://www.googleapis.com/auth/meetings.space.created",
16
- "https://www.googleapis.com/auth/meetings.space.readonly",
17
- "https://www.googleapis.com/auth/meetings.space.settings",
18
- "https://www.googleapis.com/auth/meetings.conference.media.readonly",
19
- "https://www.googleapis.com/auth/calendar.events.readonly",
20
- "https://www.googleapis.com/auth/drive.meet.readonly"
21
- ];
22
- function resolveGoogleMeetTokenExpiresAt(value) {
23
- const now = resolveDateTimestampMs(Date.now());
24
- if (typeof value === "number" && Number.isFinite(value) && value <= 0) return now;
25
- return resolveExpiresAtMsFromDurationSeconds(value, { nowMs: now }) ?? resolveExpiresAtMsFromDurationSeconds(GOOGLE_MEET_DEFAULT_TOKEN_LIFETIME_SECONDS, { nowMs: now }) ?? now;
26
- }
27
- function buildGoogleMeetAuthUrl(params) {
28
- const search = new URLSearchParams({
29
- client_id: params.clientId,
30
- response_type: "code",
31
- redirect_uri: params.redirectUri ?? GOOGLE_MEET_REDIRECT_URI,
32
- scope: (params.scopes ?? GOOGLE_MEET_SCOPES).join(" "),
33
- code_challenge: params.challenge,
34
- code_challenge_method: "S256",
35
- access_type: "offline",
36
- prompt: "consent",
37
- state: params.state
38
- });
39
- return `${GOOGLE_MEET_AUTH_URL}?${search.toString()}`;
40
- }
41
- async function executeGoogleTokenRequest(body) {
42
- const { response, release } = await fetchWithSsrFGuard({
43
- url: GOOGLE_MEET_TOKEN_URL,
44
- init: {
45
- method: "POST",
46
- headers: {
47
- "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
48
- Accept: "application/json"
49
- },
50
- body
51
- },
52
- policy: { allowedHostnames: [GOOGLE_MEET_TOKEN_HOST] },
53
- auditContext: "google-meet.oauth.token",
54
- timeoutMs: GOOGLE_OAUTH_REQUEST_TIMEOUT_MS
55
- });
56
- try {
57
- if (!response.ok) {
58
- const detail = await readGoogleApiErrorDetail(response);
59
- throw new Error(`Google OAuth token request failed (${response.status}): ${detail}`);
60
- }
61
- const payload = await readProviderJsonResponse(response, "Google OAuth token", { maxBytes: GOOGLE_OAUTH_TOKEN_JSON_MAX_BYTES });
62
- const accessToken = payload.access_token?.trim();
63
- if (!accessToken) throw new Error("Google OAuth token response was missing access_token");
64
- return {
65
- accessToken,
66
- expiresAt: resolveGoogleMeetTokenExpiresAt(payload.expires_in),
67
- refreshToken: payload.refresh_token?.trim() || void 0,
68
- scope: payload.scope?.trim() || void 0,
69
- tokenType: payload.token_type?.trim() || void 0
70
- };
71
- } finally {
72
- await release();
73
- }
74
- }
75
- function tokenRequestBody(values) {
76
- const body = new URLSearchParams();
77
- for (const [key, value] of Object.entries(values)) if (value?.trim()) body.set(key, value);
78
- return body;
79
- }
80
- async function exchangeGoogleMeetAuthCode(params) {
81
- return await executeGoogleTokenRequest(tokenRequestBody({
82
- client_id: params.clientId,
83
- client_secret: params.clientSecret,
84
- code: params.code,
85
- grant_type: "authorization_code",
86
- redirect_uri: params.redirectUri ?? GOOGLE_MEET_REDIRECT_URI,
87
- code_verifier: params.verifier
88
- }));
89
- }
90
- async function refreshGoogleMeetAccessToken(params) {
91
- return await executeGoogleTokenRequest(tokenRequestBody({
92
- client_id: params.clientId,
93
- client_secret: params.clientSecret,
94
- grant_type: "refresh_token",
95
- refresh_token: params.refreshToken
96
- }));
97
- }
98
- function shouldUseCachedGoogleMeetAccessToken(params) {
99
- const now = Date.now();
100
- return Boolean(params.accessToken?.trim() && typeof params.expiresAt === "number" && Number.isFinite(params.expiresAt) && params.expiresAt <= MAX_DATE_TIMESTAMP_MS && params.expiresAt > now + 6e4);
101
- }
102
- async function resolveGoogleMeetAccessToken(params) {
103
- if (shouldUseCachedGoogleMeetAccessToken(params)) return {
104
- accessToken: params.accessToken.trim(),
105
- expiresAt: params.expiresAt,
106
- refreshed: false
107
- };
108
- if (!params.clientId?.trim() || !params.refreshToken?.trim()) throw new Error("Missing Google Meet OAuth credentials. Configure oauth.clientId and oauth.refreshToken, or pass --client-id and --refresh-token.");
109
- const refreshed = await refreshGoogleMeetAccessToken({
110
- clientId: params.clientId,
111
- clientSecret: params.clientSecret,
112
- refreshToken: params.refreshToken
113
- });
114
- return {
115
- accessToken: refreshed.accessToken,
116
- expiresAt: refreshed.expiresAt,
117
- refreshed: true
118
- };
119
- }
120
- function isLocalCallbackListenerError(error) {
121
- if (!(error instanceof Error)) return false;
122
- return error.message.includes("EADDRINUSE") || error.message.includes("port") || error.message.includes("listen");
123
- }
124
- async function readManualGoogleMeetAuthCode(params) {
125
- const input = await params.promptInput("Paste the full redirect URL here: ");
126
- const parsed = parseOAuthCallbackInput(input, {
127
- missingState: "Missing 'state' parameter. Paste the full redirect URL.",
128
- invalidInput: "Paste the full redirect URL, not just the code."
129
- });
130
- if ("error" in parsed) throw new Error(parsed.error);
131
- if (parsed.state !== params.state) throw new Error("OAuth state mismatch - please try again");
132
- return parsed.code;
133
- }
134
- async function waitForGoogleMeetAuthCode(params) {
135
- params.writeLine(`Open this URL in your browser:\n\n${params.authUrl}\n`);
136
- if (params.manual) return await readManualGoogleMeetAuthCode({
137
- state: params.state,
138
- promptInput: params.promptInput
139
- });
140
- try {
141
- return (await waitForLocalOAuthCallback({
142
- expectedState: params.state,
143
- timeoutMs: params.timeoutMs,
144
- port: 8085,
145
- callbackPath: "/oauth2callback",
146
- redirectUri: GOOGLE_MEET_REDIRECT_URI,
147
- successTitle: "Google Meet OAuth complete"
148
- })).code;
149
- } catch (error) {
150
- if (!isLocalCallbackListenerError(error)) throw error;
151
- params.writeLine("Local callback server failed. Switching to manual mode...");
152
- return await readManualGoogleMeetAuthCode({
153
- state: params.state,
154
- promptInput: params.promptInput
155
- });
156
- }
157
- }
158
- export { buildGoogleMeetAuthUrl, exchangeGoogleMeetAuthCode, resolveGoogleMeetAccessToken, waitForGoogleMeetAuthCode };
@@ -1,4 +0,0 @@
1
- type ObjectLike = Record<PropertyKey, any>;
2
- /** Conditionally freezes the value if `immutableTypes` is true, otherwise no action. */
3
- export declare function Freeze(value: ObjectLike): ObjectLike;
4
- export {};
@@ -1,6 +0,0 @@
1
- // deno-lint-ignore-file no-explicit-any
2
- import { Settings } from '../settings/index.mjs';
3
- /** Conditionally freezes the value if `immutableTypes` is true, otherwise no action. */
4
- export function Freeze(value) {
5
- return Settings.Get().immutableTypes ? Object.freeze(value) : value;
6
- }