deepagents-serve 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.
@@ -0,0 +1,5 @@
1
+ """deepagents-serve: universal agent server for LangGraph graphs."""
2
+
3
+ from deepagents_serve.app import DeepAgentsServeApp
4
+
5
+ __all__ = ["DeepAgentsServeApp"]
@@ -0,0 +1 @@
1
+ """Adapters that encode :data:`~deepagents_serve.events.AgentEvent` values into protocol-specific SSE streams."""
@@ -0,0 +1,81 @@
1
+ """Encode :data:`~deepagents_serve.events.AgentEvent` values as Vercel AI Data Protocol SSE frames."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import dataclasses
6
+ import json
7
+ from typing import TYPE_CHECKING
8
+
9
+ from deepagents_serve import events
10
+ from deepagents_serve.adapter import vercel_protocol as protocol
11
+
12
+ if TYPE_CHECKING:
13
+ from collections.abc import Iterator
14
+
15
+ from deepagents_serve.events import AgentEvent
16
+
17
+
18
+ class VercelAIProtocolAdapter:
19
+ """Stateful adapter that converts :class:`~deepagents_serve.events.AgentEvent` values into Vercel AI Data Protocol SSE frames.
20
+
21
+ Tracks open text/reasoning/tool-input blocks so that ``*-start`` and ``*-end``
22
+ frames are emitted correctly around delta streams.
23
+ """
24
+
25
+ def __init__(self) -> None:
26
+ """Initialise with no active blocks."""
27
+ self._active_text_id: str | None = None
28
+ self._active_reasoning_id: str | None = None
29
+ self._active_tool_input_id: str | None = None
30
+
31
+ def encode(self, agent_event: AgentEvent) -> Iterator[str]:
32
+ """Encode a single :class:`~deepagents_serve.events.AgentEvent` as one or more SSE data lines."""
33
+ for part in self._to_parts(agent_event):
34
+ yield f"data: {json.dumps(dataclasses.asdict(part))}\n\n"
35
+
36
+ def flush(self) -> Iterator[str]:
37
+ """Close any open text/reasoning blocks after the stream ends."""
38
+ for part in self._flush_parts():
39
+ yield f"data: {json.dumps(dataclasses.asdict(part))}\n\n"
40
+
41
+ def _to_parts(self, agent_event: AgentEvent) -> Iterator[protocol.StreamPart]: # noqa: C901
42
+ match agent_event:
43
+ case events.TextDelta(id=id, content=content):
44
+ if id != self._active_text_id:
45
+ if self._active_text_id is not None:
46
+ yield protocol.TextEnd(id=self._active_text_id)
47
+ yield protocol.TextStart(id=id)
48
+ self._active_text_id = id
49
+ yield protocol.TextDelta(id=id, delta=content)
50
+
51
+ case events.ReasoningDelta(id=id, content=content):
52
+ if id != self._active_reasoning_id:
53
+ if self._active_reasoning_id is not None:
54
+ yield protocol.ReasoningEnd(id=self._active_reasoning_id)
55
+ yield protocol.ReasoningStart(id=id)
56
+ self._active_reasoning_id = id
57
+ yield protocol.ReasoningDelta(id=id, delta=content)
58
+
59
+ case events.ToolInputDelta(id=id, name=name, args_delta=args_delta):
60
+ if id != self._active_tool_input_id:
61
+ yield protocol.ToolInputStart(toolCallId=id, toolName=name)
62
+ self._active_tool_input_id = id
63
+ yield protocol.ToolInputDelta(toolCallId=id, inputTextDelta=args_delta)
64
+
65
+ case events.ToolOutputAvailable(id=id, output=output):
66
+ yield protocol.ToolOutputAvailable(toolCallId=id, output=output)
67
+
68
+ case events.Error(text=text):
69
+ yield protocol.ErrorPart(errorText=text)
70
+
71
+ case events.Abort(reason=reason):
72
+ yield protocol.AbortPart(reason=reason)
73
+
74
+ def _flush_parts(self) -> Iterator[protocol.StreamPart]:
75
+ if self._active_text_id is not None:
76
+ yield protocol.TextEnd(id=self._active_text_id)
77
+ self._active_text_id = None
78
+ if self._active_reasoning_id is not None:
79
+ yield protocol.ReasoningEnd(id=self._active_reasoning_id)
80
+ self._active_reasoning_id = None
81
+ self._active_tool_input_id = None
@@ -0,0 +1,193 @@
1
+ """Vercel AI Data Protocol stream-part dataclasses.
2
+
3
+ Field names are intentionally camelCase to match the JSON field names defined by the
4
+ `Vercel AI Data Protocol <https://sdk.vercel.ai/docs/ai-sdk-ui/stream-protocol>`_.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from dataclasses import dataclass, field
10
+ from typing import Any
11
+
12
+
13
+ @dataclass(frozen=True, slots=True)
14
+ class MessageStart:
15
+ """Signals the start of a new AI message."""
16
+
17
+ messageId: str
18
+ type: str = field(default="start", init=False)
19
+
20
+
21
+ @dataclass(frozen=True, slots=True)
22
+ class TextStart:
23
+ """Signals the start of a text content block."""
24
+
25
+ id: str
26
+ type: str = field(default="text-start", init=False)
27
+
28
+
29
+ @dataclass(frozen=True, slots=True)
30
+ class TextDelta:
31
+ """A text content fragment."""
32
+
33
+ id: str
34
+ delta: str
35
+ type: str = field(default="text-delta", init=False)
36
+
37
+
38
+ @dataclass(frozen=True, slots=True)
39
+ class TextEnd:
40
+ """Signals the end of a text content block."""
41
+
42
+ id: str
43
+ type: str = field(default="text-end", init=False)
44
+
45
+
46
+ @dataclass(frozen=True, slots=True)
47
+ class ReasoningStart:
48
+ """Signals the start of a reasoning/thinking block."""
49
+
50
+ id: str
51
+ type: str = field(default="reasoning-start", init=False)
52
+
53
+
54
+ @dataclass(frozen=True, slots=True)
55
+ class ReasoningDelta:
56
+ """A reasoning/thinking content fragment."""
57
+
58
+ id: str
59
+ delta: str
60
+ type: str = field(default="reasoning-delta", init=False)
61
+
62
+
63
+ @dataclass(frozen=True, slots=True)
64
+ class ReasoningEnd:
65
+ """Signals the end of a reasoning/thinking block."""
66
+
67
+ id: str
68
+ type: str = field(default="reasoning-end", init=False)
69
+
70
+
71
+ @dataclass(frozen=True, slots=True)
72
+ class SourceUrl:
73
+ """A source URL citation."""
74
+
75
+ sourceId: str
76
+ url: str
77
+ type: str = field(default="source-url", init=False)
78
+
79
+
80
+ @dataclass(frozen=True, slots=True)
81
+ class SourceDocument:
82
+ """A source document citation."""
83
+
84
+ sourceId: str
85
+ mediaType: str
86
+ title: str
87
+ type: str = field(default="source-document", init=False)
88
+
89
+
90
+ @dataclass(frozen=True, slots=True)
91
+ class FilePart:
92
+ """A file attachment part."""
93
+
94
+ url: str
95
+ mediaType: str
96
+ type: str = field(default="file", init=False)
97
+
98
+
99
+ @dataclass(frozen=True, slots=True)
100
+ class ErrorPart:
101
+ """A non-fatal error part."""
102
+
103
+ errorText: str
104
+ type: str = field(default="error", init=False)
105
+
106
+
107
+ @dataclass(frozen=True, slots=True)
108
+ class ToolInputStart:
109
+ """Signals the start of a tool-call input stream."""
110
+
111
+ toolCallId: str
112
+ toolName: str
113
+ type: str = field(default="tool-input-start", init=False)
114
+
115
+
116
+ @dataclass(frozen=True, slots=True)
117
+ class ToolInputDelta:
118
+ """A streamed fragment of a tool-call input JSON string."""
119
+
120
+ toolCallId: str
121
+ inputTextDelta: str
122
+ type: str = field(default="tool-input-delta", init=False)
123
+
124
+
125
+ @dataclass(frozen=True, slots=True)
126
+ class ToolInputAvailable:
127
+ """The complete, parsed input for a tool call."""
128
+
129
+ toolCallId: str
130
+ toolName: str
131
+ input: Any
132
+ type: str = field(default="tool-input-available", init=False)
133
+
134
+
135
+ @dataclass(frozen=True, slots=True)
136
+ class ToolOutputAvailable:
137
+ """The output of a completed tool call."""
138
+
139
+ toolCallId: str
140
+ output: Any
141
+ type: str = field(default="tool-output-available", init=False)
142
+
143
+
144
+ @dataclass(frozen=True, slots=True)
145
+ class StartStep:
146
+ """Signals the start of an agent reasoning step."""
147
+
148
+ type: str = field(default="start-step", init=False)
149
+
150
+
151
+ @dataclass(frozen=True, slots=True)
152
+ class FinishStep:
153
+ """Signals the end of an agent reasoning step."""
154
+
155
+ type: str = field(default="finish-step", init=False)
156
+
157
+
158
+ @dataclass(frozen=True, slots=True)
159
+ class FinishMessage:
160
+ """Signals that the full AI message is complete."""
161
+
162
+ type: str = field(default="finish", init=False)
163
+
164
+
165
+ @dataclass(frozen=True, slots=True)
166
+ class AbortPart:
167
+ """Signals that the stream was aborted."""
168
+
169
+ reason: str | None = None
170
+ type: str = field(default="abort", init=False)
171
+
172
+
173
+ StreamPart = (
174
+ MessageStart
175
+ | TextStart
176
+ | TextDelta
177
+ | TextEnd
178
+ | ReasoningStart
179
+ | ReasoningDelta
180
+ | ReasoningEnd
181
+ | SourceUrl
182
+ | SourceDocument
183
+ | FilePart
184
+ | ErrorPart
185
+ | ToolInputStart
186
+ | ToolInputDelta
187
+ | ToolInputAvailable
188
+ | ToolOutputAvailable
189
+ | StartStep
190
+ | FinishStep
191
+ | FinishMessage
192
+ | AbortPart
193
+ )
@@ -0,0 +1,33 @@
1
+ """DeepAgentsServeApp — wraps a LangGraph graph and exposes it via Starlette."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from starlette.applications import Starlette
8
+
9
+ from deepagents_serve.route.health import router as health_router
10
+ from deepagents_serve.route.vercel import router as vercel_router
11
+
12
+
13
+ class DeepAgentsServeApp:
14
+ """Builds a Starlette ASGI application from any compiled LangGraph graph.
15
+
16
+ Args:
17
+ graph: A compiled LangGraph graph (or any object with an ``astream`` method).
18
+ """
19
+
20
+ def __init__(self, graph: Any) -> None:
21
+ """Initialise with a compiled LangGraph graph."""
22
+ self._graph = graph
23
+
24
+ def build(self) -> Starlette:
25
+ """Assemble and return the Starlette ASGI application."""
26
+ app = Starlette(
27
+ routes=[
28
+ *health_router.routes,
29
+ *vercel_router.routes,
30
+ ]
31
+ )
32
+ app.state.graph = self._graph
33
+ return app
@@ -0,0 +1,53 @@
1
+ """Canonical agent event types emitted by the normaliser."""
2
+
3
+ from dataclasses import dataclass
4
+
5
+
6
+ @dataclass(frozen=True, slots=True)
7
+ class TextDelta:
8
+ """A streamed text content fragment from an AI message."""
9
+
10
+ id: str
11
+ content: str
12
+
13
+
14
+ @dataclass(frozen=True, slots=True)
15
+ class ReasoningDelta:
16
+ """A streamed reasoning/thinking fragment from an AI message."""
17
+
18
+ id: str
19
+ content: str
20
+
21
+
22
+ @dataclass(frozen=True, slots=True)
23
+ class ToolInputDelta:
24
+ """A streamed partial argument string for a tool call."""
25
+
26
+ id: str
27
+ name: str
28
+ args_delta: str
29
+
30
+
31
+ @dataclass(frozen=True, slots=True)
32
+ class ToolOutputAvailable:
33
+ """The complete output of a finished tool call."""
34
+
35
+ id: str
36
+ output: str
37
+
38
+
39
+ @dataclass(frozen=True, slots=True)
40
+ class Error:
41
+ """A non-fatal error event from the agent."""
42
+
43
+ text: str
44
+
45
+
46
+ @dataclass(frozen=True, slots=True)
47
+ class Abort:
48
+ """Signals that the agent stream was aborted."""
49
+
50
+ reason: str | None = None
51
+
52
+
53
+ AgentEvent = TextDelta | ReasoningDelta | ToolInputDelta | ToolOutputAvailable | Error | Abort
@@ -0,0 +1,54 @@
1
+ """Normalise LangGraph ``stream_mode='messages'`` output into :data:`AgentEvent` values."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any
6
+
7
+ from langchain_core.messages import AIMessage, AIMessageChunk, ToolMessage
8
+
9
+ from deepagents_serve.events import (
10
+ AgentEvent,
11
+ TextDelta,
12
+ ToolInputDelta,
13
+ ToolOutputAvailable,
14
+ )
15
+
16
+ if TYPE_CHECKING:
17
+ from collections.abc import AsyncIterator, Iterator
18
+
19
+
20
+ async def normalize(stream: AsyncIterator[Any]) -> AsyncIterator[AgentEvent]:
21
+ """Yield :class:`AgentEvent` values from a LangGraph messages stream."""
22
+ async for message, _metadata in stream:
23
+ for agent_event in _parse_message(message):
24
+ yield agent_event
25
+
26
+
27
+ def _parse_message(message: Any) -> Iterator[AgentEvent]:
28
+ if isinstance(message, (AIMessage, AIMessageChunk)):
29
+ yield from _parse_ai_message(message)
30
+ elif isinstance(message, ToolMessage):
31
+ yield ToolOutputAvailable(id=message.tool_call_id, output=str(message.content))
32
+
33
+
34
+ def _parse_ai_message(message: AIMessage | AIMessageChunk) -> Iterator[AgentEvent]:
35
+ msg_id = message.id or "msg"
36
+ content = message.content
37
+
38
+ if isinstance(content, str):
39
+ if content:
40
+ yield TextDelta(id=msg_id, content=content)
41
+ elif isinstance(content, list):
42
+ for block in content:
43
+ if not isinstance(block, dict):
44
+ continue
45
+ if block.get("type") == "text" and block.get("text"):
46
+ yield TextDelta(id=msg_id, content=block["text"])
47
+
48
+ for tool_call in getattr(message, "tool_call_chunks", []):
49
+ if tool_call.get("args"):
50
+ yield ToolInputDelta(
51
+ id=tool_call["id"] or msg_id,
52
+ name=tool_call.get("name", ""),
53
+ args_delta=tool_call["args"],
54
+ )
File without changes
@@ -0,0 +1 @@
1
+ """Starlette route definitions for the deepagents-serve endpoints."""
@@ -0,0 +1,24 @@
1
+ """Health and readiness check endpoints."""
2
+
3
+ from starlette.requests import Request
4
+ from starlette.responses import JSONResponse
5
+ from starlette.routing import Route, Router
6
+
7
+
8
+ async def _health(_request: Request) -> JSONResponse:
9
+ return JSONResponse({"status": "ok"})
10
+
11
+
12
+ async def _ready(request: Request) -> JSONResponse:
13
+ graph = request.app.state.graph
14
+ if graph is None:
15
+ return JSONResponse({"status": "not ready"}, status_code=503)
16
+ return JSONResponse({"status": "ready"})
17
+
18
+
19
+ router = Router(
20
+ routes=[
21
+ Route("/health", _health, methods=["GET"]),
22
+ Route("/ready", _ready, methods=["GET"]),
23
+ ]
24
+ )
@@ -0,0 +1,49 @@
1
+ """Vercel AI Data Protocol streaming chat endpoint."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from starlette.responses import StreamingResponse
8
+ from starlette.routing import Route, Router
9
+
10
+ from deepagents_serve.adapter.vercel import VercelAIProtocolAdapter
11
+ from deepagents_serve.normaliser import normalize
12
+
13
+ if TYPE_CHECKING:
14
+ from collections.abc import AsyncIterator
15
+
16
+ from starlette.requests import Request
17
+
18
+ # TODO: formalise request schema with a dataclass/Pydantic model
19
+ # Expected shape: {"messages": [{"role": "user"|"assistant", "content": str}]}
20
+
21
+
22
+ async def _chat_stream(request: Request) -> StreamingResponse:
23
+ body = await request.json()
24
+ messages = body.get("messages", [])
25
+ graph = request.app.state.graph
26
+
27
+ async def event_generator() -> AsyncIterator[str]:
28
+ adapter = VercelAIProtocolAdapter()
29
+ stream = graph.astream({"messages": messages}, stream_mode="messages")
30
+
31
+ async for agent_event in normalize(stream):
32
+ for chunk in adapter.encode(agent_event):
33
+ yield chunk
34
+
35
+ for chunk in adapter.flush():
36
+ yield chunk
37
+
38
+ return StreamingResponse(
39
+ event_generator(),
40
+ media_type="text/event-stream",
41
+ headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"},
42
+ )
43
+
44
+
45
+ router = Router(
46
+ routes=[
47
+ Route("/chat/stream", _chat_stream, methods=["POST"]),
48
+ ]
49
+ )
@@ -0,0 +1,160 @@
1
+ Metadata-Version: 2.4
2
+ Name: deepagents_serve
3
+ Version: 0.1.0
4
+ Summary: Universal agent server. Wraps any LangGraph graph and exposes it over standard agent protocols — Vercel AI SDK, Claude Code, TUIs, and more.
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/FengJi2021/deepagents-serve
7
+ Project-URL: Repository, https://github.com/FengJi2021/deepagents-serve
8
+ Project-URL: Issues, https://github.com/FengJi2021/deepagents-serve/issues
9
+ Keywords: agents,ai,llm,langgraph,langchain,agent-server,vercel-ai,streaming
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Requires-Python: <4.0,>=3.11
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: starlette>=0.46.0
22
+ Requires-Dist: uvicorn>=0.34.0
23
+ Requires-Dist: langgraph>=0.4.0
24
+ Requires-Dist: langchain-core>=0.3.0
25
+
26
+ # deepagents-serve
27
+
28
+ Universal agent server. Wraps any LangGraph graph and exposes it over standard agent protocols — Vercel AI SDK, Claude Code, TUIs, and more.
29
+
30
+ ## Quick start
31
+
32
+ ```python
33
+ from deepagents_serve import DeepAgentsServeApp
34
+ from deepagents import create_deep_agent
35
+ import uvicorn
36
+
37
+ agent = create_deep_agent(
38
+ model="anthropic:claude-opus-4-8",
39
+ skills=["myskillsregistry/skills"],
40
+ system_prompt="You are a helpful assistant."
41
+ )
42
+
43
+ app = DeepAgentsServeApp(agent)
44
+
45
+ uvicorn.run(app.build(), host="0.0.0.0", port=8000)
46
+ ```
47
+
48
+ ---
49
+
50
+ ## Endpoint design
51
+
52
+ ### `POST /chat/stream`
53
+
54
+ Stateless. One request, one SSE stream, done. No session state is kept between calls.
55
+
56
+ **Request**
57
+
58
+ ```json
59
+ {
60
+ "messages": [
61
+ {"role": "user", "content": "List the files in the working directory."}
62
+ ]
63
+ }
64
+ ```
65
+
66
+ **Response** — `Content-Type: text/event-stream`
67
+
68
+ Uses the [Vercel AI Data Protocol](https://sdk.vercel.ai/docs/ai-sdk-ui/stream-protocol). Each line is `data: <json>`:
69
+
70
+ ```text
71
+ data: {"type": "text-start", "id": "msg_01"}
72
+ data: {"type": "text-delta", "id": "msg_01", "delta": "Here are the files:\n"}
73
+ data: {"type": "text-end", "id": "msg_01"}
74
+
75
+ data: {"type": "tool-input-start", "toolCallId": "tc_01", "toolName": "bash"}
76
+ data: {"type": "tool-input-delta", "toolCallId": "tc_01", "inputTextDelta": "{\"command\":\"ls\"}"}
77
+ data: {"type": "tool-output-available", "toolCallId": "tc_01", "output": "README.md\nsrc/"}
78
+
79
+ data: {"type": "reasoning-start", "id": "r_01"}
80
+ data: {"type": "reasoning-delta", "id": "r_01", "delta": "I should list the files..."}
81
+ data: {"type": "reasoning-end", "id": "r_01"}
82
+
83
+ data: {"type": "error", "errorText": "something went wrong"}
84
+ data: {"type": "abort", "reason": "user cancelled"}
85
+ data: {"type": "finish"}
86
+ ```
87
+
88
+ ---
89
+
90
+ ## Signal diagram
91
+
92
+ ```text
93
+ Client (Vercel SDK / Claude Code / TUI)
94
+
95
+ │ POST /chat/stream
96
+ │ {"messages": [{"role": "user", "content": "..."}]}
97
+
98
+ ┌──────────────────┐
99
+ │ Input Parser │ extract last user message from messages array
100
+ └────────┬─────────┘
101
+ │ {"role": "user", "content": "..."}
102
+
103
+ ┌──────────────────┐
104
+ │ LangGraph Graph │ graph.astream({"messages": [...]}, stream_mode=["messages"])
105
+ └────────┬─────────┘
106
+ │ (stream_part, metadata) chunks
107
+
108
+ ┌──────────────────┐
109
+ │ Normaliser │ LangGraph messages → canonical AgentEvent
110
+ │ │
111
+ │ AIMessage │→ TextDelta | ReasoningDelta
112
+ │ ToolCall │→ ToolInputDelta
113
+ │ ToolMessage │→ ToolOutputAvailable
114
+ │ Error │→ Error | Abort
115
+ └────────┬─────────┘
116
+ │ AgentEvent
117
+
118
+ ┌──────────────────┐
119
+ │ Vercel Adapter │ AgentEvent → Vercel SSE stream parts
120
+ └────────┬─────────┘
121
+ │ text/event-stream
122
+
123
+ Client
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Roadmap
129
+
130
+ **Near-term**
131
+
132
+ - [ ] Input parsing — read request body, extract messages
133
+ - [ ] Complete normaliser — tool calls, tool results, reasoning deltas from LangGraph
134
+ - [ ] Request validation — reject malformed payloads at the boundary
135
+
136
+ **Protocol compatibility**
137
+
138
+ - [ ] Claude Managed Agents endpoints — `/v1/sessions`, `/v1/sessions/{id}/events`, `/v1/sessions/{id}/events/stream`
139
+ - [ ] Claude Managed Agents SSE encoding — `agent.message`, `agent.tool_use`, `session.status_idle` event types
140
+ - [ ] Agent metadata endpoint — `GET /v1/agents/default`
141
+
142
+ **Statefulness**
143
+
144
+ - [ ] Session layer — LangGraph `thread_id` checkpointing, `session_id` → `thread_id` mapping
145
+ - [ ] Multi-turn conversations — persist conversation history across requests
146
+ - [ ] Interrupt support — `user.interrupt` event stops graph mid-execution
147
+
148
+ **Deployment**
149
+
150
+ - [ ] kagent packaging — Kubernetes-compatible worker pattern
151
+
152
+ **Eval**
153
+
154
+ - [ ] Event history capture — persist full turn events with timestamps and token counts
155
+ - [ ] Session replay — re-run a captured session for regression testing
156
+
157
+ **Skills**
158
+
159
+ - [ ] Skill registry compatibility — discover and invoke skills from a registry
160
+ - [ ] Finetune on skills — export session history as structured training data
@@ -0,0 +1,15 @@
1
+ deepagents_serve/__init__.py,sha256=A3vL6So1kMaK8eEdge5-gm4bTrWHwGPP3Pk4rRm0Mvo,156
2
+ deepagents_serve/app.py,sha256=fFYqbgTk4c8OH1XOX4WvVmizkYwUKaUmFvkoYd8oKOs,970
3
+ deepagents_serve/events.py,sha256=olZlMvgnasEfCjNpTHm5TDBW7DF0_PSSFLxGabrybgw,1069
4
+ deepagents_serve/normaliser.py,sha256=MYuDrqLXE58JKas9MflnV0ntfioJnS7ElsyHAAJp7K4,1824
5
+ deepagents_serve/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ deepagents_serve/adapter/__init__.py,sha256=Y5ZhfkOQ1ivKNrwA4y4Zm6QuxnB7ZepV5Ns_sMFvUJg,114
7
+ deepagents_serve/adapter/vercel.py,sha256=zJzrStfqFhVJ3HN31gxYxmOXG5526TBXEd7bL0e01Hk,3558
8
+ deepagents_serve/adapter/vercel_protocol.py,sha256=f9TnJbAJ64we0WuKR77aZoTggV2FnPJvw5iXqradkWU,4287
9
+ deepagents_serve/route/__init__.py,sha256=T9nPIr6_9bL0b35SsxZR2UXqz2bSYiApxFmimcLAxwM,70
10
+ deepagents_serve/route/health.py,sha256=LOulB2C9giIcpDJkfmq3ErbN848hb5XUj9PvLHKptUg,640
11
+ deepagents_serve/route/vercel.py,sha256=DnqdTptUT3vHL2ZXYsxYJaXONHRyVJE7xj-58pKysOw,1424
12
+ deepagents_serve-0.1.0.dist-info/METADATA,sha256=F0MQ69r8A9gCGxxMztRESZvbplnXOvtpx0OggdIFv6w,5622
13
+ deepagents_serve-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
14
+ deepagents_serve-0.1.0.dist-info/top_level.txt,sha256=BAx7uyQaeFCbDLF0dQWN49ml4NBHjaKv8L5Q6yL9FAs,17
15
+ deepagents_serve-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ deepagents_serve