better-notion 1.5.5__py3-none-any.whl → 1.6.0__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.
@@ -21,6 +21,7 @@ def format_response(
21
21
  data: Any = None,
22
22
  error: dict[str, Any] | None = None,
23
23
  rate_limit: dict[str, Any] | None = None,
24
+ meta: dict[str, Any] | None = None,
24
25
  ) -> str:
25
26
  """
26
27
  Format CLI response as JSON.
@@ -33,6 +34,7 @@ def format_response(
33
34
  data: Response data (for successful operations)
34
35
  error: Error information (for failed operations)
35
36
  rate_limit: Rate limit information from API response
37
+ meta: Additional metadata for AI agents (context, next_steps, etc.)
36
38
 
37
39
  Returns:
38
40
  JSON-formatted response string
@@ -50,6 +52,28 @@ def format_response(
50
52
  }
51
53
  }
52
54
 
55
+ Response with AI metadata:
56
+ >>> format_response(
57
+ ... success=True,
58
+ ... data={"workspace_id": "abc123"},
59
+ ... meta={
60
+ ... "command": "agents init",
61
+ ... "context": {"state": "initialized"},
62
+ ... "next_steps": [{"command": "agents info"}]
63
+ ... }
64
+ ... )
65
+ {
66
+ "success": true,
67
+ "data": {"workspace_id": "abc123"},
68
+ "meta": {
69
+ "version": "0.4.0",
70
+ "timestamp": "2025-01-26T10:00:00Z",
71
+ "command": "agents init",
72
+ "context": {"state": "initialized"},
73
+ "next_steps": [{"command": "agents info"}]
74
+ }
75
+ }
76
+
53
77
  Error response:
54
78
  >>> format_response(
55
79
  ... success=False,
@@ -58,11 +82,7 @@ def format_response(
58
82
  {
59
83
  "success": false,
60
84
  "error": {"code": "NOT_FOUND", "message": "Page not found", "retry": false},
61
- "meta": {
62
- "version": "0.4.0",
63
- "timestamp": "2025-01-26T10:00:00Z",
64
- "rate_limit": {"remaining": null, "reset_at": null}
65
- }
85
+ "meta": {...}
66
86
  }
67
87
  """
68
88
  response: dict[str, Any] = {
@@ -81,6 +101,10 @@ def format_response(
81
101
  if error is not None:
82
102
  response["error"] = error
83
103
 
104
+ # Add custom metadata for AI agents
105
+ if meta:
106
+ response["meta"].update(meta)
107
+
84
108
  return json.dumps(response, indent=2)
85
109
 
86
110
 
@@ -90,6 +114,7 @@ def format_error(
90
114
  *,
91
115
  retry: bool = False,
92
116
  details: dict[str, Any] | None = None,
117
+ meta: dict[str, Any] | None = None,
93
118
  ) -> str:
94
119
  """
95
120
  Format an error response.
@@ -101,6 +126,7 @@ def format_error(
101
126
  message: Human-readable error message
102
127
  retry: Whether the operation should be retried
103
128
  details: Additional error details
129
+ meta: Additional metadata for AI agents (recovery strategies, etc.)
104
130
 
105
131
  Returns:
106
132
  JSON-formatted error response string
@@ -116,6 +142,20 @@ def format_error(
116
142
  },
117
143
  "meta": {...}
118
144
  }
145
+
146
+ With error recovery metadata:
147
+ >>> format_error(
148
+ ... "WORKSPACE_EXISTS",
149
+ ... "Workspace already initialized",
150
+ ... meta={
151
+ ... "error_recovery": {
152
+ ... "solutions": [
153
+ ... {"flag": "--skip", "action": "use_existing"},
154
+ ... {"flag": "--reset", "action": "recreate"}
155
+ ... ]
156
+ ... }
157
+ ... }
158
+ ... )
119
159
  """
120
160
  error_info: dict[str, Any] = {
121
161
  "code": code,
@@ -126,10 +166,15 @@ def format_error(
126
166
  if details:
127
167
  error_info["details"] = details
128
168
 
129
- return format_response(success=False, error=error_info)
169
+ return format_response(success=False, error=error_info, meta=meta)
130
170
 
131
171
 
132
- def format_success(data: Any, *, rate_limit: dict[str, Any] | None = None) -> str:
172
+ def format_success(
173
+ data: Any,
174
+ *,
175
+ rate_limit: dict[str, Any] | None = None,
176
+ meta: dict[str, Any] | None = None,
177
+ ) -> str:
133
178
  """
134
179
  Format a success response.
135
180
 
@@ -138,6 +183,7 @@ def format_success(data: Any, *, rate_limit: dict[str, Any] | None = None) -> st
138
183
  Args:
139
184
  data: Response data
140
185
  rate_limit: Rate limit information from API response
186
+ meta: Additional metadata for AI agents (context, next_steps, etc.)
141
187
 
142
188
  Returns:
143
189
  JSON-formatted success response string
@@ -149,5 +195,15 @@ def format_success(data: Any, *, rate_limit: dict[str, Any] | None = None) -> st
149
195
  "data": {"id": "page_123", "title": "My Page"},
150
196
  "meta": {...}
151
197
  }
198
+
199
+ With contextual metadata:
200
+ >>> format_success(
201
+ ... {"workspace_id": "abc123"},
202
+ ... meta={
203
+ ... "command": "agents init",
204
+ ... "context": {"state": "initialized"},
205
+ ... "next_steps": [{"command": "agents info"}]
206
+ ... }
207
+ ... )
152
208
  """
153
- return format_response(success=True, data=data, rate_limit=rate_limit)
209
+ return format_response(success=True, data=data, rate_limit=rate_limit, meta=meta)
@@ -162,6 +162,29 @@ class AgentsPlugin(CombinedPluginInterface):
162
162
  "workspace_id": existing.get("workspace_id"),
163
163
  "databases_found": len(database_ids),
164
164
  "database_ids": database_ids,
165
+ },
166
+ meta={
167
+ "command": "agents init",
168
+ "context": {
169
+ "state": "already_initialized",
170
+ "description": "Agents workspace already exists in this page",
171
+ },
172
+ "next_steps": [
173
+ {
174
+ "action": "query_tasks",
175
+ "command": f"notion databases query --database {database_ids.get('tasks', 'TASKS_DB_ID')}",
176
+ "purpose": "List all tasks in workspace",
177
+ },
178
+ {
179
+ "action": "create_task",
180
+ "description": "To create a new task, use pages create with Version relation",
181
+ },
182
+ ],
183
+ "capabilities": [
184
+ "create_tasks",
185
+ "manage_versions",
186
+ "track_projects",
187
+ ],
165
188
  }
166
189
  )
167
190
  except Exception:
@@ -181,6 +204,48 @@ class AgentsPlugin(CombinedPluginInterface):
181
204
  "workspace_id": initializer._workspace_id,
182
205
  "databases_created": len(database_ids),
183
206
  "database_ids": database_ids,
207
+ },
208
+ meta={
209
+ "command": "agents init",
210
+ "context": {
211
+ "state": "initialized",
212
+ "description": "Agents workspace ready for task management",
213
+ "workspace_name": workspace_name,
214
+ },
215
+ "next_steps": [
216
+ {
217
+ "command": "agents info --parent-page " + parent_page_id,
218
+ "purpose": "View workspace status and database IDs",
219
+ "when": "To verify workspace setup",
220
+ },
221
+ {
222
+ "command": f"notion databases query --database {database_ids.get('tasks', 'TASKS_DB_ID')}",
223
+ "purpose": "List all tasks in workspace",
224
+ "when": "To see existing tasks",
225
+ },
226
+ ],
227
+ "capabilities": [
228
+ "create_tasks",
229
+ "manage_versions",
230
+ "track_projects",
231
+ "manage_ideas",
232
+ "track_incidents",
233
+ ],
234
+ "common_workflows": [
235
+ {
236
+ "name": "create_organization",
237
+ "description": "Create a new organization in the workspace",
238
+ "command": f"notion pages create --parent {database_ids.get('organizations', 'ORGANIZATIONS_DB_ID')} --title 'Organization Name'",
239
+ },
240
+ {
241
+ "name": "create_task",
242
+ "description": "Create a task in the workspace",
243
+ "steps": [
244
+ f"agents info --parent-page {parent_page_id}",
245
+ f"notion pages create --parent {database_ids.get('tasks', 'TASKS_DB_ID')} --title 'Task Name' --properties '{{\"Status\": \"Todo\", \"Version\": \"VERSION_ID\"}}'",
246
+ ],
247
+ },
248
+ ],
184
249
  }
185
250
  )
186
251
 
@@ -234,6 +299,32 @@ class AgentsPlugin(CombinedPluginInterface):
234
299
  "databases_count": len(database_ids),
235
300
  "database_ids": database_ids,
236
301
  "detection_method": existing.get("detection_method", "config_file"),
302
+ },
303
+ meta={
304
+ "command": "agents info",
305
+ "context": {
306
+ "state": "workspace_found",
307
+ "description": "Workspace is ready for use",
308
+ },
309
+ "available_databases": list(database_ids.keys()),
310
+ "next_steps": [
311
+ {
312
+ "action": "query_tasks",
313
+ "command": f"notion databases query --database {database_ids.get('tasks', 'TASKS_DB_ID')}",
314
+ "purpose": "List all tasks in workspace",
315
+ },
316
+ {
317
+ "action": "create_task",
318
+ "command": f"notion pages create --parent {database_ids.get('tasks', 'TASKS_DB_ID')} --title 'Task Name' --properties '{{\"Status\": \"Todo\"}}'",
319
+ "purpose": "Create a new task",
320
+ "note": "Make sure to set Version relation",
321
+ },
322
+ {
323
+ "action": "list_projects",
324
+ "command": f"notion databases query --database {database_ids.get('projects', 'PROJECTS_DB_ID')}",
325
+ "purpose": "List all projects",
326
+ },
327
+ ],
237
328
  }
238
329
  )
239
330
  else:
@@ -256,6 +347,25 @@ class AgentsPlugin(CombinedPluginInterface):
256
347
  "parent_title": page.title,
257
348
  "workspace_initialized": False,
258
349
  "other_databases": len(databases_in_page),
350
+ },
351
+ meta={
352
+ "command": "agents info",
353
+ "context": {
354
+ "state": "no_workspace",
355
+ "description": "No agents workspace detected in this page",
356
+ },
357
+ "next_steps": [
358
+ {
359
+ "action": "initialize_workspace",
360
+ "command": f"notion agents init --parent-page {parent_page_id}",
361
+ "purpose": "Initialize a new agents workspace",
362
+ "note": "This will create 8 databases for workflow management",
363
+ },
364
+ ],
365
+ "error_recovery": {
366
+ "message": "Workspace must be initialized before managing tasks",
367
+ "solution": "Run 'agents init' to create the workspace",
368
+ },
259
369
  }
260
370
  )
261
371
 
@@ -266,6 +376,52 @@ class AgentsPlugin(CombinedPluginInterface):
266
376
  result = asyncio.run(_info())
267
377
  typer.echo(result)
268
378
 
379
+ @agents_app.command("schema")
380
+ def agents_schema(
381
+ format: str = typer.Option(
382
+ "json",
383
+ "--format",
384
+ "-f",
385
+ help="Output format (json, yaml, pretty)",
386
+ ),
387
+ ) -> None:
388
+ """
389
+ Get agents plugin schema for AI agents.
390
+
391
+ Returns comprehensive documentation about the agents system including:
392
+ - Concepts (workspace, task, project, version)
393
+ - Workflows (initialize, create_task, query_tasks)
394
+ - Commands documentation (init, info)
395
+ - Best practices and usage examples
396
+
397
+ Example:
398
+ $ notion agents schema
399
+ $ notion agents schema --format json
400
+ $ notion agents schema --format yaml
401
+ $ notion agents schema --format pretty
402
+ """
403
+ from better_notion.plugins.official.agents_schema import AGENTS_SCHEMA
404
+ from better_notion._cli.docs.formatters import (
405
+ format_schema_json,
406
+ format_schema_yaml,
407
+ format_schema_pretty,
408
+ )
409
+
410
+ if format == "json":
411
+ typer.echo(format_schema_json(AGENTS_SCHEMA))
412
+ elif format == "yaml":
413
+ typer.echo(format_schema_yaml(AGENTS_SCHEMA))
414
+ elif format == "pretty":
415
+ typer.echo(format_schema_pretty(AGENTS_SCHEMA))
416
+ else:
417
+ result = format_error(
418
+ "INVALID_FORMAT",
419
+ f"Unknown format: {format}. Supported formats: json, yaml, pretty",
420
+ retry=False,
421
+ )
422
+ typer.echo(result)
423
+ raise typer.Exit(code=1)
424
+
269
425
  @agents_app.command("init-project")
270
426
  def init_project(
271
427
  project_id: str = typer.Option(