arcade-google-docs 3.0.0__py3-none-any.whl → 3.1.1__py3-none-any.whl

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.
@@ -1,8 +1,10 @@
1
1
  from arcade_google_docs.tools import (
2
+ comment_on_document,
2
3
  create_blank_document,
3
4
  create_document_from_text,
4
5
  get_document_by_id,
5
6
  insert_text_at_end_of_document,
7
+ list_document_comments,
6
8
  search_and_retrieve_documents,
7
9
  search_documents,
8
10
  )
@@ -10,6 +12,8 @@ from arcade_google_docs.tools import (
10
12
  __all__ = [
11
13
  "create_blank_document",
12
14
  "create_document_from_text",
15
+ "comment_on_document",
16
+ "list_document_comments",
13
17
  "get_document_by_id",
14
18
  "insert_text_at_end_of_document",
15
19
  "search_and_retrieve_documents",
@@ -1,3 +1,7 @@
1
+ from arcade_google_docs.tools.comment import (
2
+ comment_on_document,
3
+ list_document_comments,
4
+ )
1
5
  from arcade_google_docs.tools.create import (
2
6
  create_blank_document,
3
7
  create_document_from_text,
@@ -13,6 +17,8 @@ __all__ = [
13
17
  "create_blank_document",
14
18
  "create_document_from_text",
15
19
  "get_document_by_id",
20
+ "comment_on_document",
21
+ "list_document_comments",
16
22
  "insert_text_at_end_of_document",
17
23
  "search_and_retrieve_documents",
18
24
  "search_documents",
@@ -0,0 +1,98 @@
1
+ from typing import Annotated
2
+
3
+ from arcade_tdk import ToolContext, tool
4
+ from arcade_tdk.auth import Google
5
+
6
+ from arcade_google_docs.utils import build_drive_service
7
+
8
+
9
+ @tool(
10
+ requires_auth=Google(
11
+ scopes=[
12
+ "https://www.googleapis.com/auth/drive.file",
13
+ ],
14
+ )
15
+ )
16
+ async def comment_on_document(
17
+ context: ToolContext,
18
+ document_id: Annotated[str, "The ID of the document to comment on"],
19
+ comment_text: Annotated[str, "The comment to add to the document"],
20
+ ) -> Annotated[dict, "The comment's ID, documentId, and documentUrl in a dictionary"]:
21
+ """
22
+ Comment on a specific document by its ID.
23
+ """
24
+ drive_service = build_drive_service(context.get_auth_token_or_empty())
25
+
26
+ response = (
27
+ drive_service.comments()
28
+ .create(
29
+ fileId=document_id,
30
+ body={
31
+ "content": comment_text,
32
+ },
33
+ fields="id",
34
+ )
35
+ .execute()
36
+ )
37
+
38
+ return {
39
+ "comment_id": response["id"],
40
+ "document_url": f"https://docs.google.com/document/d/{document_id}",
41
+ }
42
+
43
+
44
+ @tool(
45
+ requires_auth=Google(
46
+ scopes=[
47
+ "https://www.googleapis.com/auth/drive.file",
48
+ ],
49
+ )
50
+ )
51
+ async def list_document_comments(
52
+ context: ToolContext,
53
+ document_id: Annotated[str, "The ID of the document to list comments for"],
54
+ include_deleted: Annotated[
55
+ bool,
56
+ "Whether to include deleted comments in the results. Defaults to False.",
57
+ ] = False,
58
+ ) -> Annotated[
59
+ dict,
60
+ "A dictionary containing the comments",
61
+ ]:
62
+ """
63
+ List all comments on the specified Google Docs document.
64
+ """
65
+ drive_service = build_drive_service(context.get_auth_token_or_empty())
66
+
67
+ comments: list[dict] = []
68
+ params: dict = {
69
+ "fileId": document_id,
70
+ "pageSize": 100,
71
+ "fields": (
72
+ "nextPageToken,comments(id,content,createdTime,modifiedTime,deleted,"
73
+ "author(displayName,emailAddress),replies(id,content,createdTime,modifiedTime,deleted,author(displayName,emailAddress)))"
74
+ ),
75
+ }
76
+ if include_deleted:
77
+ params["includeDeleted"] = True
78
+
79
+ while True:
80
+ results = drive_service.comments().list(**params).execute()
81
+ batch = results.get("comments", [])
82
+ comments.extend(batch)
83
+ next_page_token = results.get("nextPageToken")
84
+ if not next_page_token:
85
+ break
86
+ params["pageToken"] = next_page_token
87
+
88
+ reply_count = 0
89
+ for comment in comments:
90
+ reply_count += len(comment.get("replies", []))
91
+
92
+ return {
93
+ "comments_count": len(comments),
94
+ "replies_count": reply_count,
95
+ "total_discussion_count": len(comments) + reply_count,
96
+ "comments": comments,
97
+ "document_url": f"https://docs.google.com/document/d/{document_id}",
98
+ }
@@ -55,7 +55,9 @@ async def search_documents(
55
55
  ] = False,
56
56
  order_by: Annotated[
57
57
  list[OrderBy] | None,
58
- "Sort order. Defaults to listing the most recently modified documents first",
58
+ "Sort order. Defaults to listing the most recently modified documents first. If "
59
+ "document_contains or document_not_contains is provided, "
60
+ "then the order_by will be ignored.",
59
61
  ] = None,
60
62
  limit: Annotated[int, "The number of documents to list"] = 50,
61
63
  pagination_token: Annotated[
@@ -69,7 +71,12 @@ async def search_documents(
69
71
  """
70
72
  Searches for documents in the user's Google Drive. Excludes documents that are in the trash.
71
73
  """
72
- if order_by is None:
74
+ if document_contains or document_not_contains:
75
+ # Google drive API does not support other order_by values for
76
+ # queries with fullText search (which is used when document_contains
77
+ # or document_not_contains is provided).
78
+ order_by = None
79
+ elif order_by is None:
73
80
  order_by = [OrderBy.MODIFIED_TIME_DESC]
74
81
  elif isinstance(order_by, OrderBy):
75
82
  order_by = [order_by]
@@ -34,7 +34,7 @@ def build_drive_service(auth_token: str | None) -> Resource: # type: ignore[no-
34
34
  def build_files_list_params(
35
35
  mime_type: str,
36
36
  page_size: int,
37
- order_by: list[OrderBy],
37
+ order_by: list[OrderBy] | None,
38
38
  pagination_token: str | None,
39
39
  include_shared_drives: bool,
40
40
  search_only_in_shared_drive_id: str | None,
@@ -51,7 +51,7 @@ def build_files_list_params(
51
51
  params = {
52
52
  "q": query,
53
53
  "pageSize": page_size,
54
- "orderBy": ",".join([item.value for item in order_by]),
54
+ "orderBy": ",".join([item.value for item in order_by]) if order_by else None,
55
55
  "pageToken": pagination_token,
56
56
  }
57
57
 
@@ -102,8 +102,8 @@ def build_files_list_query(
102
102
  name_not_contains = keyword.replace("'", "\\'")
103
103
  full_text_not_contains = keyword.replace("'", "\\'")
104
104
  keyword_query = (
105
- f"(name not contains '{name_not_contains}' and "
106
- f"fullText not contains '{full_text_not_contains}')"
105
+ f"(not (name contains '{name_not_contains}' or "
106
+ f"fullText contains '{full_text_not_contains}'))"
107
107
  )
108
108
  query.append(keyword_query)
109
109
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arcade_google_docs
3
- Version: 3.0.0
3
+ Version: 3.1.1
4
4
  Summary: Arcade.dev LLM tools for Google Docs
5
5
  Author-email: Arcade <dev@arcade.dev>
6
6
  License: Proprietary - Arcade Software License Agreement v1.0
@@ -1,16 +1,17 @@
1
- arcade_google_docs/__init__.py,sha256=WxIJBwkBmVeHfvgQ9E8eZy28SVqSkBlbZPhgFWhVd7o,418
1
+ arcade_google_docs/__init__.py,sha256=J3c3lEuqb86UE5zScpv7Gd4TltmzTUq_tWyA2Ff0gmI,528
2
2
  arcade_google_docs/decorators.py,sha256=5ONZ3vS2lZBmog5c1TcuWjyPDeftBPAJ7vXyLjSPFRk,751
3
3
  arcade_google_docs/doc_to_html.py,sha256=6RTpzRSrazNa6AndLZhA20wgVDzZuHUqpu3WAkAsbjQ,3146
4
4
  arcade_google_docs/doc_to_markdown.py,sha256=eT-sc6ruxN8nEtUm9mBHFOWXajEBTTXkxsn6XsLHIxo,2020
5
5
  arcade_google_docs/enum.py,sha256=vFJWPe1JPG6I9xqdVVvuaEeen4LvvtJxax1sDYeh4UU,3421
6
6
  arcade_google_docs/file_picker.py,sha256=kGfUVfH5QVlIW1sL-_gAwPokt7TwVEcPk3Vnk53GKUE,2005
7
7
  arcade_google_docs/templates.py,sha256=pxbdMj57eV3-ImW3CixDWscpVKS94Z8nTNyTxDhUfGY,283
8
- arcade_google_docs/utils.py,sha256=Eku4b1olLcXfQ20liE9m3iPWvy60VA62tQ8TFwRKn94,3722
9
- arcade_google_docs/tools/__init__.py,sha256=f0d7ZRXCqgODDBkKtNhvHzsqs_GuZ97fe0dpjBcXKq8,548
8
+ arcade_google_docs/utils.py,sha256=XMgKcWPWKy8SbH3y2eCil01hssHhUgYxVrwXyvHEU4A,3748
9
+ arcade_google_docs/tools/__init__.py,sha256=vtn_NKrYwgWsdgcDYBY4t8m_XF73jB4j7zrpt-NC-dI,707
10
+ arcade_google_docs/tools/comment.py,sha256=Qm5NHdNHONs3j4gqbZ7Fw9NrTVBb_mZ-th1X-z2IoLM,2836
10
11
  arcade_google_docs/tools/create.py,sha256=AuYy8yMGscrxAdLJQX0WiisGHCTufSlaRu_QGMMKQmM,2764
11
12
  arcade_google_docs/tools/get.py,sha256=2wi9ZF9s_57mMbIGgsqr53Fr0AJyrYVOQ11x7nAyk8Y,1339
12
- arcade_google_docs/tools/search.py,sha256=_CaEs1A_qGToNPeuGQ2yN3phGtPD7fFQbW3UqZr_qpg,8617
13
+ arcade_google_docs/tools/search.py,sha256=6wMacfbO3Pzxu30I-otaFIA5b9b9AKcIkgHr8M9QXLo,9007
13
14
  arcade_google_docs/tools/update.py,sha256=9SvffQIHnmYiEgyE1VrhXG2aHb0hIfWYPzPLc4nTdKI,2030
14
- arcade_google_docs-3.0.0.dist-info/METADATA,sha256=cO6YZ4UaKm2dqy0SNN1PVTIb7m0OCM1UcfHNFQaRal8,1097
15
- arcade_google_docs-3.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
- arcade_google_docs-3.0.0.dist-info/RECORD,,
15
+ arcade_google_docs-3.1.1.dist-info/METADATA,sha256=reKLvMCf-wM_GLIExvxUYXYUiCxYxoRXqN9vpiNa-24,1097
16
+ arcade_google_docs-3.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
17
+ arcade_google_docs-3.1.1.dist-info/RECORD,,