mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:50:43 +00:00
feat(google-meet): default artifacts to latest record
This commit is contained in:
@@ -77,6 +77,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Plugins/Google Meet: add `googlemeet artifacts` and `googlemeet attendance` commands plus matching tool/gateway actions for conference records, recordings, transcripts and transcript entries, smart notes, and participant sessions. Thanks @steipete.
|
||||
- Plugins/Google Meet: add markdown and file output for `googlemeet artifacts` and `googlemeet attendance` reports. Thanks @steipete.
|
||||
- Plugins/Google Meet: add `googlemeet latest` plus matching tool/gateway actions to find the newest conference record for a meeting. Thanks @steipete.
|
||||
- Plugins/Google Meet: make meeting-based artifact and attendance lookups use the latest conference record by default, with `--all-conference-records` for full history. Thanks @steipete.
|
||||
- Plugins/Google Meet: add `googlemeet doctor --oauth` so operators can verify OAuth token refresh, Meet space reads, and side-effecting space creation without printing secrets. Thanks @steipete.
|
||||
- Plugins/Voice Call: expose the shared `openclaw_agent_consult` realtime tool so live phone calls can ask the full OpenClaw agent for deeper/tool-backed answers. Thanks @steipete.
|
||||
- Plugins/Voice Call: add `voicecall setup` and a dry-run-by-default `voicecall smoke` command so Twilio/provider readiness can be checked before placing a live test call. Thanks @steipete.
|
||||
|
||||
@@ -635,6 +635,10 @@ openclaw googlemeet artifacts --meeting https://meet.google.com/abc-defg-hij
|
||||
openclaw googlemeet attendance --meeting https://meet.google.com/abc-defg-hij
|
||||
```
|
||||
|
||||
With `--meeting`, `artifacts` and `attendance` use the latest conference record
|
||||
by default. Pass `--all-conference-records` when you want every retained record
|
||||
for that meeting.
|
||||
|
||||
If you already know the conference record id, address it directly:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -439,7 +439,7 @@ describe("google-meet plugin", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("lists Meet artifact metadata for conference records", async () => {
|
||||
it("lists Meet artifact metadata for the latest conference record by default", async () => {
|
||||
const fetchMock = stubMeetArtifactsApi();
|
||||
|
||||
await expect(
|
||||
@@ -483,7 +483,7 @@ describe("google-meet plugin", () => {
|
||||
}
|
||||
const listUrl = requestUrl(listCall[0]);
|
||||
expect(listUrl.searchParams.get("filter")).toBe('space.name = "spaces/abc-defg-hij"');
|
||||
expect(listUrl.searchParams.get("pageSize")).toBe("2");
|
||||
expect(listUrl.searchParams.get("pageSize")).toBe("1");
|
||||
expect(fetchGuardMocks.fetchWithSsrFGuard).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
url: "https://meet.googleapis.com/v2/conferenceRecords/rec-1/smartNotes?pageSize=2",
|
||||
@@ -498,6 +498,28 @@ describe("google-meet plugin", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps all conference records available when requested", async () => {
|
||||
const fetchMock = stubMeetArtifactsApi();
|
||||
|
||||
await fetchGoogleMeetArtifacts({
|
||||
accessToken: "token",
|
||||
meeting: "abc-defg-hij",
|
||||
pageSize: 2,
|
||||
allConferenceRecords: true,
|
||||
});
|
||||
|
||||
const listCall = fetchMock.mock.calls.find(([input]) => {
|
||||
const url = requestUrl(input);
|
||||
return url.pathname === "/v2/conferenceRecords";
|
||||
});
|
||||
if (!listCall) {
|
||||
throw new Error("Expected conferenceRecords.list fetch call");
|
||||
}
|
||||
const listUrl = requestUrl(listCall[0]);
|
||||
expect(listUrl.searchParams.get("pageSize")).toBe("2");
|
||||
expect(listUrl.searchParams.get("filter")).toBe('space.name = "spaces/abc-defg-hij"');
|
||||
});
|
||||
|
||||
it("fetches only the latest Meet conference record for a meeting", async () => {
|
||||
const fetchMock = stubMeetArtifactsApi();
|
||||
|
||||
|
||||
@@ -191,6 +191,12 @@ const GoogleMeetToolSchema = Type.Object({
|
||||
includeTranscriptEntries: Type.Optional(
|
||||
Type.Boolean({ description: "For artifacts, include structured transcript entries" }),
|
||||
),
|
||||
includeAllConferenceRecords: Type.Optional(
|
||||
Type.Boolean({
|
||||
description:
|
||||
"For artifacts or attendance with meeting input, fetch all conference records instead of only the latest.",
|
||||
}),
|
||||
),
|
||||
accessToken: Type.Optional(Type.String({ description: "Access token override" })),
|
||||
refreshToken: Type.Optional(Type.String({ description: "Refresh token override" })),
|
||||
clientId: Type.Optional(Type.String({ description: "OAuth client id override" })),
|
||||
@@ -277,6 +283,7 @@ async function resolveArtifactQueryFromParams(
|
||||
conferenceRecord,
|
||||
pageSize: resolveOptionalPositiveInteger(raw.pageSize),
|
||||
includeTranscriptEntries: raw.includeTranscriptEntries !== false,
|
||||
allConferenceRecords: raw.includeAllConferenceRecords === true,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -424,6 +431,7 @@ export default definePluginEntry({
|
||||
conferenceRecord: resolved.conferenceRecord,
|
||||
pageSize: resolved.pageSize,
|
||||
includeTranscriptEntries: resolved.includeTranscriptEntries,
|
||||
allConferenceRecords: resolved.allConferenceRecords,
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
@@ -445,6 +453,7 @@ export default definePluginEntry({
|
||||
meeting: resolved.meeting,
|
||||
conferenceRecord: resolved.conferenceRecord,
|
||||
pageSize: resolved.pageSize,
|
||||
allConferenceRecords: resolved.allConferenceRecords,
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
@@ -604,6 +613,7 @@ export default definePluginEntry({
|
||||
conferenceRecord: resolved.conferenceRecord,
|
||||
pageSize: resolved.pageSize,
|
||||
includeTranscriptEntries: resolved.includeTranscriptEntries,
|
||||
allConferenceRecords: resolved.allConferenceRecords,
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -615,6 +625,7 @@ export default definePluginEntry({
|
||||
meeting: resolved.meeting,
|
||||
conferenceRecord: resolved.conferenceRecord,
|
||||
pageSize: resolved.pageSize,
|
||||
allConferenceRecords: resolved.allConferenceRecords,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ type MeetArtifactOptions = ResolveSpaceOptions & {
|
||||
conferenceRecord?: string;
|
||||
pageSize?: string;
|
||||
transcriptEntries?: boolean;
|
||||
allConferenceRecords?: boolean;
|
||||
format?: "summary" | "markdown";
|
||||
output?: string;
|
||||
};
|
||||
@@ -445,6 +446,7 @@ function resolveArtifactTokenOptions(
|
||||
expiresAt?: number;
|
||||
pageSize?: number;
|
||||
includeTranscriptEntries?: boolean;
|
||||
allConferenceRecords?: boolean;
|
||||
} {
|
||||
const meeting = options.meeting?.trim() || config.defaults.meeting;
|
||||
const conferenceRecord = options.conferenceRecord?.trim();
|
||||
@@ -463,6 +465,7 @@ function resolveArtifactTokenOptions(
|
||||
expiresAt: parseOptionalNumber(options.expiresAt) ?? config.oauth.expiresAt,
|
||||
pageSize: parseOptionalNumber(options.pageSize),
|
||||
includeTranscriptEntries: options.transcriptEntries !== false,
|
||||
allConferenceRecords: Boolean(options.allConferenceRecords),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1030,6 +1033,7 @@ export function registerGoogleMeetCli(params: {
|
||||
.option("--client-secret <secret>", "OAuth client secret override")
|
||||
.option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds")
|
||||
.option("--page-size <n>", "Max resources per Meet API page")
|
||||
.option("--all-conference-records", "Fetch every conference record for --meeting")
|
||||
.option("--no-transcript-entries", "Skip structured transcript entry lookup")
|
||||
.option("--format <format>", "Output format: summary or markdown", "summary")
|
||||
.option("--output <path>", "Write output to a file instead of stdout")
|
||||
@@ -1043,6 +1047,7 @@ export function registerGoogleMeetCli(params: {
|
||||
conferenceRecord: resolved.conferenceRecord,
|
||||
pageSize: resolved.pageSize,
|
||||
includeTranscriptEntries: resolved.includeTranscriptEntries,
|
||||
allConferenceRecords: resolved.allConferenceRecords,
|
||||
});
|
||||
if (options.json) {
|
||||
await writeCliOutput(
|
||||
@@ -1083,6 +1088,7 @@ export function registerGoogleMeetCli(params: {
|
||||
.option("--client-secret <secret>", "OAuth client secret override")
|
||||
.option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds")
|
||||
.option("--page-size <n>", "Max resources per Meet API page")
|
||||
.option("--all-conference-records", "Fetch every conference record for --meeting")
|
||||
.option("--format <format>", "Output format: summary or markdown", "summary")
|
||||
.option("--output <path>", "Write output to a file instead of stdout")
|
||||
.option("--json", "Print JSON output", false)
|
||||
@@ -1094,6 +1100,7 @@ export function registerGoogleMeetCli(params: {
|
||||
meeting: resolved.meeting,
|
||||
conferenceRecord: resolved.conferenceRecord,
|
||||
pageSize: resolved.pageSize,
|
||||
allConferenceRecords: resolved.allConferenceRecords,
|
||||
});
|
||||
if (options.json) {
|
||||
await writeCliOutput(
|
||||
|
||||
@@ -532,6 +532,7 @@ async function resolveConferenceRecordQuery(params: {
|
||||
meeting?: string;
|
||||
conferenceRecord?: string;
|
||||
pageSize?: number;
|
||||
allConferenceRecords?: boolean;
|
||||
}): Promise<{
|
||||
input?: string;
|
||||
space?: GoogleMeetSpace;
|
||||
@@ -557,7 +558,8 @@ async function resolveConferenceRecordQuery(params: {
|
||||
const conferenceRecords = await listGoogleMeetConferenceRecords({
|
||||
accessToken: params.accessToken,
|
||||
meeting: space.name,
|
||||
pageSize: params.pageSize,
|
||||
pageSize: params.allConferenceRecords ? params.pageSize : 1,
|
||||
maxItems: params.allConferenceRecords ? undefined : 1,
|
||||
});
|
||||
return {
|
||||
input: params.meeting,
|
||||
@@ -572,6 +574,7 @@ export async function fetchGoogleMeetArtifacts(params: {
|
||||
conferenceRecord?: string;
|
||||
pageSize?: number;
|
||||
includeTranscriptEntries?: boolean;
|
||||
allConferenceRecords?: boolean;
|
||||
}): Promise<GoogleMeetArtifactsResult> {
|
||||
const resolved = await resolveConferenceRecordQuery(params);
|
||||
const artifacts = await Promise.all(
|
||||
@@ -652,6 +655,7 @@ export async function fetchGoogleMeetAttendance(params: {
|
||||
meeting?: string;
|
||||
conferenceRecord?: string;
|
||||
pageSize?: number;
|
||||
allConferenceRecords?: boolean;
|
||||
}): Promise<GoogleMeetAttendanceResult> {
|
||||
const resolved = await resolveConferenceRecordQuery(params);
|
||||
const nestedRows = await Promise.all(
|
||||
|
||||
Reference in New Issue
Block a user