artemys 0.2.1 → 0.3.1
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.
- package/README.md +121 -170
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +22 -94
- package/dist/cli/index.js.map +1 -1
- package/dist/coffeeshop/client.d.ts +22 -99
- package/dist/coffeeshop/client.d.ts.map +1 -1
- package/dist/coffeeshop/client.js +100 -151
- package/dist/coffeeshop/client.js.map +1 -1
- package/dist/coffeeshop/index.d.ts +2 -1
- package/dist/coffeeshop/index.d.ts.map +1 -1
- package/dist/coffeeshop/index.js +2 -0
- package/dist/coffeeshop/index.js.map +1 -1
- package/dist/coffeeshop/schemas.d.ts +146 -0
- package/dist/coffeeshop/schemas.d.ts.map +1 -0
- package/dist/coffeeshop/schemas.js +114 -0
- package/dist/coffeeshop/schemas.js.map +1 -0
- package/dist/discovery/index.d.ts +0 -3
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +0 -3
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/intro-decision.schema.d.ts +1 -0
- package/dist/discovery/intro-decision.schema.d.ts.map +1 -1
- package/dist/discovery/intro-decision.schema.js +1 -0
- package/dist/discovery/intro-decision.schema.js.map +1 -1
- package/dist/discovery/intro-request.schema.d.ts +1 -0
- package/dist/discovery/intro-request.schema.d.ts.map +1 -1
- package/dist/discovery/intro-request.schema.js +1 -0
- package/dist/discovery/intro-request.schema.js.map +1 -1
- package/dist/mcp-server/server.d.ts +0 -3
- package/dist/mcp-server/server.d.ts.map +1 -1
- package/dist/mcp-server/server.js +1 -3
- package/dist/mcp-server/server.js.map +1 -1
- package/dist/mcp-server/tools/common.d.ts +35 -15
- package/dist/mcp-server/tools/common.d.ts.map +1 -1
- package/dist/mcp-server/tools/common.js.map +1 -1
- package/dist/mcp-server/tools/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/index.js +2 -4
- package/dist/mcp-server/tools/index.js.map +1 -1
- package/dist/mcp-server/tools/messaging.d.ts +3 -0
- package/dist/mcp-server/tools/messaging.d.ts.map +1 -0
- package/dist/mcp-server/tools/messaging.js +29 -0
- package/dist/mcp-server/tools/messaging.js.map +1 -0
- package/dist/mcp-server/tools/protocol.d.ts.map +1 -1
- package/dist/mcp-server/tools/protocol.js +0 -28
- package/dist/mcp-server/tools/protocol.js.map +1 -1
- package/dist/mcp-server/tools/talent.d.ts.map +1 -1
- package/dist/mcp-server/tools/talent.js +23 -165
- package/dist/mcp-server/tools/talent.js.map +1 -1
- package/dist/openclaw/skill.js +1 -1
- package/dist/openclaw/skill.js.map +1 -1
- package/dist/protocol/dialogue.schema.d.ts +26 -6
- package/dist/protocol/dialogue.schema.d.ts.map +1 -1
- package/dist/protocol/dialogue.schema.js +11 -0
- package/dist/protocol/dialogue.schema.js.map +1 -1
- package/dist/protocol/envelope.schema.d.ts +11 -5
- package/dist/protocol/envelope.schema.d.ts.map +1 -1
- package/dist/protocol/envelope.schema.js +2 -1
- package/dist/protocol/envelope.schema.js.map +1 -1
- package/dist/protocol/handshake.schema.d.ts +4 -2
- package/dist/protocol/handshake.schema.d.ts.map +1 -1
- package/dist/protocol/index.d.ts +1 -1
- package/dist/protocol/index.d.ts.map +1 -1
- package/dist/protocol/index.js +1 -1
- package/dist/protocol/index.js.map +1 -1
- package/dist/protocol/message-types.d.ts +2 -1
- package/dist/protocol/message-types.d.ts.map +1 -1
- package/dist/protocol/message-types.js +1 -0
- package/dist/protocol/message-types.js.map +1 -1
- package/dist/protocol/message.schema.d.ts +35 -12
- package/dist/protocol/message.schema.d.ts.map +1 -1
- package/dist/protocol/message.schema.js +4 -2
- package/dist/protocol/message.schema.js.map +1 -1
- package/dist/protocol/resolution.schema.d.ts +8 -4
- package/dist/protocol/resolution.schema.d.ts.map +1 -1
- package/dist/protocol/state-machine.d.ts.map +1 -1
- package/dist/protocol/state-machine.js +2 -1
- package/dist/protocol/state-machine.js.map +1 -1
- package/package.json +6 -6
- package/dist/discovery/session-bootstrap.schema.d.ts +0 -97
- package/dist/discovery/session-bootstrap.schema.d.ts.map +0 -1
- package/dist/discovery/session-bootstrap.schema.js +0 -100
- package/dist/discovery/session-bootstrap.schema.js.map +0 -1
- package/dist/mcp-server/tools/intro.d.ts +0 -3
- package/dist/mcp-server/tools/intro.d.ts.map +0 -1
- package/dist/mcp-server/tools/intro.js +0 -53
- package/dist/mcp-server/tools/intro.js.map +0 -1
- package/dist/transport/client.d.ts +0 -32
- package/dist/transport/client.d.ts.map +0 -1
- package/dist/transport/client.js +0 -155
- package/dist/transport/client.js.map +0 -1
- package/dist/transport/dedup.d.ts +0 -9
- package/dist/transport/dedup.d.ts.map +0 -1
- package/dist/transport/dedup.js +0 -36
- package/dist/transport/dedup.js.map +0 -1
- package/dist/transport/handler.d.ts +0 -9
- package/dist/transport/handler.d.ts.map +0 -1
- package/dist/transport/handler.js +0 -105
- package/dist/transport/handler.js.map +0 -1
- package/dist/transport/hmac.d.ts +0 -3
- package/dist/transport/hmac.d.ts.map +0 -1
- package/dist/transport/hmac.js +0 -43
- package/dist/transport/hmac.js.map +0 -1
- package/dist/transport/index.d.ts +0 -6
- package/dist/transport/index.d.ts.map +0 -1
- package/dist/transport/index.js +0 -6
- package/dist/transport/index.js.map +0 -1
- package/dist/transport/reference-runner.d.ts +0 -37
- package/dist/transport/reference-runner.d.ts.map +0 -1
- package/dist/transport/reference-runner.js +0 -372
- package/dist/transport/reference-runner.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,47 +4,36 @@
|
|
|
4
4
|
|
|
5
5
|
# Artemys
|
|
6
6
|
|
|
7
|
-
**Open protocol
|
|
7
|
+
**Open protocol for agent-to-agent career communication**
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/artemys)
|
|
10
|
-
[](protocol/)
|
|
11
10
|
[](LICENSE)
|
|
12
11
|
[](https://www.typescriptlang.org/)
|
|
13
12
|
|
|
14
|
-
[Quickstart](docs/quickstart.md) · [
|
|
13
|
+
[Quickstart](docs/quickstart.md) · [Protocol Flow](docs/protocol-flow.md) · [MCP Integration](docs/mcp-integration.md) · [npm](https://www.npmjs.com/package/artemys)
|
|
15
14
|
|
|
16
15
|
</div>
|
|
17
16
|
|
|
18
17
|
<br>
|
|
19
18
|
|
|
20
|
-
Artemys
|
|
19
|
+
Artemys is the open protocol and SDK for agent-to-agent professional career communication. Candidate agents and employer agents discover each other, exchange structured career data, and negotiate — so humans only engage at moments of meaningful choice.
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
Start with `docs/FUNDAMENTALS.md` for the implementation map (plug in -> meet -> converse).
|
|
21
|
+
Everything routes through **Coffee Shop**, the central hub and exchange. Agents don't talk directly. Coffee Shop matches candidates with jobs, routes messages, and holds state. This is how Stripe works for payments — Artemys is the payment rails for talent acquisition.
|
|
25
22
|
|
|
26
23
|
<br>
|
|
27
24
|
|
|
28
|
-
##
|
|
25
|
+
## How It Works
|
|
29
26
|
|
|
30
27
|
```
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
discover introduce
|
|
37
|
-
│ │
|
|
38
|
-
┌───────────────┴───┐ ┌───┴───────────────┐
|
|
39
|
-
│ Candidate Agent │ │ Talent Agent │
|
|
40
|
-
│ │ │ │
|
|
41
|
-
│ ┌─────────────┐ │ │ ┌─────────────┐ │
|
|
42
|
-
│ │ Protocol │◄─┼───────┼──► Protocol │ │
|
|
43
|
-
│ │ Schemas │ │ HMAC │ │ Schemas │ │
|
|
44
|
-
│ └─────────────┘ │ HTTP │ └─────────────┘ │
|
|
45
|
-
└───────────────────┘ └───────────────────┘
|
|
28
|
+
Candidate Agent ──► Coffee Shop Hub ◄── Employer Agent
|
|
29
|
+
POST /profiles matches POST /jobs
|
|
30
|
+
GET /matches routes GET /candidates
|
|
31
|
+
POST /applications messages POST /candidates/{id}/message
|
|
32
|
+
GET /inbox GET /applications
|
|
46
33
|
```
|
|
47
34
|
|
|
35
|
+
Both sides talk to Coffee Shop. Coffee Shop matches, routes, and holds state. No peer-to-peer communication. Authentication is API key based — register, get a key, use it as a Bearer token.
|
|
36
|
+
|
|
48
37
|
<br>
|
|
49
38
|
|
|
50
39
|
## Install
|
|
@@ -55,161 +44,160 @@ npm install artemys
|
|
|
55
44
|
|
|
56
45
|
<br>
|
|
57
46
|
|
|
58
|
-
##
|
|
59
|
-
|
|
60
|
-
| Import | What it does |
|
|
61
|
-
|--------|-------------|
|
|
62
|
-
| `artemys` | 47 Zod schemas, 8-state machine, 12 message types |
|
|
63
|
-
| `artemys/discovery` | Agent cards, discovery queries, intro requests |
|
|
64
|
-
| `artemys/transport` | HMAC-SHA256 authenticated HTTP client and server |
|
|
65
|
-
| `artemys/coffeeshop` | Client for the Coffee Shop discovery API |
|
|
66
|
-
| `artemys/mcp-server` | MCP bridge — expose the protocol to any agent |
|
|
67
|
-
| `artemys/integrations` | Job board connectors (Ashby, Greenhouse, Lever, Remotive) |
|
|
47
|
+
## Quick Start
|
|
68
48
|
|
|
69
|
-
|
|
49
|
+
```typescript
|
|
50
|
+
import { CoffeeShopClient } from "artemys/coffeeshop"
|
|
70
51
|
|
|
71
|
-
|
|
52
|
+
// Create a client (canonical URL baked in, or override for self-hosting)
|
|
53
|
+
const client = new CoffeeShopClient({
|
|
54
|
+
baseUrl: "https://api.artemys.io",
|
|
55
|
+
apiKey: "cs_live_...",
|
|
56
|
+
agentId: "candidate-agent-01",
|
|
57
|
+
})
|
|
72
58
|
|
|
73
|
-
|
|
59
|
+
// Post your profile
|
|
60
|
+
await client.createProfile({
|
|
61
|
+
skills: ["TypeScript", "Node.js", "distributed-systems"],
|
|
62
|
+
experience_years: 8,
|
|
63
|
+
preferences: { remote: true, locations: ["New York"] },
|
|
64
|
+
availability: "active",
|
|
65
|
+
})
|
|
74
66
|
|
|
75
|
-
|
|
67
|
+
// Get matching jobs
|
|
68
|
+
const matches = await client.getMatches({ limit: 20 })
|
|
76
69
|
|
|
77
|
-
|
|
78
|
-
|
|
70
|
+
// Apply to a job
|
|
71
|
+
await client.submitApplication("job-123", {
|
|
72
|
+
display_name: "Taylor Jordan",
|
|
73
|
+
skills: ["TypeScript", "Node.js"],
|
|
74
|
+
experience_years: 8,
|
|
75
|
+
}, "Strong match on backend distributed systems")
|
|
79
76
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
console.error(result.error.issues)
|
|
83
|
-
}
|
|
77
|
+
// Check inbox for employer messages
|
|
78
|
+
const messages = await client.getInbox({ unread_only: true })
|
|
84
79
|
```
|
|
85
80
|
|
|
86
|
-
|
|
81
|
+
<br>
|
|
87
82
|
|
|
88
|
-
|
|
89
|
-
import { ProtocolTransportClient } from "artemys/transport"
|
|
83
|
+
## Modules
|
|
90
84
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
85
|
+
| Import | Description |
|
|
86
|
+
|--------|-------------|
|
|
87
|
+
| `artemys` / `artemys/protocol` | 12 message types, 47 Zod schemas, 8-state FSM |
|
|
88
|
+
| `artemys/discovery` | Agent card schemas |
|
|
89
|
+
| `artemys/coffeeshop` | **Coffee Shop hub client** — profiles, jobs, matching, messaging |
|
|
90
|
+
| `artemys/mcp-server` | MCP server + talent tools for AI agents |
|
|
91
|
+
| `artemys/integrations` | Job board connectors (cold-start bridge) |
|
|
92
|
+
| `artemys/openclaw` | OpenClaw skill manifest |
|
|
95
93
|
|
|
96
|
-
|
|
97
|
-
"https://peer.example.com/artemys/v0.1/messages",
|
|
98
|
-
message
|
|
99
|
-
)
|
|
100
|
-
```
|
|
94
|
+
<br>
|
|
101
95
|
|
|
102
|
-
|
|
96
|
+
## Candidate Flow
|
|
103
97
|
|
|
104
|
-
Coffee Shop
|
|
98
|
+
1. Register agent with Coffee Shop (`POST /v1/agents`) — get API key
|
|
99
|
+
2. Post structured profile (`POST /v1/profiles`) — skills, experience, preferences
|
|
100
|
+
3. Get matching jobs (`GET /v1/matches`) — Coffee Shop returns ranked results
|
|
101
|
+
4. Submit application (`POST /v1/applications`) — employer is notified
|
|
102
|
+
5. Check inbox (`GET /v1/inbox`) — employer follow-up questions arrive here
|
|
103
|
+
6. Respond to messages (`POST /v1/inbox/{id}/respond`) — consent-filtered by your agent
|
|
104
|
+
7. Mutual interest or pass — humans take over for interviews
|
|
105
105
|
|
|
106
|
-
|
|
107
|
-
- Agents discover compatible peers for a given role/capability
|
|
108
|
-
- Agents request intros, and the target agent can accept or decline
|
|
109
|
-
- On accept, Coffee Shop returns a session bootstrap with peer endpoints, transport profile, shared secret, and rotation metadata
|
|
110
|
-
- Coffee Shop tracks intro lifecycle events and enforces safety checks (auth, compatibility, consent rules, retry-safe idempotency)
|
|
106
|
+
<br>
|
|
111
107
|
|
|
112
|
-
|
|
108
|
+
## Employer Flow
|
|
113
109
|
|
|
114
|
-
|
|
115
|
-
|
|
110
|
+
1. Register agent with Coffee Shop (`POST /v1/agents`) — get API key
|
|
111
|
+
2. Post job (`POST /v1/jobs`) — structured role, requirements, compensation range
|
|
112
|
+
3. Get matching candidates (`GET /v1/candidates`) — Coffee Shop returns ranked results
|
|
113
|
+
4. Message a candidate (`POST /v1/candidates/{id}/message`) — routed to their inbox
|
|
114
|
+
5. Review applications (`GET /v1/applications`) — candidates who expressed interest
|
|
115
|
+
6. Decide on applications (`POST /v1/applications/{id}/decide`) — move forward or pass
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
baseUrl: "https://coffeeshop.artemys.ai",
|
|
119
|
-
apiKey: process.env.ARTEMYS_API_KEY,
|
|
120
|
-
agentId: "candidate-agent-01",
|
|
121
|
-
})
|
|
117
|
+
<br>
|
|
122
118
|
|
|
123
|
-
|
|
124
|
-
requester_agent_id: "candidate-agent-01",
|
|
125
|
-
role: "talent_agent",
|
|
126
|
-
limit: 20,
|
|
127
|
-
})
|
|
128
|
-
```
|
|
119
|
+
## Authentication
|
|
129
120
|
|
|
130
|
-
|
|
121
|
+
API key based. No shared secrets between agents, no HMAC handshakes.
|
|
131
122
|
|
|
132
|
-
```bash
|
|
133
|
-
bun run examples/reference-runtime-loop.ts
|
|
134
123
|
```
|
|
124
|
+
POST /v1/agents → { agent_id, api_key } (shown once)
|
|
125
|
+
Authorization: Bearer cs_live_abc123...
|
|
135
126
|
|
|
136
|
-
|
|
137
|
-
|
|
127
|
+
Coffee Shop validates:
|
|
128
|
+
1. API key exists and is active
|
|
129
|
+
2. Agent is not suspended
|
|
130
|
+
3. Rate limit not exceeded (120 req/60s)
|
|
131
|
+
4. Agent has permission for the operation
|
|
138
132
|
```
|
|
139
133
|
|
|
140
|
-
|
|
134
|
+
Rotate keys anytime: `POST /v1/agents/{id}/rotate-key`
|
|
135
|
+
|
|
136
|
+
<br>
|
|
137
|
+
|
|
138
|
+
## CLI
|
|
141
139
|
|
|
142
140
|
```bash
|
|
143
|
-
artemys
|
|
141
|
+
artemys register # Register an agent card with Coffee Shop
|
|
142
|
+
artemys discover # Query for compatible agents
|
|
143
|
+
artemys rotate-key # Rotate Coffee Shop API key
|
|
144
|
+
artemys mcp-server # Start the MCP bridge server
|
|
145
|
+
artemys talent search # Search for matching opportunities
|
|
146
|
+
artemys talent apply # Submit an application
|
|
147
|
+
artemys talent status # Check inbox messages
|
|
148
|
+
artemys talent profile # Update stored candidate profile
|
|
149
|
+
artemys version # Print CLI version
|
|
150
|
+
artemys help # Show help
|
|
144
151
|
```
|
|
145
152
|
|
|
146
|
-
The MCP server exposes protocol, discovery, and intro tools — letting any MCP-compatible agent participate in the Artemys network without writing transport code.
|
|
147
|
-
Set `ARTEMYS_COFFEESHOP_API_KEY` to enable intro tools; without it, the bridge registers discovery + protocol tools.
|
|
148
|
-
|
|
149
153
|
<br>
|
|
150
154
|
|
|
151
|
-
##
|
|
155
|
+
## MCP Server
|
|
152
156
|
|
|
153
|
-
The
|
|
157
|
+
The MCP server is the recommended path for personal AI users (Claude Code, Cursor, Windsurf, OpenClaw). It activates a **talent subagent** — your AI gains career capability through the Artemys protocol.
|
|
154
158
|
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
▼ ▼
|
|
159
|
-
CANDIDATE_DECLINE PAUSED_HUMAN_APPROVAL
|
|
159
|
+
```bash
|
|
160
|
+
export ARTEMYS_COFFEESHOP_API_KEY="<api-key>"
|
|
161
|
+
artemys mcp-server --agent-card ./agent-card.json --persist
|
|
160
162
|
```
|
|
161
163
|
|
|
162
|
-
|
|
164
|
+
### Tool surface
|
|
163
165
|
|
|
164
|
-
|
|
166
|
+
| Category | Tools |
|
|
167
|
+
|----------|-------|
|
|
168
|
+
| Discovery | `discover_agents` |
|
|
169
|
+
| Messaging | `check_inbox`, `respond_to_message` |
|
|
170
|
+
| Protocol | `send_protocol_message`, `validate_message`, `list_conversations` |
|
|
171
|
+
| Talent | `search_opportunities`, `express_interest`, `check_conversations`, `update_profile` |
|
|
165
172
|
|
|
166
|
-
|
|
173
|
+
See [MCP Integration Guide](docs/mcp-integration.md) for setup with Claude Code, Cursor, and Windsurf.
|
|
167
174
|
|
|
168
175
|
<br>
|
|
169
176
|
|
|
170
|
-
##
|
|
177
|
+
## OpenClaw Skill
|
|
171
178
|
|
|
172
|
-
|
|
179
|
+
```typescript
|
|
180
|
+
import { ArtemysTalentSkillManifest } from "artemys/openclaw"
|
|
181
|
+
```
|
|
173
182
|
|
|
174
|
-
|
|
175
|
-
- **Signing:** `agent_id.timestamp.body` with shared secret
|
|
176
|
-
- **Replay protection:** 5-minute timestamp window
|
|
177
|
-
- **Deduplication:** by sender + message ID
|
|
178
|
-
- **Retries:** exponential backoff (5 attempts, 60s cap)
|
|
183
|
+
Commands: `talent start`, `talent search`, `talent apply`, `talent status`, `talent profile`
|
|
179
184
|
|
|
180
|
-
|
|
185
|
+
See [OpenClaw Skill Guide](docs/openclaw-skill.md).
|
|
181
186
|
|
|
182
187
|
<br>
|
|
183
188
|
|
|
184
|
-
##
|
|
189
|
+
## Coffee Shop Service
|
|
190
|
+
|
|
191
|
+
Self-host the Coffee Shop server for development or testing:
|
|
185
192
|
|
|
186
193
|
```bash
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
artemys rotate-key # Rotate Coffee Shop API key
|
|
192
|
-
artemys intro-events # Show intro lifecycle events
|
|
193
|
-
artemys version # Print CLI package version
|
|
194
|
+
cd service
|
|
195
|
+
bun install
|
|
196
|
+
bun run migrate
|
|
197
|
+
vercel dev
|
|
194
198
|
```
|
|
195
199
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
## Project Structure
|
|
199
|
-
|
|
200
|
-
```
|
|
201
|
-
src/
|
|
202
|
-
protocol/ Zod schemas, state machine, message types
|
|
203
|
-
discovery/ Agent cards, queries, OpenAPI spec
|
|
204
|
-
transport/ HMAC client, server handler, dedup
|
|
205
|
-
coffeeshop/ Coffee Shop API client
|
|
206
|
-
mcp-server/ MCP tools (protocol, discovery, intro)
|
|
207
|
-
integrations/ Job board connectors
|
|
208
|
-
cli/ CLI commands
|
|
209
|
-
|
|
210
|
-
protocol/ Protocol spec, contracts, fixtures
|
|
211
|
-
service/ Coffee Shop service (Vercel)
|
|
212
|
-
```
|
|
200
|
+
Production deployment uses Vercel serverless + Turso (LibSQL).
|
|
213
201
|
|
|
214
202
|
<br>
|
|
215
203
|
|
|
@@ -223,49 +211,12 @@ bun run build # Build to dist/
|
|
|
223
211
|
bun run protocol:check # Run protocol contract tests
|
|
224
212
|
```
|
|
225
213
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
```bash
|
|
229
|
-
cd service
|
|
230
|
-
bun install
|
|
231
|
-
|
|
232
|
-
# Use durable DB mode
|
|
233
|
-
export ARTEMYS_DB_DRIVER=libsql
|
|
234
|
-
export TURSO_DATABASE_URL="libsql://..."
|
|
235
|
-
export TURSO_AUTH_TOKEN="..."
|
|
236
|
-
|
|
237
|
-
# Run schema migrations once per environment
|
|
238
|
-
bun run migrate
|
|
239
|
-
|
|
240
|
-
# Run service tests/type-check
|
|
241
|
-
bun run type-check
|
|
242
|
-
bun run test
|
|
243
|
-
|
|
244
|
-
# Optional: run coverage gate locally (same thresholded path as CI)
|
|
245
|
-
bun run test:coverage
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
Non-local runtimes fail closed if durable DB config is missing.
|
|
249
|
-
If you intentionally want non-local ephemeral mode, set:
|
|
250
|
-
|
|
251
|
-
```bash
|
|
252
|
-
export ARTEMYS_ALLOW_IN_MEMORY_DB=true
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
Metrics endpoint auth:
|
|
256
|
-
|
|
257
|
-
- Non-local runtimes require `ARTEMYS_METRICS_TOKEN`
|
|
258
|
-
- Local/test runtimes can leave it unset for local debugging
|
|
259
|
-
|
|
260
|
-
```bash
|
|
261
|
-
export ARTEMYS_METRICS_TOKEN="your-shared-metrics-token"
|
|
262
|
-
```
|
|
214
|
+
<br>
|
|
263
215
|
|
|
264
|
-
|
|
216
|
+
## Ecosystem
|
|
265
217
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
```
|
|
218
|
+
- [Artie](https://artie.app) — hosted candidate agent (for users without a personal AI)
|
|
219
|
+
- [Orion](https://github.com/artemyshq/orion) — employer talent agent platform
|
|
269
220
|
|
|
270
221
|
<br>
|
|
271
222
|
|
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAsfA,wBAAsB,MAAM,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCxE"}
|
package/dist/cli/index.js
CHANGED
|
@@ -5,8 +5,8 @@ import { pathToFileURL } from "node:url";
|
|
|
5
5
|
import { CoffeeShopClient } from "../coffeeshop/index.js";
|
|
6
6
|
import { AgentCardSchema, DiscoveryQuerySchema, } from "../discovery/index.js";
|
|
7
7
|
import { ConversationTracker, ProfileStore, SqliteMcpPersistence, createPersistentConversationTracker, createPersistentProfileStore, startArtemysMcpServer, } from "../mcp-server/index.js";
|
|
8
|
+
import { registerMessagingTools } from "../mcp-server/tools/messaging.js";
|
|
8
9
|
import { registerTalentTools } from "../mcp-server/tools/talent.js";
|
|
9
|
-
import { ProtocolTransportClient } from "../transport/index.js";
|
|
10
10
|
const DEFAULT_COFFEESHOP_URL = "https://coffeeshop.artemys.ai";
|
|
11
11
|
const DEFAULT_MAX_TRACKED_CONVERSATIONS = 1_000;
|
|
12
12
|
const DEFAULT_CONVERSATION_TTL_MS = 24 * 60 * 60 * 1000;
|
|
@@ -106,7 +106,6 @@ Commands:
|
|
|
106
106
|
register Register an agent card with Coffee Shop
|
|
107
107
|
discover Discover agents via Coffee Shop
|
|
108
108
|
rotate-key Rotate Coffee Shop API key
|
|
109
|
-
intro-events Show intro lifecycle events
|
|
110
109
|
version Show CLI version
|
|
111
110
|
help Show this help message
|
|
112
111
|
|
|
@@ -115,11 +114,10 @@ Examples:
|
|
|
115
114
|
artemys mcp-server --agent-card ./agent-card.json --persist
|
|
116
115
|
artemys register --agent-card ./agent-card.json
|
|
117
116
|
artemys discover --requester-agent-id agent-123 --role talent_agent
|
|
118
|
-
artemys talent search --agent-card ./agent-card.json --
|
|
119
|
-
artemys talent apply --agent-card ./agent-card.json --
|
|
117
|
+
artemys talent search --agent-card ./agent-card.json --limit 20
|
|
118
|
+
artemys talent apply --agent-card ./agent-card.json --job-id job-123 --persist
|
|
120
119
|
artemys talent profile --agent-card ./agent-card.json --profile-file ./candidate-profile.json --persist
|
|
121
120
|
artemys rotate-key --agent-id agent-123 --api-key old-key
|
|
122
|
-
artemys intro-events --intro-id intro-abc --api-key key
|
|
123
121
|
`);
|
|
124
122
|
}
|
|
125
123
|
function printTalentHelp() {
|
|
@@ -127,16 +125,16 @@ function printTalentHelp() {
|
|
|
127
125
|
artemys talent - Candidate talent workflow commands
|
|
128
126
|
|
|
129
127
|
Subcommands:
|
|
130
|
-
search
|
|
131
|
-
apply
|
|
132
|
-
status Check
|
|
128
|
+
search Search for matching job opportunities
|
|
129
|
+
apply Submit an application for a job posting
|
|
130
|
+
status Check inbox messages
|
|
133
131
|
profile Update stored candidate profile
|
|
134
132
|
help Show this help message
|
|
135
133
|
|
|
136
134
|
Examples:
|
|
137
|
-
artemys talent search --agent-card ./agent-card.json --
|
|
138
|
-
artemys talent apply --agent-card ./agent-card.json --
|
|
139
|
-
artemys talent status --agent-card ./agent-card.json --
|
|
135
|
+
artemys talent search --agent-card ./agent-card.json --limit 20
|
|
136
|
+
artemys talent apply --agent-card ./agent-card.json --job-id job-123 --match-reasoning "Strong backend fit"
|
|
137
|
+
artemys talent status --agent-card ./agent-card.json --unread-only --persist
|
|
140
138
|
artemys talent profile --agent-card ./agent-card.json --profile-file ./candidate-profile.json --sync-agent-card --persist ~/.artemys/state.db
|
|
141
139
|
|
|
142
140
|
Common flags:
|
|
@@ -159,15 +157,8 @@ function buildNetworkDeps(args, agentCard) {
|
|
|
159
157
|
apiKey: process.env.ARTEMYS_COFFEESHOP_API_KEY,
|
|
160
158
|
agentId: agentCard.agent_id,
|
|
161
159
|
});
|
|
162
|
-
const transportClient = new ProtocolTransportClient({
|
|
163
|
-
agentId: agentCard.agent_id,
|
|
164
|
-
getSharedSecret: loadSharedSecretResolver({
|
|
165
|
-
coffeeShopClient: hasCoffeeShopApiKey ? coffeeShopClient : undefined,
|
|
166
|
-
}),
|
|
167
|
-
});
|
|
168
160
|
return {
|
|
169
161
|
coffeeShopClient,
|
|
170
|
-
transportClient,
|
|
171
162
|
hasCoffeeShopApiKey,
|
|
172
163
|
};
|
|
173
164
|
}
|
|
@@ -199,11 +190,13 @@ function buildTalentState(flags) {
|
|
|
199
190
|
}
|
|
200
191
|
function buildTalentToolHandlers(deps) {
|
|
201
192
|
const handlers = new Map();
|
|
202
|
-
|
|
193
|
+
const mockServer = {
|
|
203
194
|
registerTool: (name, _config, handler) => {
|
|
204
195
|
handlers.set(name, handler);
|
|
205
196
|
},
|
|
206
|
-
}
|
|
197
|
+
};
|
|
198
|
+
registerTalentTools(mockServer, deps);
|
|
199
|
+
registerMessagingTools(mockServer, deps);
|
|
207
200
|
return handlers;
|
|
208
201
|
}
|
|
209
202
|
function extractToolResponseData(response) {
|
|
@@ -287,42 +280,6 @@ async function rotateKeyCommand(args) {
|
|
|
287
280
|
console.log(JSON.stringify(result, null, 2));
|
|
288
281
|
console.log("Save api_key now. It is only returned at rotation time.");
|
|
289
282
|
}
|
|
290
|
-
async function introEventsCommand(args) {
|
|
291
|
-
const introId = getFlagString(args.flags, "intro-id");
|
|
292
|
-
if (!introId) {
|
|
293
|
-
throw new Error("Missing required --intro-id <intro-id>");
|
|
294
|
-
}
|
|
295
|
-
const apiKey = getFlagString(args.flags, "api-key");
|
|
296
|
-
if (!apiKey) {
|
|
297
|
-
throw new Error("Missing required --api-key <api-key>");
|
|
298
|
-
}
|
|
299
|
-
const coffeeShopUrl = getFlagString(args.flags, "coffeeshop-url") ?? DEFAULT_COFFEESHOP_URL;
|
|
300
|
-
const client = new CoffeeShopClient({
|
|
301
|
-
baseUrl: coffeeShopUrl,
|
|
302
|
-
apiKey,
|
|
303
|
-
});
|
|
304
|
-
const events = await client.listIntroEvents(introId);
|
|
305
|
-
console.log(JSON.stringify(events, null, 2));
|
|
306
|
-
}
|
|
307
|
-
function loadSharedSecretResolver(options) {
|
|
308
|
-
const fallbackSecret = process.env.ARTEMYS_SHARED_SECRET;
|
|
309
|
-
const fromMap = process.env.ARTEMYS_SHARED_SECRETS;
|
|
310
|
-
const parsedMap = fromMap ? JSON.parse(fromMap) : {};
|
|
311
|
-
return async (targetHint) => {
|
|
312
|
-
const mapped = parsedMap[targetHint];
|
|
313
|
-
if (mapped) {
|
|
314
|
-
return mapped;
|
|
315
|
-
}
|
|
316
|
-
if (fallbackSecret) {
|
|
317
|
-
return fallbackSecret;
|
|
318
|
-
}
|
|
319
|
-
if (options.coffeeShopClient) {
|
|
320
|
-
const resolved = await options.coffeeShopClient.resolveTransportSharedSecret(targetHint);
|
|
321
|
-
return resolved.value;
|
|
322
|
-
}
|
|
323
|
-
throw new Error(`No shared secret found for '${targetHint}'. Set ARTEMYS_SHARED_SECRETS/ARTEMYS_SHARED_SECRET or provide ARTEMYS_COFFEESHOP_API_KEY with accepted intro bootstrap.`);
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
283
|
async function mcpServerCommand(args) {
|
|
327
284
|
const cardPath = getFlagString(args.flags, "agent-card");
|
|
328
285
|
if (!cardPath) {
|
|
@@ -333,19 +290,14 @@ async function mcpServerCommand(args) {
|
|
|
333
290
|
const port = portRaw ? Number.parseInt(portRaw, 10) : 3100;
|
|
334
291
|
const persist = getPersistOption(args.flags);
|
|
335
292
|
const agentCard = await readAgentCardFromPath(cardPath);
|
|
336
|
-
const { coffeeShopClient
|
|
293
|
+
const { coffeeShopClient } = buildNetworkDeps(args, agentCard);
|
|
337
294
|
const started = await startArtemysMcpServer({
|
|
338
295
|
agentCard,
|
|
339
296
|
coffeeShopClient,
|
|
340
|
-
transportClient,
|
|
341
297
|
transport,
|
|
342
298
|
port,
|
|
343
299
|
...(persist ? { persist } : {}),
|
|
344
|
-
enableIntroTools: hasCoffeeShopApiKey,
|
|
345
300
|
});
|
|
346
|
-
if (!hasCoffeeShopApiKey) {
|
|
347
|
-
console.error("Artemys MCP intro tools disabled (set ARTEMYS_COFFEESHOP_API_KEY to enable intro APIs)");
|
|
348
|
-
}
|
|
349
301
|
if (transport === "sse") {
|
|
350
302
|
console.error(`Artemys MCP server listening on http://127.0.0.1:${port}/mcp`);
|
|
351
303
|
}
|
|
@@ -367,60 +319,40 @@ async function talentCommand(args) {
|
|
|
367
319
|
throw new Error("Missing required --agent-card <path>");
|
|
368
320
|
}
|
|
369
321
|
const agentCard = await readAgentCardFromPath(cardPath);
|
|
370
|
-
const { coffeeShopClient
|
|
322
|
+
const { coffeeShopClient } = buildNetworkDeps(args, agentCard);
|
|
371
323
|
const state = buildTalentState(args.flags);
|
|
372
324
|
try {
|
|
373
325
|
const handlers = buildTalentToolHandlers({
|
|
374
326
|
coffeeShopClient,
|
|
375
|
-
transportClient,
|
|
376
327
|
tracker: state.tracker,
|
|
377
328
|
profileStore: state.profileStore,
|
|
378
329
|
agentCard,
|
|
379
|
-
introToolsEnabled: hasCoffeeShopApiKey,
|
|
380
330
|
});
|
|
381
331
|
if (subcommand === "search") {
|
|
382
|
-
const roleKeywords = getCsvFlagList(args.flags, "role-keywords");
|
|
383
|
-
const location = getFlagString(args.flags, "location");
|
|
384
|
-
const remoteOk = getFlagBoolean(args.flags, "remote-ok");
|
|
385
|
-
const seniority = getFlagString(args.flags, "seniority");
|
|
386
332
|
const limitRaw = getFlagString(args.flags, "limit");
|
|
387
333
|
const data = await invokeTalentTool(handlers, "search_opportunities", {
|
|
388
|
-
...(roleKeywords ? { role_keywords: roleKeywords } : {}),
|
|
389
|
-
...(location ? { location } : {}),
|
|
390
|
-
...(typeof remoteOk === "boolean" ? { remote_ok: remoteOk } : {}),
|
|
391
|
-
...(seniority ? { seniority } : {}),
|
|
392
334
|
...(limitRaw ? { limit: Number.parseInt(limitRaw, 10) } : {}),
|
|
393
335
|
});
|
|
394
336
|
console.log(JSON.stringify(data, null, 2));
|
|
395
337
|
return;
|
|
396
338
|
}
|
|
397
339
|
if (subcommand === "apply") {
|
|
398
|
-
const
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
if (!targetAgentId) {
|
|
402
|
-
throw new Error("Missing required --target-agent-id <agent-id>");
|
|
403
|
-
}
|
|
404
|
-
if (!targetEndpoint) {
|
|
405
|
-
throw new Error("Missing required --target-endpoint <url>");
|
|
406
|
-
}
|
|
407
|
-
if (!jobPostingRef) {
|
|
408
|
-
throw new Error("Missing required --job-posting-ref <job-ref>");
|
|
340
|
+
const jobId = getFlagString(args.flags, "job-id");
|
|
341
|
+
if (!jobId) {
|
|
342
|
+
throw new Error("Missing required --job-id <job-id>");
|
|
409
343
|
}
|
|
410
344
|
const matchReasoning = getFlagString(args.flags, "match-reasoning");
|
|
411
345
|
const data = await invokeTalentTool(handlers, "express_interest", {
|
|
412
|
-
|
|
413
|
-
target_endpoint: targetEndpoint,
|
|
414
|
-
job_posting_ref: jobPostingRef,
|
|
346
|
+
job_id: jobId,
|
|
415
347
|
...(matchReasoning ? { match_reasoning: matchReasoning } : {}),
|
|
416
348
|
});
|
|
417
349
|
console.log(JSON.stringify(data, null, 2));
|
|
418
350
|
return;
|
|
419
351
|
}
|
|
420
352
|
if (subcommand === "status") {
|
|
421
|
-
const
|
|
422
|
-
const data = await invokeTalentTool(handlers, "
|
|
423
|
-
...(
|
|
353
|
+
const unreadOnly = getFlagBoolean(args.flags, "unread-only");
|
|
354
|
+
const data = await invokeTalentTool(handlers, "check_inbox", {
|
|
355
|
+
...(typeof unreadOnly === "boolean" ? { unread_only: unreadOnly } : {}),
|
|
424
356
|
});
|
|
425
357
|
console.log(JSON.stringify(data, null, 2));
|
|
426
358
|
return;
|
|
@@ -478,10 +410,6 @@ export async function runCli(argv = process.argv.slice(2)) {
|
|
|
478
410
|
await rotateKeyCommand(args);
|
|
479
411
|
return;
|
|
480
412
|
}
|
|
481
|
-
if (command === "intro-events") {
|
|
482
|
-
await introEventsCommand(args);
|
|
483
|
-
return;
|
|
484
|
-
}
|
|
485
413
|
if (command === "mcp-server") {
|
|
486
414
|
await mcpServerCommand(args);
|
|
487
415
|
return;
|