deepmate 0.1.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.
- deepmate/__init__.py +5 -0
- deepmate/__main__.py +5 -0
- deepmate/activity/__init__.py +10 -0
- deepmate/activity/journal.py +269 -0
- deepmate/app/__init__.py +47 -0
- deepmate/app/settings.py +1620 -0
- deepmate/behavior/__init__.py +27 -0
- deepmate/behavior/rules.py +622 -0
- deepmate/behavior/runtime.py +406 -0
- deepmate/builtin_skills/architecture-advisor/SKILL.md +36 -0
- deepmate/builtin_skills/data-advisor/SKILL.md +36 -0
- deepmate/builtin_skills/delivery-advisor/SKILL.md +35 -0
- deepmate/builtin_skills/html-report/SKILL.md +53 -0
- deepmate/builtin_skills/prd/SKILL.md +63 -0
- deepmate/builtin_skills/product-advisor/SKILL.md +35 -0
- deepmate/builtin_skills/research-advisor/SKILL.md +36 -0
- deepmate/builtin_skills/research-brief/SKILL.md +60 -0
- deepmate/builtin_skills/tech-diagram/SKILL.md +143 -0
- deepmate/builtin_skills/technical-architecture/SKILL.md +63 -0
- deepmate/builtin_skills/ux-advisor/SKILL.md +36 -0
- deepmate/capabilities/__init__.py +47 -0
- deepmate/capabilities/maintenance.py +357 -0
- deepmate/capabilities/state.py +522 -0
- deepmate/capabilities/surface.py +137 -0
- deepmate/channels/__init__.py +7 -0
- deepmate/channels/checkpointing.py +299 -0
- deepmate/channels/cli.py +6626 -0
- deepmate/channels/interactive.py +1408 -0
- deepmate/channels/remote/__init__.py +13 -0
- deepmate/channels/remote/binding.py +327 -0
- deepmate/channels/session_lineage.py +289 -0
- deepmate/channels/session_maintenance.py +1191 -0
- deepmate/channels/skill_view.py +330 -0
- deepmate/channels/tui/__init__.py +21 -0
- deepmate/channels/tui/app.py +5604 -0
- deepmate/channels/tui/bridge.py +1137 -0
- deepmate/channels/tui/commands.py +1421 -0
- deepmate/channels/tui/files.py +536 -0
- deepmate/channels/tui/formatters.py +654 -0
- deepmate/channels/tui/render.py +526 -0
- deepmate/channels/tui/state.py +336 -0
- deepmate/channels/tui/status.py +398 -0
- deepmate/channels/wecom/__init__.py +15 -0
- deepmate/channels/wecom/channel.py +1798 -0
- deepmate/channels/wecom/client.py +251 -0
- deepmate/context/__init__.py +27 -0
- deepmate/context/builder.py +538 -0
- deepmate/context/snapshot.py +103 -0
- deepmate/cron/__init__.py +14 -0
- deepmate/cron/commands.py +262 -0
- deepmate/cron/model.py +309 -0
- deepmate/cron/planner.py +335 -0
- deepmate/cron/runner.py +323 -0
- deepmate/cron/schedule.py +113 -0
- deepmate/cron/store.py +187 -0
- deepmate/domain/__init__.py +24 -0
- deepmate/domain/approval.py +18 -0
- deepmate/domain/artifact.py +17 -0
- deepmate/domain/capability.py +37 -0
- deepmate/domain/errors.py +18 -0
- deepmate/domain/event.py +18 -0
- deepmate/domain/memory.py +34 -0
- deepmate/domain/message.py +26 -0
- deepmate/domain/profile.py +19 -0
- deepmate/evolution/__init__.py +89 -0
- deepmate/evolution/behavior.py +227 -0
- deepmate/evolution/changes.py +379 -0
- deepmate/evolution/evidence_mining.py +358 -0
- deepmate/evolution/failure_patterns.py +356 -0
- deepmate/evolution/generated_skills.py +507 -0
- deepmate/evolution/maintenance.py +892 -0
- deepmate/foundation/__init__.py +20 -0
- deepmate/foundation/path.py +15 -0
- deepmate/foundation/text.py +67 -0
- deepmate/foundation/time.py +18 -0
- deepmate/foundation/tool_schema.py +185 -0
- deepmate/local/__init__.py +40 -0
- deepmate/local/ollama.py +648 -0
- deepmate/local/presets.py +201 -0
- deepmate/local/state.py +161 -0
- deepmate/mcp/__init__.py +65 -0
- deepmate/mcp/catalog.py +340 -0
- deepmate/mcp/client.py +859 -0
- deepmate/mcp/discovery.py +138 -0
- deepmate/mcp/executor.py +433 -0
- deepmate/mcp/output_policy.py +262 -0
- deepmate/mcp/spec.py +161 -0
- deepmate/mcp/state.py +361 -0
- deepmate/memory/__init__.py +63 -0
- deepmate/memory/curator.py +715 -0
- deepmate/memory/extractor.py +317 -0
- deepmate/memory/maintenance.py +787 -0
- deepmate/memory/manager.py +459 -0
- deepmate/pet/__init__.py +49 -0
- deepmate/pet/copy.py +159 -0
- deepmate/pet/electron_host.py +151 -0
- deepmate/pet/events.py +328 -0
- deepmate/pet/learning.py +235 -0
- deepmate/pet/pets.py +224 -0
- deepmate/pet/policy.py +39 -0
- deepmate/pet/service.py +651 -0
- deepmate/pet/state.py +368 -0
- deepmate/preview_deploy/__init__.py +14 -0
- deepmate/preview_deploy/commands.py +996 -0
- deepmate/preview_deploy/health.py +37 -0
- deepmate/preview_deploy/state.py +197 -0
- deepmate/preview_deploy/supervisor.py +242 -0
- deepmate/preview_deploy/tunnel.py +465 -0
- deepmate/providers/__init__.py +39 -0
- deepmate/providers/base.py +15 -0
- deepmate/providers/chat_completions.py +933 -0
- deepmate/providers/messages.py +213 -0
- deepmate/providers/usage.py +20 -0
- deepmate/qa/__init__.py +33 -0
- deepmate/qa/commands.py +349 -0
- deepmate/qa/context.py +82 -0
- deepmate/qa/discovery.py +231 -0
- deepmate/qa/engine.py +177 -0
- deepmate/qa/model.py +255 -0
- deepmate/qa/planner.py +556 -0
- deepmate/qa/report.py +165 -0
- deepmate/qa/runner.py +237 -0
- deepmate/qa/store.py +306 -0
- deepmate/runtime/__init__.py +261 -0
- deepmate/runtime/activation.py +118 -0
- deepmate/runtime/agent_loop.py +3048 -0
- deepmate/runtime/checkpoint_update.py +384 -0
- deepmate/runtime/conversation_budget.py +352 -0
- deepmate/runtime/cost_summary.py +125 -0
- deepmate/runtime/delivery_review.py +336 -0
- deepmate/runtime/diagnostics.py +368 -0
- deepmate/runtime/followup.py +89 -0
- deepmate/runtime/hooks/__init__.py +76 -0
- deepmate/runtime/hooks/diagnostics.py +141 -0
- deepmate/runtime/hooks/loader.py +820 -0
- deepmate/runtime/hooks/manager.py +252 -0
- deepmate/runtime/hooks/matcher.py +106 -0
- deepmate/runtime/hooks/registry.py +150 -0
- deepmate/runtime/hooks/signals.py +229 -0
- deepmate/runtime/hooks/trust.py +123 -0
- deepmate/runtime/hooks/types.py +279 -0
- deepmate/runtime/loop_guard.py +226 -0
- deepmate/runtime/model_request.py +149 -0
- deepmate/runtime/prefix_cache.py +119 -0
- deepmate/runtime/process_env.py +30 -0
- deepmate/runtime/safety.py +677 -0
- deepmate/runtime/sandbox.py +422 -0
- deepmate/runtime/session_runtime.py +573 -0
- deepmate/runtime/session_summary.py +669 -0
- deepmate/runtime/tool_executor.py +165 -0
- deepmate/runtime/tool_output_compaction.py +1358 -0
- deepmate/runtime/tool_policy.py +233 -0
- deepmate/runtime/tool_repair.py +661 -0
- deepmate/runtime/wakelock.py +211 -0
- deepmate/skills/__init__.py +54 -0
- deepmate/skills/catalog.py +134 -0
- deepmate/skills/install.py +1644 -0
- deepmate/skills/loader.py +56 -0
- deepmate/skills/manifest.py +205 -0
- deepmate/skills/metadata.py +45 -0
- deepmate/skills/skill_file.py +173 -0
- deepmate/storage/__init__.py +68 -0
- deepmate/storage/atomic.py +89 -0
- deepmate/storage/checkpoint_store.py +815 -0
- deepmate/storage/jsonl.py +89 -0
- deepmate/storage/session_store.py +983 -0
- deepmate/storage/tool_output_store.py +237 -0
- deepmate/subagents/__init__.py +56 -0
- deepmate/subagents/orchestration.py +782 -0
- deepmate/subagents/runtime.py +595 -0
- deepmate/subagents/store.py +373 -0
- deepmate/subagents/tool_executor.py +1388 -0
- deepmate/subagents/types.py +129 -0
- deepmate/subagents/verification.py +220 -0
- deepmate/tasks/__init__.py +77 -0
- deepmate/tasks/command.py +71 -0
- deepmate/tasks/execute.py +381 -0
- deepmate/tasks/json_helpers.py +22 -0
- deepmate/tasks/render.py +293 -0
- deepmate/tasks/session.py +172 -0
- deepmate/tasks/store.py +465 -0
- deepmate/tasks/update.py +524 -0
- deepmate/tools/__init__.py +148 -0
- deepmate/tools/artifacts.py +627 -0
- deepmate/tools/browser.py +1670 -0
- deepmate/tools/computer.py +1456 -0
- deepmate/tools/diagrams.py +1123 -0
- deepmate/tools/documents.py +799 -0
- deepmate/tools/filesystem.py +665 -0
- deepmate/tools/lsp.py +661 -0
- deepmate/tools/mcp_loader.py +168 -0
- deepmate/tools/registry.py +91 -0
- deepmate/tools/reports.py +737 -0
- deepmate/tools/search.py +438 -0
- deepmate/tools/shell.py +264 -0
- deepmate/tools/skill_installer.py +1101 -0
- deepmate/tools/skill_loader.py +172 -0
- deepmate/tools/svg_security.py +17 -0
- deepmate/tools/tool_output.py +177 -0
- deepmate/tools/url_safety.py +94 -0
- deepmate/tools/web.py +682 -0
- deepmate/trace/__init__.py +38 -0
- deepmate/trace/exporter.py +93 -0
- deepmate/trace/otel.py +163 -0
- deepmate/trace/recorder.py +116 -0
- deepmate/trace/schema.py +134 -0
- deepmate/trace/semantic.py +225 -0
- deepmate/trace/sinks.py +19 -0
- deepmate-0.1.0.dist-info/METADATA +231 -0
- deepmate-0.1.0.dist-info/RECORD +214 -0
- deepmate-0.1.0.dist-info/WHEEL +5 -0
- deepmate-0.1.0.dist-info/entry_points.txt +2 -0
- deepmate-0.1.0.dist-info/licenses/LICENSE +21 -0
- deepmate-0.1.0.dist-info/top_level.txt +1 -0
deepmate/__init__.py
ADDED
deepmate/__main__.py
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"""Daily activity journal for human-readable session handoff."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass(frozen=True, slots=True)
|
|
11
|
+
class ActivityEntry:
|
|
12
|
+
"""One activity checkpoint written to a daily note."""
|
|
13
|
+
|
|
14
|
+
timestamp: str
|
|
15
|
+
event: str
|
|
16
|
+
status: str
|
|
17
|
+
title: str
|
|
18
|
+
summary: str
|
|
19
|
+
session_id: str
|
|
20
|
+
session_title: str
|
|
21
|
+
profile: str
|
|
22
|
+
workspace: str
|
|
23
|
+
summary_id: str = ""
|
|
24
|
+
covered_until_sequence: int = 0
|
|
25
|
+
transcript_path: str = ""
|
|
26
|
+
session_summary_path: str = ""
|
|
27
|
+
trace_path: str = ""
|
|
28
|
+
refs: tuple[str, ...] = field(default_factory=tuple)
|
|
29
|
+
|
|
30
|
+
def is_ready(self) -> bool:
|
|
31
|
+
"""Return whether the entry has enough metadata to be useful."""
|
|
32
|
+
return bool(
|
|
33
|
+
_date_from_timestamp(self.timestamp)
|
|
34
|
+
and self.event.strip()
|
|
35
|
+
and self.status.strip()
|
|
36
|
+
and self.title.strip()
|
|
37
|
+
and self.session_id.strip()
|
|
38
|
+
and self.profile.strip()
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
def local_date(self) -> str:
|
|
42
|
+
"""Return the YYYY-MM-DD date part used for the daily note filename."""
|
|
43
|
+
date = _date_from_timestamp(self.timestamp)
|
|
44
|
+
if not date:
|
|
45
|
+
raise ValueError("activity timestamp must start with YYYY-MM-DD")
|
|
46
|
+
return date
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ActivityStore:
|
|
50
|
+
"""Append human-readable activity entries under one profile activity root."""
|
|
51
|
+
|
|
52
|
+
def __init__(self, root: str | Path) -> None:
|
|
53
|
+
self.root = Path(root)
|
|
54
|
+
|
|
55
|
+
def daily_path(self, local_date: str) -> Path:
|
|
56
|
+
"""Return the daily note path for YYYY-MM-DD."""
|
|
57
|
+
date = _validated_date(local_date)
|
|
58
|
+
return self.root / "daily" / f"{date}.md"
|
|
59
|
+
|
|
60
|
+
def monthly_summary_path(self, month: str) -> Path:
|
|
61
|
+
"""Return the future monthly summary path for YYYY-MM."""
|
|
62
|
+
clean_month = _validated_month(month)
|
|
63
|
+
return self.root / "summaries" / f"{clean_month}.md"
|
|
64
|
+
|
|
65
|
+
def list_daily_dates(self, month: str) -> tuple[str, ...]:
|
|
66
|
+
"""Return YYYY-MM-DD dates that have daily notes for a month."""
|
|
67
|
+
clean_month = _validated_month(month)
|
|
68
|
+
directory = self.root / "daily"
|
|
69
|
+
if not directory.exists():
|
|
70
|
+
return ()
|
|
71
|
+
dates = [
|
|
72
|
+
path.stem
|
|
73
|
+
for path in directory.glob(f"{clean_month}-*.md")
|
|
74
|
+
if _date_from_timestamp(path.stem)
|
|
75
|
+
]
|
|
76
|
+
return tuple(sorted(dates))
|
|
77
|
+
|
|
78
|
+
def append_daily_entry(self, entry: ActivityEntry) -> Path:
|
|
79
|
+
"""Append one entry to the matching daily note and return its path."""
|
|
80
|
+
if not entry.is_ready():
|
|
81
|
+
raise ValueError("activity entry is not ready")
|
|
82
|
+
path = self.daily_path(entry.local_date())
|
|
83
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
84
|
+
existing = path.read_text(encoding="utf-8") if path.exists() else ""
|
|
85
|
+
with path.open("a", encoding="utf-8") as file:
|
|
86
|
+
if not existing.strip():
|
|
87
|
+
file.write(f"# Activity Note - {entry.local_date()}\n")
|
|
88
|
+
elif not existing.endswith("\n"):
|
|
89
|
+
file.write("\n")
|
|
90
|
+
file.write("\n")
|
|
91
|
+
file.write(_render_entry(entry))
|
|
92
|
+
return path
|
|
93
|
+
|
|
94
|
+
def upsert_monthly_summary_entry(
|
|
95
|
+
self,
|
|
96
|
+
local_date: str,
|
|
97
|
+
summary: str,
|
|
98
|
+
highlights: tuple[str, ...] = (),
|
|
99
|
+
next_steps: tuple[str, ...] = (),
|
|
100
|
+
refs: tuple[str, ...] = (),
|
|
101
|
+
) -> Path:
|
|
102
|
+
"""Create or replace one date section in the monthly summary."""
|
|
103
|
+
date = _validated_date(local_date)
|
|
104
|
+
month = date[:7]
|
|
105
|
+
path = self.monthly_summary_path(month)
|
|
106
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
107
|
+
existing = path.read_text(encoding="utf-8") if path.exists() else ""
|
|
108
|
+
section = _render_monthly_summary_entry(
|
|
109
|
+
local_date=date,
|
|
110
|
+
summary=summary,
|
|
111
|
+
highlights=highlights,
|
|
112
|
+
next_steps=next_steps,
|
|
113
|
+
refs=refs,
|
|
114
|
+
)
|
|
115
|
+
content = _upsert_markdown_section(
|
|
116
|
+
existing=existing,
|
|
117
|
+
title=f"# Activity Summary - {month}",
|
|
118
|
+
section_heading=f"## {date}",
|
|
119
|
+
section=section,
|
|
120
|
+
)
|
|
121
|
+
path.write_text(content, encoding="utf-8")
|
|
122
|
+
return path
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def preview_activity_text(text: str, limit: int = 500) -> str:
|
|
126
|
+
"""Return a compact single-line preview for activity notes."""
|
|
127
|
+
value = " ".join(text.split())
|
|
128
|
+
if len(value) <= limit:
|
|
129
|
+
return value
|
|
130
|
+
return value[: limit - 3].rstrip() + "..."
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def _render_entry(entry: ActivityEntry) -> str:
|
|
134
|
+
lines = [
|
|
135
|
+
f"## {_time_from_timestamp(entry.timestamp)} - {entry.title.strip()}",
|
|
136
|
+
"",
|
|
137
|
+
f"- event: {entry.event.strip()}",
|
|
138
|
+
f"- status: {entry.status.strip()}",
|
|
139
|
+
f"- session_id: {entry.session_id.strip()}",
|
|
140
|
+
f"- session_title: {preview_activity_text(entry.session_title, 160)}",
|
|
141
|
+
f"- profile: {entry.profile.strip()}",
|
|
142
|
+
]
|
|
143
|
+
if entry.workspace.strip():
|
|
144
|
+
lines.append(f"- workspace: {entry.workspace.strip()}")
|
|
145
|
+
summary = preview_activity_text(entry.summary, 700)
|
|
146
|
+
if summary:
|
|
147
|
+
lines.append(f"- summary: {summary}")
|
|
148
|
+
if entry.summary_id.strip():
|
|
149
|
+
lines.append(f"- summary_id: {entry.summary_id.strip()}")
|
|
150
|
+
if entry.covered_until_sequence > 0:
|
|
151
|
+
lines.append(f"- covered_until_sequence: {entry.covered_until_sequence}")
|
|
152
|
+
sources = _source_lines(entry)
|
|
153
|
+
if sources:
|
|
154
|
+
lines.append("- sources:")
|
|
155
|
+
lines.extend(f" - {source}" for source in sources)
|
|
156
|
+
refs = tuple(ref.strip() for ref in entry.refs if ref.strip())
|
|
157
|
+
if refs:
|
|
158
|
+
lines.append("- refs:")
|
|
159
|
+
lines.extend(f" - {ref}" for ref in refs)
|
|
160
|
+
lines.append("")
|
|
161
|
+
return "\n".join(lines)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def _render_monthly_summary_entry(
|
|
165
|
+
local_date: str,
|
|
166
|
+
summary: str,
|
|
167
|
+
highlights: tuple[str, ...],
|
|
168
|
+
next_steps: tuple[str, ...],
|
|
169
|
+
refs: tuple[str, ...],
|
|
170
|
+
) -> str:
|
|
171
|
+
lines = [f"## {local_date}", ""]
|
|
172
|
+
clean_summary = preview_activity_text(summary, 900)
|
|
173
|
+
if clean_summary:
|
|
174
|
+
lines.append(f"- summary: {clean_summary}")
|
|
175
|
+
clean_highlights = tuple(value.strip() for value in highlights if value.strip())
|
|
176
|
+
if clean_highlights:
|
|
177
|
+
lines.append("- highlights:")
|
|
178
|
+
lines.extend(f" - {preview_activity_text(value, 240)}" for value in clean_highlights)
|
|
179
|
+
clean_next_steps = tuple(value.strip() for value in next_steps if value.strip())
|
|
180
|
+
if clean_next_steps:
|
|
181
|
+
lines.append("- next_steps:")
|
|
182
|
+
lines.extend(f" - {preview_activity_text(value, 240)}" for value in clean_next_steps)
|
|
183
|
+
lines.append(f"- daily_note: daily/{local_date}.md")
|
|
184
|
+
clean_refs = tuple(value.strip() for value in refs if value.strip())
|
|
185
|
+
if clean_refs:
|
|
186
|
+
lines.append("- refs:")
|
|
187
|
+
lines.extend(f" - {preview_activity_text(value, 240)}" for value in clean_refs)
|
|
188
|
+
lines.append("")
|
|
189
|
+
return "\n".join(lines)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def _upsert_markdown_section(
|
|
193
|
+
existing: str,
|
|
194
|
+
title: str,
|
|
195
|
+
section_heading: str,
|
|
196
|
+
section: str,
|
|
197
|
+
) -> str:
|
|
198
|
+
clean_existing = existing.strip()
|
|
199
|
+
if not clean_existing:
|
|
200
|
+
return f"{title}\n\n{section.strip()}\n"
|
|
201
|
+
lines = clean_existing.splitlines()
|
|
202
|
+
if lines[0].strip() != title:
|
|
203
|
+
lines.insert(0, title)
|
|
204
|
+
lines.insert(1, "")
|
|
205
|
+
start = None
|
|
206
|
+
for index, line in enumerate(lines):
|
|
207
|
+
if line.strip() == section_heading:
|
|
208
|
+
start = index
|
|
209
|
+
break
|
|
210
|
+
if start is None:
|
|
211
|
+
if lines and lines[-1].strip():
|
|
212
|
+
lines.append("")
|
|
213
|
+
lines.extend(section.strip().splitlines())
|
|
214
|
+
return "\n".join(lines).rstrip() + "\n"
|
|
215
|
+
end = len(lines)
|
|
216
|
+
for index in range(start + 1, len(lines)):
|
|
217
|
+
if lines[index].startswith("## "):
|
|
218
|
+
end = index
|
|
219
|
+
break
|
|
220
|
+
updated = lines[:start] + section.strip().splitlines() + lines[end:]
|
|
221
|
+
return "\n".join(updated).rstrip() + "\n"
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def _source_lines(entry: ActivityEntry) -> tuple[str, ...]:
|
|
225
|
+
sources: list[str] = []
|
|
226
|
+
if entry.session_summary_path.strip():
|
|
227
|
+
sources.append(f"session_summary: {entry.session_summary_path.strip()}")
|
|
228
|
+
if entry.transcript_path.strip():
|
|
229
|
+
sources.append(f"transcript: {entry.transcript_path.strip()}")
|
|
230
|
+
if entry.trace_path.strip():
|
|
231
|
+
sources.append(f"trace: {entry.trace_path.strip()}")
|
|
232
|
+
return tuple(sources)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def _date_from_timestamp(timestamp: str) -> str:
|
|
236
|
+
value = timestamp.strip()
|
|
237
|
+
if len(value) < 10:
|
|
238
|
+
return ""
|
|
239
|
+
date = value[:10]
|
|
240
|
+
try:
|
|
241
|
+
datetime.strptime(date, "%Y-%m-%d")
|
|
242
|
+
except ValueError:
|
|
243
|
+
return ""
|
|
244
|
+
return date
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def _time_from_timestamp(timestamp: str) -> str:
|
|
248
|
+
value = timestamp.strip()
|
|
249
|
+
if "T" not in value:
|
|
250
|
+
return value
|
|
251
|
+
return value.split("T", 1)[1]
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def _validated_date(value: str) -> str:
|
|
255
|
+
date = value.strip()
|
|
256
|
+
if not _date_from_timestamp(date):
|
|
257
|
+
raise ValueError("date must use YYYY-MM-DD")
|
|
258
|
+
return date[:10]
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def _validated_month(value: str) -> str:
|
|
262
|
+
month = value.strip()
|
|
263
|
+
if len(month) != 7:
|
|
264
|
+
raise ValueError("month must use YYYY-MM")
|
|
265
|
+
try:
|
|
266
|
+
datetime.strptime(month, "%Y-%m")
|
|
267
|
+
except ValueError as exc:
|
|
268
|
+
raise ValueError("month must use YYYY-MM") from exc
|
|
269
|
+
return month
|
deepmate/app/__init__.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Application assembly helpers."""
|
|
2
|
+
|
|
3
|
+
from deepmate.app.settings import (
|
|
4
|
+
AppSettings,
|
|
5
|
+
ContextSettings,
|
|
6
|
+
HookSettings,
|
|
7
|
+
LoopGuardSettings,
|
|
8
|
+
ModelCallConfig,
|
|
9
|
+
ModelPurposeSettings,
|
|
10
|
+
ProviderRetrySettings,
|
|
11
|
+
ProviderSettings,
|
|
12
|
+
RemoteSettings,
|
|
13
|
+
RuntimeWakeSettings,
|
|
14
|
+
SubagentSettings,
|
|
15
|
+
ToolOutputSettings,
|
|
16
|
+
ToolRepairSettings,
|
|
17
|
+
WeComRemoteSettings,
|
|
18
|
+
load_settings,
|
|
19
|
+
provider_api_key,
|
|
20
|
+
provider_secret_path,
|
|
21
|
+
resolve_model_purpose,
|
|
22
|
+
save_provider_api_key,
|
|
23
|
+
save_wecom_remote_settings,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"AppSettings",
|
|
28
|
+
"ContextSettings",
|
|
29
|
+
"HookSettings",
|
|
30
|
+
"LoopGuardSettings",
|
|
31
|
+
"ModelCallConfig",
|
|
32
|
+
"ModelPurposeSettings",
|
|
33
|
+
"ProviderRetrySettings",
|
|
34
|
+
"ProviderSettings",
|
|
35
|
+
"RemoteSettings",
|
|
36
|
+
"RuntimeWakeSettings",
|
|
37
|
+
"SubagentSettings",
|
|
38
|
+
"ToolOutputSettings",
|
|
39
|
+
"ToolRepairSettings",
|
|
40
|
+
"WeComRemoteSettings",
|
|
41
|
+
"load_settings",
|
|
42
|
+
"provider_api_key",
|
|
43
|
+
"provider_secret_path",
|
|
44
|
+
"resolve_model_purpose",
|
|
45
|
+
"save_provider_api_key",
|
|
46
|
+
"save_wecom_remote_settings",
|
|
47
|
+
]
|