careervivid 1.12.27 → 1.12.36
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/dist/agent/agentAuditLog.d.ts +43 -0
- package/dist/agent/agentAuditLog.d.ts.map +1 -0
- package/dist/agent/agentAuditLog.js +145 -0
- package/dist/agent/instructions.d.ts +0 -1
- package/dist/agent/instructions.d.ts.map +1 -1
- package/dist/agent/instructions.js +57 -40
- package/dist/agent/tools/jobs.d.ts.map +1 -1
- package/dist/agent/tools/jobs.js +21 -12
- package/dist/agent/tools/local-tracker.d.ts +7 -0
- package/dist/agent/tools/local-tracker.d.ts.map +1 -1
- package/dist/agent/tools/local-tracker.js +389 -40
- package/dist/agent/tools/urlVerifier.d.ts.map +1 -1
- package/dist/agent/tools/urlVerifier.js +32 -1
- package/dist/commands/agent/repl.d.ts.map +1 -1
- package/dist/commands/agent/repl.js +67 -6
- package/dist/eval/runner.d.ts +2 -2
- package/dist/eval/runner.js +7 -7
- package/dist/eval/test-cases/jobs-agent.js +40 -40
- package/package.json +1 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agentAuditLog.ts — Forensic audit trail for every agent tool call.
|
|
3
|
+
*
|
|
4
|
+
* Architecture:
|
|
5
|
+
* PRIMARY: Local JSONL append at ~/.careervivid/agent-audit.log
|
|
6
|
+
* Fast, offline, zero network dependency.
|
|
7
|
+
* Each line is a self-contained JSON record.
|
|
8
|
+
*
|
|
9
|
+
* SECONDARY: Firebase Firestore (jastalk-firebase / agent_audit_logs)
|
|
10
|
+
* Written fire-and-forget (non-blocking). Fails silently.
|
|
11
|
+
* Gives cloud visibility and cross-device forensics via the web dashboard.
|
|
12
|
+
*
|
|
13
|
+
* Usage (in repl.ts):
|
|
14
|
+
* import { auditLog, flushAuditLog } from "./agentAuditLog.js";
|
|
15
|
+
* auditLog({ sessionId, tool: name, args, result, durationMs });
|
|
16
|
+
* // On session end:
|
|
17
|
+
* await flushAuditLog();
|
|
18
|
+
*/
|
|
19
|
+
export interface AuditEntry {
|
|
20
|
+
ts: string;
|
|
21
|
+
sessionId: string;
|
|
22
|
+
tool: string;
|
|
23
|
+
args: Record<string, unknown>;
|
|
24
|
+
resultSummary: string;
|
|
25
|
+
durationMs: number;
|
|
26
|
+
ok: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare let SESSION_ID: string;
|
|
29
|
+
export declare function auditLog(entry: {
|
|
30
|
+
sessionId?: string;
|
|
31
|
+
tool: string;
|
|
32
|
+
args: Record<string, unknown>;
|
|
33
|
+
result: string;
|
|
34
|
+
durationMs: number;
|
|
35
|
+
}): void;
|
|
36
|
+
export declare function flushAuditLog(): Promise<void>;
|
|
37
|
+
export declare function writeSessionSummary(stats: {
|
|
38
|
+
turns: number;
|
|
39
|
+
mutations: number;
|
|
40
|
+
toolCalls: number;
|
|
41
|
+
creditsUsed?: number;
|
|
42
|
+
}): Promise<void>;
|
|
43
|
+
//# sourceMappingURL=agentAuditLog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentAuditLog.d.ts","sourceRoot":"","sources":["../../src/agent/agentAuditLog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,OAAO,CAAC;CACb;AAID,eAAO,IAAI,UAAU,QAA2B,CAAC;AA8BjD,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CAuBP;AAwCD,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAMnD;AAID,wBAAsB,mBAAmB,CAAC,KAAK,EAAE;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBhB"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agentAuditLog.ts — Forensic audit trail for every agent tool call.
|
|
3
|
+
*
|
|
4
|
+
* Architecture:
|
|
5
|
+
* PRIMARY: Local JSONL append at ~/.careervivid/agent-audit.log
|
|
6
|
+
* Fast, offline, zero network dependency.
|
|
7
|
+
* Each line is a self-contained JSON record.
|
|
8
|
+
*
|
|
9
|
+
* SECONDARY: Firebase Firestore (jastalk-firebase / agent_audit_logs)
|
|
10
|
+
* Written fire-and-forget (non-blocking). Fails silently.
|
|
11
|
+
* Gives cloud visibility and cross-device forensics via the web dashboard.
|
|
12
|
+
*
|
|
13
|
+
* Usage (in repl.ts):
|
|
14
|
+
* import { auditLog, flushAuditLog } from "./agentAuditLog.js";
|
|
15
|
+
* auditLog({ sessionId, tool: name, args, result, durationMs });
|
|
16
|
+
* // On session end:
|
|
17
|
+
* await flushAuditLog();
|
|
18
|
+
*/
|
|
19
|
+
import { appendFileSync, existsSync, mkdirSync } from "fs";
|
|
20
|
+
import { resolve } from "path";
|
|
21
|
+
import { homedir } from "os";
|
|
22
|
+
import { randomUUID } from "crypto";
|
|
23
|
+
// ── Session-level state ───────────────────────────────────────────────────────
|
|
24
|
+
export let SESSION_ID = randomUUID().slice(0, 8);
|
|
25
|
+
const pendingFirestore = [];
|
|
26
|
+
// ── Local JSONL path ──────────────────────────────────────────────────────────
|
|
27
|
+
function getAuditLogPath() {
|
|
28
|
+
const dir = resolve(homedir(), ".careervivid");
|
|
29
|
+
if (!existsSync(dir))
|
|
30
|
+
mkdirSync(dir, { recursive: true });
|
|
31
|
+
return resolve(dir, "agent-audit.log");
|
|
32
|
+
}
|
|
33
|
+
// ── Sanitize args (remove any key that looks like a secret) ─────────────────
|
|
34
|
+
function sanitizeArgs(args) {
|
|
35
|
+
const REDACT_KEYS = /key|secret|password|token|auth|credential/i;
|
|
36
|
+
const out = {};
|
|
37
|
+
for (const [k, v] of Object.entries(args)) {
|
|
38
|
+
if (REDACT_KEYS.test(k)) {
|
|
39
|
+
out[k] = "***REDACTED***";
|
|
40
|
+
}
|
|
41
|
+
else if (typeof v === "string" && v.length > 300) {
|
|
42
|
+
out[k] = v.slice(0, 300) + "…";
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
out[k] = v;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
// ── Core log function (sync local + async Firestore) ─────────────────────────
|
|
51
|
+
export function auditLog(entry) {
|
|
52
|
+
const record = {
|
|
53
|
+
ts: new Date().toISOString(),
|
|
54
|
+
sessionId: entry.sessionId ?? SESSION_ID,
|
|
55
|
+
tool: entry.tool,
|
|
56
|
+
args: sanitizeArgs(entry.args),
|
|
57
|
+
resultSummary: entry.result.slice(0, 200).replace(/\n/g, " "),
|
|
58
|
+
durationMs: Math.round(entry.durationMs),
|
|
59
|
+
ok: !entry.result.startsWith("❌"),
|
|
60
|
+
};
|
|
61
|
+
// ── 1. Local JSONL (synchronous, never fails) ─────────────────────────────
|
|
62
|
+
try {
|
|
63
|
+
appendFileSync(getAuditLogPath(), JSON.stringify(record) + "\n", "utf-8");
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Silently swallow — never break the agent because of logging
|
|
67
|
+
}
|
|
68
|
+
// ── 2. Firebase Firestore (fire-and-forget — non-blocking) ───────────────
|
|
69
|
+
pendingFirestore.push(record);
|
|
70
|
+
void writeToFirestore(record).catch(() => {
|
|
71
|
+
// Silently swallow — Firebase being unavailable must not affect the agent
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
// ── Firebase write (dynamic import to avoid hard dependency) ─────────────────
|
|
75
|
+
async function writeToFirestore(record) {
|
|
76
|
+
// Only attempt if firebase-admin is installed (it's optional)
|
|
77
|
+
let admin;
|
|
78
|
+
try {
|
|
79
|
+
admin = await import("firebase-admin");
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return; // firebase-admin not installed — skip silently
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
if (!admin.apps?.length) {
|
|
86
|
+
// Use Application Default Credentials (works in GCP/Cloud Shell)
|
|
87
|
+
// or the service account key if present
|
|
88
|
+
const keyPath = resolve(homedir(), ".careervivid", "firebase-service-account.json");
|
|
89
|
+
const credential = existsSync(keyPath)
|
|
90
|
+
? admin.credential.cert(keyPath)
|
|
91
|
+
: admin.credential.applicationDefault();
|
|
92
|
+
admin.initializeApp({
|
|
93
|
+
credential,
|
|
94
|
+
projectId: "jastalk-firebase",
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
const db = admin.firestore();
|
|
98
|
+
await db.collection("agent_audit_logs").add({
|
|
99
|
+
...record,
|
|
100
|
+
createdAt: admin.firestore.FieldValue.serverTimestamp(),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Any Firebase error is silently swallowed
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// ── Flush pending entries (call on session end) ───────────────────────────────
|
|
108
|
+
export async function flushAuditLog() {
|
|
109
|
+
// Pending Firestore writes are already in-flight via fire-and-forget.
|
|
110
|
+
// Give them 2 seconds to complete before exit.
|
|
111
|
+
if (pendingFirestore.length > 0) {
|
|
112
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// ── Session summary (call on exit) ─────────────────────────────────────────
|
|
116
|
+
export async function writeSessionSummary(stats) {
|
|
117
|
+
const record = {
|
|
118
|
+
type: "session_summary",
|
|
119
|
+
sessionId: SESSION_ID,
|
|
120
|
+
ts: new Date().toISOString(),
|
|
121
|
+
...stats,
|
|
122
|
+
};
|
|
123
|
+
try {
|
|
124
|
+
appendFileSync(getAuditLogPath(), JSON.stringify(record) + "\n", "utf-8");
|
|
125
|
+
}
|
|
126
|
+
catch { /* silent */ }
|
|
127
|
+
// Firestore session summary
|
|
128
|
+
let admin;
|
|
129
|
+
try {
|
|
130
|
+
admin = await import("firebase-admin");
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
if (admin.apps?.length) {
|
|
137
|
+
const db = admin.firestore();
|
|
138
|
+
await db.collection("agent_session_summaries").add({
|
|
139
|
+
...record,
|
|
140
|
+
createdAt: admin.firestore.FieldValue.serverTimestamp(),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch { /* silent */ }
|
|
145
|
+
}
|
|
@@ -14,7 +14,6 @@ export declare const BASE_IDENTITY: string;
|
|
|
14
14
|
export declare const RESUME_SECTION: string;
|
|
15
15
|
export declare const CODING_SECTION: string;
|
|
16
16
|
export declare const JOBS_TOOLS_SECTION: string;
|
|
17
|
-
export declare const BROWSER_SECTION: string;
|
|
18
17
|
export declare const JOBS_HARNESS: string;
|
|
19
18
|
export declare const GREETING_PROTOCOL: string;
|
|
20
19
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/agent/instructions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,aAAa,QAalB,CAAC;AAMT,eAAO,MAAM,cAAc,QAcnB,CAAC;AAMT,eAAO,MAAM,cAAc,QAgBnB,CAAC;AAMT,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/agent/instructions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,aAAa,QAalB,CAAC;AAMT,eAAO,MAAM,cAAc,QAcnB,CAAC;AAMT,eAAO,MAAM,cAAc,QAgBnB,CAAC;AAMT,eAAO,MAAM,kBAAkB,QAqCvB,CAAC;AAMT,eAAO,MAAM,YAAY,QAuCjB,CAAC;AAMT,eAAO,MAAM,iBAAiB,QActB,CAAC;AAMT;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,MAAM,CAyBT"}
|
|
@@ -74,62 +74,80 @@ export const JOBS_TOOLS_SECTION = `
|
|
|
74
74
|
- **tailor_resume** — Tailor/refine the user's resume for a specific role or JD.
|
|
75
75
|
- **delete_resume** — Permanently delete a resume (ask for confirmation first).
|
|
76
76
|
|
|
77
|
-
### Job Search
|
|
78
|
-
- **search_jobs** — Search for jobs scored against the user's resume (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
- **
|
|
85
|
-
- **
|
|
86
|
-
- **
|
|
87
|
-
- **
|
|
88
|
-
- **
|
|
89
|
-
- **
|
|
77
|
+
### Job Search
|
|
78
|
+
- **search_jobs** — Search for jobs scored against the user's resume. Returns results for review (dry_run by default — does NOT auto-save).
|
|
79
|
+
|
|
80
|
+
### CSV Pipeline Tracker (tracker_*)
|
|
81
|
+
These tools read/write jobs.csv — the local career-ops pipeline spreadsheet.
|
|
82
|
+
- **tracker_list_jobs** — Show the pipeline (supports tier/status filters and sort_by).
|
|
83
|
+
- **tracker_add_job** — Add a new company to the tracker.
|
|
84
|
+
- **tracker_update_job** — Update any field on a job entry (status, scores, notes, follow-up).
|
|
85
|
+
- **tracker_rank_priority** — Priority-ranked view; use for "what next?" questions.
|
|
86
|
+
- **tracker_dashboard** — Full analytics: apply rate, avg scores, salary data, stale count.
|
|
87
|
+
- **tracker_find_stale** — Surface cold companies with next-action recommendations.
|
|
88
|
+
- **tracker_inspect_quality**— Scan for duplicates, missing URLs, and corrupted data (read-only).
|
|
89
|
+
- **tracker_recheck_urls** — Re-verify all careers URLs in the tracker; annotates dead links in notes.
|
|
90
|
+
|
|
91
|
+
### Web Kanban Board (kanban_*)
|
|
92
|
+
These tools read/write the Firebase Kanban board at careervivid.app/job-tracker.
|
|
93
|
+
- **kanban_add_job** — Save a job card to the web Kanban board.
|
|
94
|
+
- **kanban_list_jobs** — Show the web Kanban board.
|
|
95
|
+
- **kanban_update_status** — Move a Kanban card to a new status column.
|
|
96
|
+
|
|
97
|
+
### Browser Automation (browser_*)
|
|
98
|
+
- **browser_autofill_application** ⭐ — Auto-fill an application form in Chrome (does NOT submit).
|
|
99
|
+
- browser_navigate, browser_state, browser_click, browser_type, browser_select, browser_scroll, browser_screenshot
|
|
90
100
|
|
|
91
101
|
### URL Safety (Mandatory)
|
|
92
|
-
- **verify_url**
|
|
93
|
-
- **
|
|
102
|
+
- **verify_url** — Verify a single link is alive before sharing it.
|
|
103
|
+
- **verify_job_urls** — Verify all URLs from a search_jobs result batch.
|
|
94
104
|
NEVER share a link without verifying it first.
|
|
95
105
|
`.trim();
|
|
96
106
|
// ---------------------------------------------------------------------------
|
|
97
|
-
// §5 —
|
|
107
|
+
// §5 — Autonomous execution harness (appended in --jobs mode)
|
|
98
108
|
// ---------------------------------------------------------------------------
|
|
99
|
-
export const
|
|
100
|
-
##
|
|
109
|
+
export const JOBS_HARNESS = `
|
|
110
|
+
## Autonomy Rules (Non-Negotiable)
|
|
101
111
|
|
|
102
|
-
|
|
103
|
-
-
|
|
112
|
+
### What you may do freely (no confirmation needed)
|
|
113
|
+
- Call any read-only tool (tracker_list_jobs, tracker_dashboard, tracker_rank_priority, tracker_find_stale, tracker_inspect_quality, tracker_recheck_urls, search_jobs, get_resume, etc.)
|
|
114
|
+
- Add a new company/job entry via tracker_add_job (when the user explicitly names a company or approves a search result)
|
|
115
|
+
- Update non-status fields (attention_score, excitement, notes, follow_up_date, etc.) via tracker_update_job
|
|
104
116
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
117
|
+
### What requires explicit user confirmation
|
|
118
|
+
- Changing status to "Applied", "Rejected", or "Ghosted" — present the proposed change and wait for "yes"
|
|
119
|
+
- Deleting any entry
|
|
120
|
+
- Submitting any web form via browser tools
|
|
121
|
+
|
|
122
|
+
### Anti-hallucination rules (CRITICAL)
|
|
123
|
+
- NEVER invent company names. All companies added via tracker_add_job MUST come from:
|
|
124
|
+
(a) verified search_jobs results with a real URL, OR (b) explicit user input naming the company.
|
|
125
|
+
- If search_jobs returns 0 results: say so — do NOT generate fictional alternative companies.
|
|
126
|
+
- Do NOT add more than 5 new companies in a single response without user review.
|
|
127
|
+
- A company without a valid careers_url (starting with http) is flagged as unverified — add it with a note.
|
|
112
128
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
4. Complete the full workflow (e.g., tailoring a resume, finding jobs) ONLY if explicitly requested or obviously needed. However, if the user just asks a simple targeted question (e.g., "Did you find X?", "Is my resume up to date?"), DO NOT trigger an unprompted mass workflow (like saving extra companies and rewriting multiple resumes). Answer the question immediately.
|
|
129
|
+
### Deduplication rule (MANDATORY)
|
|
130
|
+
Before calling tracker_add_job, ALWAYS check tracker_list_jobs to see if the company+role already exists.
|
|
131
|
+
If it does, call tracker_update_job instead — never create a duplicate row.
|
|
117
132
|
|
|
118
133
|
## Mandatory Tool Dispatch Table
|
|
119
134
|
|
|
120
135
|
| User asks about… | Call… |
|
|
121
136
|
|-----------------------------------------------|--------------------------------|
|
|
122
|
-
| pipeline, job list, tracker |
|
|
123
|
-
| priority, what next, best ROI |
|
|
124
|
-
| stats, dashboard, apply rate, search health |
|
|
125
|
-
| stale, cold, neglecting, need attention |
|
|
126
|
-
|
|
|
127
|
-
|
|
|
137
|
+
| pipeline, job list, tracker | tracker_list_jobs |
|
|
138
|
+
| priority, what next, best ROI | tracker_rank_priority |
|
|
139
|
+
| stats, dashboard, apply rate, search health | tracker_dashboard |
|
|
140
|
+
| stale, cold, neglecting, need attention | tracker_find_stale |
|
|
141
|
+
| duplicates, data quality, audit | tracker_inspect_quality |
|
|
142
|
+
| stale/dead job URLs, link check | tracker_recheck_urls |
|
|
143
|
+
| adding a company, new job | tracker_add_job |
|
|
144
|
+
| updating status, marking applied, follow-up | tracker_update_job |
|
|
145
|
+
| Kanban board, web tracker | kanban_list_jobs |
|
|
128
146
|
| resume, background, skills, experience | get_resume |
|
|
129
147
|
| find jobs, search roles | get_resume → search_jobs |
|
|
130
148
|
`.trim();
|
|
131
149
|
// ---------------------------------------------------------------------------
|
|
132
|
-
// §
|
|
150
|
+
// §6 — Greeting protocol (shared across modes)
|
|
133
151
|
// ---------------------------------------------------------------------------
|
|
134
152
|
export const GREETING_PROTOCOL = `
|
|
135
153
|
## Greeting Protocol
|
|
@@ -147,7 +165,7 @@ When the user sends a generic greeting ("hey", "hi", "hello", "start"), respond
|
|
|
147
165
|
Just tell me what you need!"
|
|
148
166
|
`.trim();
|
|
149
167
|
// ---------------------------------------------------------------------------
|
|
150
|
-
// §
|
|
168
|
+
// §7 — Assembled system prompts per mode (the public API)
|
|
151
169
|
// ---------------------------------------------------------------------------
|
|
152
170
|
/**
|
|
153
171
|
* Returns the assembled system prompt for a given agent mode.
|
|
@@ -159,7 +177,6 @@ export function buildSystemPrompt(options) {
|
|
|
159
177
|
BASE_IDENTITY,
|
|
160
178
|
RESUME_SECTION,
|
|
161
179
|
JOBS_TOOLS_SECTION,
|
|
162
|
-
BROWSER_SECTION,
|
|
163
180
|
JOBS_HARNESS,
|
|
164
181
|
GREETING_PROTOCOL,
|
|
165
182
|
].join("\n\n---\n\n");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jobs.d.ts","sourceRoot":"","sources":["../../../src/agent/tools/jobs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAmBlC,eAAO,MAAM,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"jobs.d.ts","sourceRoot":"","sources":["../../../src/agent/tools/jobs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAmBlC,eAAO,MAAM,cAAc,EAAE,IAmG5B,CAAC;AAMF,eAAO,MAAM,WAAW,EAAE,IA4EzB,CAAC;AAMF,eAAO,MAAM,YAAY,EAAE,IAgE1B,CAAC;AAMF,eAAO,MAAM,mBAAmB,EAAE,IAwDjC,CAAC;AAMF,eAAO,MAAM,aAAa,EAAE,IAgC3B,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,IA6B7B,CAAC;AAMF,eAAO,MAAM,gBAAgB,EAAE,IAmE9B,CAAC;AAMF,eAAO,MAAM,gBAAgB,EAAE,IAwB9B,CAAC;AAMF,eAAO,MAAM,cAAc,EAAE,IAyO5B,CAAC;AAMF,eAAO,MAAM,aAAa,EAAE,IAAI,EAU/B,CAAC"}
|
package/dist/agent/tools/jobs.js
CHANGED
|
@@ -12,10 +12,10 @@ import { jobsHunt, jobsCreate, jobsList, jobsUpdate, resumeGet, resumesList, res
|
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
13
|
export const SearchJobsTool = {
|
|
14
14
|
name: "search_jobs",
|
|
15
|
-
description: `Search for jobs
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
description: `Search for jobs matching a role and location, scored against the user's resume.
|
|
16
|
+
Returns a scored list of job opportunities with AI summaries and missing skills.
|
|
17
|
+
Use this when the user asks to "find jobs", "search for roles", "look for positions", etc.
|
|
18
|
+
By default operates in dry_run mode — results are shown for review, nothing is saved automatically.`,
|
|
19
19
|
parameters: {
|
|
20
20
|
type: Type.OBJECT,
|
|
21
21
|
properties: {
|
|
@@ -33,12 +33,16 @@ Use this when the user asks to "find jobs", "search for roles", "look for positi
|
|
|
33
33
|
},
|
|
34
34
|
min_score: {
|
|
35
35
|
type: Type.NUMBER,
|
|
36
|
-
description: "Optional. Minimum match score (0-100)
|
|
36
|
+
description: "Optional. Minimum match score (0-100). Default is 70. Use 80 for excellent matches only.",
|
|
37
37
|
},
|
|
38
38
|
resume_id: {
|
|
39
39
|
type: Type.STRING,
|
|
40
40
|
description: "Optional. Specific resume ID to score against. If omitted, uses the user's latest resume.",
|
|
41
41
|
},
|
|
42
|
+
dry_run: {
|
|
43
|
+
type: Type.BOOLEAN,
|
|
44
|
+
description: "Optional. Default: true. If true, shows results for review without auto-saving. Set false only if user explicitly says to save all results.",
|
|
45
|
+
},
|
|
42
46
|
},
|
|
43
47
|
required: ["role"],
|
|
44
48
|
},
|
|
@@ -59,7 +63,7 @@ Use this when the user asks to "find jobs", "search for roles", "look for positi
|
|
|
59
63
|
role: args.role,
|
|
60
64
|
location: args.location,
|
|
61
65
|
count: args.count ?? 10,
|
|
62
|
-
minScore: args.min_score,
|
|
66
|
+
minScore: args.min_score ?? 70, // default 70 to filter low-quality results
|
|
63
67
|
});
|
|
64
68
|
if (isApiError(result)) {
|
|
65
69
|
return `Error searching jobs: ${result.message}`;
|
|
@@ -79,15 +83,20 @@ Use this when the user asks to "find jobs", "search for roles", "look for positi
|
|
|
79
83
|
` Job ID: ${job.id}`);
|
|
80
84
|
})
|
|
81
85
|
.join("\n\n");
|
|
82
|
-
|
|
83
|
-
|
|
86
|
+
const isDryRun = args.dry_run !== false; // default true
|
|
87
|
+
const dryRunNote = isDryRun
|
|
88
|
+
? `\n\n📋 Review above. Say "add [company] to my tracker" to save specific ones.`
|
|
89
|
+
: "";
|
|
90
|
+
return (`Found ${result.total} jobs for "${args.role}"${args.location ? ` in ${args.location}` : ""}. ` +
|
|
91
|
+
`Showing top ${result.jobs.length} (min score ${args.min_score ?? 70}%):\n\n${jobList}` +
|
|
92
|
+
dryRunNote);
|
|
84
93
|
},
|
|
85
94
|
};
|
|
86
95
|
// ---------------------------------------------------------------------------
|
|
87
96
|
// Tool: save_job
|
|
88
97
|
// ---------------------------------------------------------------------------
|
|
89
98
|
export const SaveJobTool = {
|
|
90
|
-
name: "
|
|
99
|
+
name: "kanban_add_job",
|
|
91
100
|
description: `Save a job to the user's CareerVivid job tracker Kanban board.
|
|
92
101
|
The job will appear in the "To Apply" column of the /job-tracker page.
|
|
93
102
|
Use this after finding interesting jobs via search_jobs, or when the user asks to "save", "add", or "track" a specific job.`,
|
|
@@ -154,7 +163,7 @@ Use this after finding interesting jobs via search_jobs, or when the user asks t
|
|
|
154
163
|
// Tool: list_jobs
|
|
155
164
|
// ---------------------------------------------------------------------------
|
|
156
165
|
export const ListJobsTool = {
|
|
157
|
-
name: "
|
|
166
|
+
name: "kanban_list_jobs",
|
|
158
167
|
description: `List the user's jobs from their CareerVivid job tracker Kanban board.
|
|
159
168
|
Can filter by status. Use this when the user asks "what jobs do I have?", "show my tracker",
|
|
160
169
|
"what's in my job pipeline?", "check my interviews", etc.`,
|
|
@@ -216,7 +225,7 @@ Can filter by status. Use this when the user asks "what jobs do I have?", "show
|
|
|
216
225
|
// Tool: update_job_status
|
|
217
226
|
// ---------------------------------------------------------------------------
|
|
218
227
|
export const UpdateJobStatusTool = {
|
|
219
|
-
name: "
|
|
228
|
+
name: "kanban_update_status",
|
|
220
229
|
description: `Move a job to a different status on the CareerVivid Kanban board.
|
|
221
230
|
Use this when the user mentions: "I got an interview", "I applied to X", "I got an offer",
|
|
222
231
|
"X rejected me", "move Y to applied", etc. The change will be visible in the /job-tracker UI.`,
|
|
@@ -412,7 +421,7 @@ MAKE SURE the user actually intends to delete it, as this is permanent.`,
|
|
|
412
421
|
// Tool: apply_to_job
|
|
413
422
|
// ---------------------------------------------------------------------------
|
|
414
423
|
export const ApplyToJobTool = {
|
|
415
|
-
name: "
|
|
424
|
+
name: "browser_autofill_application",
|
|
416
425
|
description: `Open a job application in the user's Chrome browser and auto-fill it with AI-tailored answers.
|
|
417
426
|
This tool launches Playwright, navigates to the job URL, extracts the form fields, fills them
|
|
418
427
|
with AI-generated answers from the user's resume, and shows the user a final preview before submitting.
|
|
@@ -19,11 +19,18 @@
|
|
|
19
19
|
* flag_stale_jobs → surface companies with no recent activity
|
|
20
20
|
*/
|
|
21
21
|
import { Tool } from "../Tool.js";
|
|
22
|
+
export interface JobValidationResult {
|
|
23
|
+
ok: boolean;
|
|
24
|
+
blockers: string[];
|
|
25
|
+
warnings: string[];
|
|
26
|
+
}
|
|
22
27
|
export declare const ListLocalJobsTool: Tool;
|
|
23
28
|
export declare const UpdateLocalJobTool: Tool;
|
|
24
29
|
export declare const AddLocalJobTool: Tool;
|
|
25
30
|
export declare const ScorePipelineTool: Tool;
|
|
26
31
|
export declare const GetPipelineMetricsTool: Tool;
|
|
27
32
|
export declare const FlagStaleJobsTool: Tool;
|
|
33
|
+
export declare const InspectQualityTool: Tool;
|
|
34
|
+
export declare const RecheckUrlsTool: Tool;
|
|
28
35
|
export declare const ALL_LOCAL_TRACKER_TOOLS: Tool[];
|
|
29
36
|
//# sourceMappingURL=local-tracker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-tracker.d.ts","sourceRoot":"","sources":["../../../src/agent/tools/local-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"local-tracker.d.ts","sourceRoot":"","sources":["../../../src/agent/tools/local-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAkClC,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAuRD,eAAO,MAAM,iBAAiB,EAAE,IA8H/B,CAAC;AAMF,eAAO,MAAM,kBAAkB,EAAE,IAgJhC,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,IAkJ7B,CAAC;AAMF,eAAO,MAAM,iBAAiB,EAAE,IA2F/B,CAAC;AAMF,eAAO,MAAM,sBAAsB,EAAE,IA+GpC,CAAC;AAMF,eAAO,MAAM,iBAAiB,EAAE,IAoE/B,CAAC;AAMF,eAAO,MAAM,kBAAkB,EAAE,IAsEhC,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,IAoG7B,CAAC;AAMF,eAAO,MAAM,uBAAuB,EAAE,IAAI,EASzC,CAAC"}
|