@ouro.bot/cli 0.1.0-alpha.49 → 0.1.0-alpha.491
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 +133 -19
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
- package/changelog.json +3126 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +140 -0
- package/dist/arc/episodes.js +117 -0
- package/dist/arc/intentions.js +133 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +237 -0
- package/dist/arc/packets.js +193 -0
- package/dist/arc/presence.js +185 -0
- package/dist/arc/task-lifecycle.js +65 -0
- package/dist/heart/active-work.js +989 -0
- package/dist/heart/agent-entry.js +58 -3
- package/dist/heart/attachments/image-normalize.js +194 -0
- package/dist/heart/attachments/materialize.js +97 -0
- package/dist/heart/attachments/originals.js +88 -0
- package/dist/heart/attachments/render.js +29 -0
- package/dist/heart/attachments/sources/adapter.js +2 -0
- package/dist/heart/attachments/sources/bluebubbles.js +156 -0
- package/dist/heart/attachments/sources/cli-local-file.js +78 -0
- package/dist/heart/attachments/sources/index.js +16 -0
- package/dist/heart/attachments/store.js +103 -0
- package/dist/heart/attachments/types.js +93 -0
- package/dist/heart/auth/auth-flow.js +426 -0
- package/dist/heart/background-operations.js +281 -0
- package/dist/heart/bridges/manager.js +37 -0
- package/dist/heart/bridges/state-machine.js +20 -0
- package/dist/heart/bundle-state.js +168 -0
- package/dist/heart/commitments.js +111 -0
- package/dist/heart/config-registry.js +304 -0
- package/dist/heart/config.js +119 -129
- package/dist/heart/core.js +845 -229
- package/dist/heart/cross-chat-delivery.js +131 -0
- package/dist/heart/daemon/agent-config-check.js +490 -0
- package/dist/heart/daemon/agent-discovery.js +79 -3
- package/dist/heart/daemon/agent-service.js +360 -0
- package/dist/heart/daemon/agentic-repair.js +216 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +640 -0
- package/dist/heart/daemon/cli-exec.js +7239 -0
- package/dist/heart/daemon/cli-help.js +493 -0
- package/dist/heart/daemon/cli-parse.js +1533 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +561 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/connect-bay.js +323 -0
- package/dist/heart/daemon/daemon-cli.js +29 -1616
- package/dist/heart/daemon/daemon-entry.js +345 -3
- package/dist/heart/daemon/daemon-health.js +141 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +190 -12
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +677 -58
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +486 -0
- package/dist/heart/daemon/health-monitor.js +92 -1
- package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
- package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
- package/dist/heart/daemon/http-health-probe.js +80 -0
- package/dist/heart/daemon/human-command-screens.js +234 -0
- package/dist/heart/daemon/human-readiness.js +114 -0
- package/dist/heart/daemon/inner-status.js +89 -0
- package/dist/heart/daemon/interactive-repair.js +394 -0
- package/dist/heart/daemon/launchd.js +25 -5
- package/dist/heart/daemon/log-tailer.js +82 -12
- package/dist/heart/daemon/logs-prune.js +110 -0
- package/dist/heart/daemon/message-router.js +2 -2
- package/dist/heart/daemon/os-cron-deps.js +134 -0
- package/dist/heart/daemon/ouro-bot-entry.js +4 -2
- package/dist/heart/daemon/ouro-entry.js +3 -1
- package/dist/heart/daemon/process-manager.js +214 -0
- package/dist/heart/daemon/provider-discovery.js +137 -0
- package/dist/heart/daemon/provider-ping-progress.js +83 -0
- package/dist/heart/daemon/pulse.js +475 -0
- package/dist/heart/daemon/readiness-repair.js +365 -0
- package/dist/heart/daemon/run-hooks.js +2 -0
- package/dist/heart/daemon/runtime-logging.js +67 -16
- package/dist/heart/daemon/runtime-metadata.js +73 -0
- package/dist/heart/daemon/runtime-mode.js +67 -0
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sense-manager.js +178 -37
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +94 -0
- package/dist/heart/daemon/socket-client.js +109 -4
- package/dist/heart/daemon/stale-bundle-prune.js +96 -0
- package/dist/heart/daemon/startup-tui.js +264 -0
- package/dist/heart/daemon/task-scheduler.js +3 -25
- package/dist/heart/daemon/terminal-ui.js +499 -0
- package/dist/heart/daemon/thoughts.js +162 -17
- package/dist/heart/daemon/up-progress.js +366 -0
- package/dist/heart/daemon/vault-items.js +56 -0
- package/dist/heart/delegation.js +62 -0
- package/dist/heart/habits/habit-migration.js +189 -0
- package/dist/heart/habits/habit-parser.js +140 -0
- package/dist/heart/habits/habit-runtime-state.js +100 -0
- package/dist/heart/habits/habit-scheduler.js +372 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +52 -117
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
- package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
- package/dist/heart/{daemon → hatch}/specialist-tools.js +35 -12
- package/dist/heart/identity.js +201 -66
- package/dist/heart/kept-notes.js +357 -0
- package/dist/heart/kicks.js +1 -1
- package/dist/heart/machine-identity.js +161 -0
- package/dist/heart/mail-import-discovery.js +353 -0
- package/dist/heart/mcp/mcp-server.js +653 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +59 -0
- package/dist/heart/outlook/outlook-http-hooks.js +66 -0
- package/dist/heart/outlook/outlook-http-response.js +7 -0
- package/dist/heart/outlook/outlook-http-routes.js +244 -0
- package/dist/heart/outlook/outlook-http-static.js +103 -0
- package/dist/heart/outlook/outlook-http-transport.js +116 -0
- package/dist/heart/outlook/outlook-http.js +99 -0
- package/dist/heart/outlook/outlook-read.js +31 -0
- package/dist/heart/outlook/outlook-types.js +27 -0
- package/dist/heart/outlook/outlook-view.js +195 -0
- package/dist/heart/outlook/readers/agent-machine.js +382 -0
- package/dist/heart/outlook/readers/continuity-readers.js +336 -0
- package/dist/heart/outlook/readers/mail.js +362 -0
- package/dist/heart/outlook/readers/runtime-readers.js +644 -0
- package/dist/heart/outlook/readers/sessions.js +232 -0
- package/dist/heart/outlook/readers/shared.js +111 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/progress-story.js +42 -0
- package/dist/heart/provider-attempt.js +134 -0
- package/dist/heart/provider-binding-resolver.js +255 -0
- package/dist/heart/provider-credentials.js +424 -0
- package/dist/heart/provider-failover.js +301 -0
- package/dist/heart/provider-models.js +81 -0
- package/dist/heart/provider-ping.js +262 -0
- package/dist/heart/provider-state.js +216 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +193 -55
- package/dist/heart/providers/azure.js +104 -13
- package/dist/heart/providers/error-classification.js +63 -0
- package/dist/heart/providers/github-copilot.js +145 -0
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +29 -7
- package/dist/heart/providers/openai-codex.js +63 -39
- package/dist/heart/runtime-capability-check.js +170 -0
- package/dist/heart/runtime-credentials.js +260 -0
- package/dist/heart/sense-truth.js +11 -4
- package/dist/heart/session-activity.js +190 -0
- package/dist/heart/session-events.js +981 -0
- package/dist/heart/session-transcript.js +167 -0
- package/dist/heart/start-of-turn-packet.js +345 -0
- package/dist/heart/streaming.js +48 -28
- package/dist/heart/sync.js +332 -0
- package/dist/heart/target-resolution.js +127 -0
- package/dist/heart/tempo.js +93 -0
- package/dist/heart/temporal-view.js +41 -0
- package/dist/heart/tool-activity-callbacks.js +36 -0
- package/dist/heart/tool-description.js +135 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +372 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/versioning/ouro-path-installer.js +425 -0
- package/dist/heart/versioning/ouro-version-manager.js +295 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
- package/dist/heart/{daemon → versioning}/update-checker.js +5 -1
- package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +600 -0
- package/dist/mailroom/core.js +658 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +426 -0
- package/dist/mailroom/mbox-import.js +382 -0
- package/dist/mailroom/outbound.js +380 -0
- package/dist/mailroom/policy.js +263 -0
- package/dist/mailroom/reader.js +219 -0
- package/dist/mailroom/search-cache.js +182 -0
- package/dist/mailroom/search-relevance.js +319 -0
- package/dist/mailroom/smtp-ingress.js +176 -0
- package/dist/mailroom/source-state.js +176 -0
- package/dist/mailroom/travel-extract.js +89 -0
- package/dist/mind/bundle-manifest.js +7 -1
- package/dist/mind/context.js +164 -93
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +74 -93
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/friends/channel.js +30 -0
- package/dist/mind/friends/group-context.js +144 -0
- package/dist/mind/friends/resolver.js +54 -2
- package/dist/mind/friends/store-file.js +39 -3
- package/dist/mind/friends/trust-explanation.js +74 -0
- package/dist/mind/friends/types.js +2 -2
- package/dist/mind/journal-index.js +161 -0
- package/dist/mind/note-search.js +268 -0
- package/dist/mind/obligation-steering.js +221 -0
- package/dist/mind/pending.js +56 -8
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +973 -168
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/scrutiny.js +173 -0
- package/dist/nerves/cli-logging.js +7 -1
- package/dist/nerves/coverage/audit-rules.js +15 -6
- package/dist/nerves/coverage/audit.js +28 -2
- package/dist/nerves/coverage/cli.js +1 -1
- package/dist/nerves/coverage/contract.js +5 -5
- package/dist/nerves/coverage/file-completeness.js +93 -5
- package/dist/nerves/coverage/run-artifacts.js +1 -1
- package/dist/nerves/event-buffer.js +111 -0
- package/dist/nerves/index.js +224 -4
- package/dist/nerves/observation.js +20 -0
- package/dist/nerves/redact.js +79 -0
- package/dist/nerves/runtime.js +5 -1
- package/dist/outlook-ui/assets/index-BPr5vNuM.css +1 -0
- package/dist/outlook-ui/assets/index-Cm51CY9W.js +61 -0
- package/dist/outlook-ui/index.html +15 -0
- package/dist/repertoire/ado-client.js +15 -56
- package/dist/repertoire/ado-semantic.js +11 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +774 -0
- package/dist/repertoire/bundle-templates.js +72 -0
- package/dist/repertoire/bw-installer.js +180 -0
- package/dist/repertoire/coding/codex-jsonl.js +64 -0
- package/dist/repertoire/coding/context-pack.js +330 -0
- package/dist/repertoire/coding/feedback.js +197 -30
- package/dist/repertoire/coding/manager.js +158 -9
- package/dist/repertoire/coding/spawner.js +55 -9
- package/dist/repertoire/coding/tools.js +170 -7
- package/dist/repertoire/commerce-errors.js +109 -0
- package/dist/repertoire/commerce-self-test.js +156 -0
- package/dist/repertoire/credential-access.js +111 -0
- package/dist/repertoire/duffel-client.js +185 -0
- package/dist/repertoire/github-client.js +14 -55
- package/dist/repertoire/graph-client.js +11 -52
- package/dist/repertoire/guardrails.js +396 -0
- package/dist/repertoire/mcp-client.js +255 -0
- package/dist/repertoire/mcp-manager.js +305 -0
- package/dist/repertoire/mcp-tools.js +63 -0
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/skills.js +15 -24
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tasks/board.js +31 -5
- package/dist/repertoire/tasks/fix.js +182 -0
- package/dist/repertoire/tasks/index.js +16 -4
- package/dist/repertoire/tasks/lifecycle.js +2 -2
- package/dist/repertoire/tasks/parser.js +3 -2
- package/dist/repertoire/tasks/scanner.js +194 -37
- package/dist/repertoire/tasks/transitions.js +16 -78
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-attachments.js +317 -0
- package/dist/repertoire/tools-base.js +46 -842
- package/dist/repertoire/tools-bluebubbles.js +1 -0
- package/dist/repertoire/tools-bridge.js +141 -0
- package/dist/repertoire/tools-bundle.js +984 -0
- package/dist/repertoire/tools-config.js +185 -0
- package/dist/repertoire/tools-continuity.js +248 -0
- package/dist/repertoire/tools-credential.js +381 -0
- package/dist/repertoire/tools-files.js +342 -0
- package/dist/repertoire/tools-flight.js +224 -0
- package/dist/repertoire/tools-flow.js +105 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-mail.js +1281 -0
- package/dist/repertoire/tools-notes.js +376 -0
- package/dist/repertoire/tools-session.js +749 -0
- package/dist/repertoire/tools-shell.js +120 -0
- package/dist/repertoire/tools-stripe.js +180 -0
- package/dist/repertoire/tools-surface.js +243 -0
- package/dist/repertoire/tools-teams.js +9 -39
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +356 -0
- package/dist/repertoire/tools-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools.js +144 -115
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/user-profile.js +131 -0
- package/dist/repertoire/vault-setup.js +246 -0
- package/dist/repertoire/vault-unlock.js +561 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/attention-queue.js +116 -0
- package/dist/senses/bluebubbles/attachment-cache.js +53 -0
- package/dist/senses/bluebubbles/attachment-download.js +137 -0
- package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
- package/dist/senses/bluebubbles/entry.js +73 -0
- package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
- package/dist/senses/bluebubbles/index.js +1835 -0
- package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
- package/dist/senses/bluebubbles/processed-log.js +111 -0
- package/dist/senses/bluebubbles/replay.js +129 -0
- package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +2 -2
- package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
- package/dist/senses/cli/bracketed-paste.js +82 -0
- package/dist/senses/cli/image-paste.js +287 -0
- package/dist/senses/cli/image-ref-navigation.js +75 -0
- package/dist/senses/cli/ink-app.js +156 -0
- package/dist/senses/cli/inline-diff.js +64 -0
- package/dist/senses/cli/input-keys.js +174 -0
- package/dist/senses/cli/kill-ring.js +86 -0
- package/dist/senses/cli/message-list.js +51 -0
- package/dist/senses/cli/ouro-tui.js +605 -0
- package/dist/senses/cli/spinner-imperative.js +135 -0
- package/dist/senses/cli/spinner.js +101 -0
- package/dist/senses/cli/status-line.js +60 -0
- package/dist/senses/cli/streaming-markdown.js +526 -0
- package/dist/senses/cli/tool-display.js +83 -0
- package/dist/senses/cli/tool-render.js +85 -0
- package/dist/senses/cli/tui-store.js +240 -0
- package/dist/senses/cli/virtual-list.js +35 -0
- package/dist/senses/cli-entry.js +60 -8
- package/dist/senses/cli-layout.js +187 -0
- package/dist/senses/cli.js +515 -211
- package/dist/senses/commands.js +66 -3
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +110 -20
- package/dist/senses/inner-dialog.js +408 -21
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +379 -0
- package/dist/senses/pipeline.js +588 -81
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +248 -0
- package/dist/senses/surface-tool.js +68 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +412 -163
- package/dist/senses/trust-gate.js +100 -5
- package/dist/trips/core.js +138 -0
- package/dist/trips/store.js +146 -0
- package/package.json +37 -7
- package/skills/agent-commerce.md +106 -0
- package/skills/browser-navigation.md +117 -0
- package/skills/commerce-setup-guide.md +116 -0
- package/skills/commerce-setup.md +84 -0
- package/skills/configure-dev-tools.md +101 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/ouro-path-installer.js +0 -178
- package/dist/heart/daemon/subagent-installer.js +0 -166
- package/dist/heart/session-recall.js +0 -116
- package/dist/mind/associative-recall.js +0 -209
- package/dist/senses/bluebubbles-entry.js +0 -13
- package/dist/senses/bluebubbles.js +0 -1032
- package/dist/senses/debug-activity.js +0 -127
- package/subagents/README.md +0 -86
- package/subagents/work-doer.md +0 -237
- package/subagents/work-merger.md +0 -618
- package/subagents/work-planner.md +0 -390
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
- /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
- /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
- /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
- /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.travelToolDefinitions = void 0;
|
|
4
|
+
const travel_api_client_1 = require("./travel-api-client");
|
|
5
|
+
const runtime_1 = require("../nerves/runtime");
|
|
6
|
+
exports.travelToolDefinitions = [
|
|
7
|
+
{
|
|
8
|
+
tool: {
|
|
9
|
+
type: "function",
|
|
10
|
+
function: {
|
|
11
|
+
name: "weather_lookup",
|
|
12
|
+
description: "Get current weather for a location. Provide either a city name or lat/lon coordinates.",
|
|
13
|
+
parameters: {
|
|
14
|
+
type: "object",
|
|
15
|
+
properties: {
|
|
16
|
+
city: { type: "string", description: "City name (e.g. 'London', 'New York')" },
|
|
17
|
+
lat: { type: "string", description: "Latitude (decimal)" },
|
|
18
|
+
lon: { type: "string", description: "Longitude (decimal)" },
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
handler: async (args) => {
|
|
24
|
+
(0, runtime_1.emitNervesEvent)({
|
|
25
|
+
component: "repertoire",
|
|
26
|
+
event: "repertoire.travel_tool_call",
|
|
27
|
+
message: "weather_lookup invoked",
|
|
28
|
+
meta: { tool: "weather_lookup" },
|
|
29
|
+
});
|
|
30
|
+
try {
|
|
31
|
+
if (args.city) {
|
|
32
|
+
const data = await (0, travel_api_client_1.getWeatherByCity)(args.city);
|
|
33
|
+
return JSON.stringify(data, null, 2);
|
|
34
|
+
}
|
|
35
|
+
if (args.lat && args.lon) {
|
|
36
|
+
const data = await (0, travel_api_client_1.getWeather)(parseFloat(args.lat), parseFloat(args.lon));
|
|
37
|
+
return JSON.stringify(data, null, 2);
|
|
38
|
+
}
|
|
39
|
+
return "Please provide either a city name or lat/lon coordinates.";
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
/* v8 ignore next -- defensive: callers throw Error instances @preserve */
|
|
43
|
+
return `Weather lookup error: ${err instanceof Error ? err.message : String(err)}`;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
summaryKeys: ["city", "lat", "lon"],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
tool: {
|
|
50
|
+
type: "function",
|
|
51
|
+
function: {
|
|
52
|
+
name: "travel_advisory",
|
|
53
|
+
description: "Get US State Department travel advisory for a country. Returns advisory level (1-4) and description.",
|
|
54
|
+
parameters: {
|
|
55
|
+
type: "object",
|
|
56
|
+
properties: {
|
|
57
|
+
country_code: {
|
|
58
|
+
type: "string",
|
|
59
|
+
description: "ISO 3166 alpha-2 country code (e.g. 'US', 'GB', 'AF')",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
required: ["country_code"],
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
handler: async (args) => {
|
|
67
|
+
(0, runtime_1.emitNervesEvent)({
|
|
68
|
+
component: "repertoire",
|
|
69
|
+
event: "repertoire.travel_tool_call",
|
|
70
|
+
message: "travel_advisory invoked",
|
|
71
|
+
meta: { tool: "travel_advisory" },
|
|
72
|
+
});
|
|
73
|
+
try {
|
|
74
|
+
const data = await (0, travel_api_client_1.getTravelAdvisory)(args.country_code.toUpperCase());
|
|
75
|
+
return JSON.stringify(data, null, 2);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
/* v8 ignore next -- defensive: callers throw Error instances @preserve */
|
|
79
|
+
return `Travel advisory error: ${err instanceof Error ? err.message : String(err)}`;
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
summaryKeys: ["country_code"],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
tool: {
|
|
86
|
+
type: "function",
|
|
87
|
+
function: {
|
|
88
|
+
name: "geocode_search",
|
|
89
|
+
description: "Search for locations, addresses, or points of interest. Returns coordinates and display names.",
|
|
90
|
+
parameters: {
|
|
91
|
+
type: "object",
|
|
92
|
+
properties: {
|
|
93
|
+
query: { type: "string", description: "Search query (e.g. 'Eiffel Tower', '123 Main St')" },
|
|
94
|
+
near_lat: { type: "string", description: "Latitude to search near (for POI search)" },
|
|
95
|
+
near_lon: { type: "string", description: "Longitude to search near (for POI search)" },
|
|
96
|
+
radius_km: { type: "string", description: "Search radius in km (default 10)" },
|
|
97
|
+
},
|
|
98
|
+
required: ["query"],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
handler: async (args) => {
|
|
103
|
+
(0, runtime_1.emitNervesEvent)({
|
|
104
|
+
component: "repertoire",
|
|
105
|
+
event: "repertoire.travel_tool_call",
|
|
106
|
+
message: "geocode_search invoked",
|
|
107
|
+
meta: { tool: "geocode_search" },
|
|
108
|
+
});
|
|
109
|
+
try {
|
|
110
|
+
if (args.near_lat && args.near_lon) {
|
|
111
|
+
const radiusKm = args.radius_km ? parseFloat(args.radius_km) : undefined;
|
|
112
|
+
const data = await (0, travel_api_client_1.searchPOI)(args.query, parseFloat(args.near_lat), parseFloat(args.near_lon), radiusKm);
|
|
113
|
+
return JSON.stringify(data, null, 2);
|
|
114
|
+
}
|
|
115
|
+
const data = await (0, travel_api_client_1.geocode)(args.query);
|
|
116
|
+
return JSON.stringify(data, null, 2);
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
/* v8 ignore next -- defensive: callers throw Error instances @preserve */
|
|
120
|
+
return `Geocode error: ${err instanceof Error ? err.message : String(err)}`;
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
summaryKeys: ["query"],
|
|
124
|
+
},
|
|
125
|
+
];
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.tripToolDefinitions = void 0;
|
|
4
|
+
const types_1 = require("../mind/friends/types");
|
|
5
|
+
const runtime_1 = require("../nerves/runtime");
|
|
6
|
+
const store_1 = require("../trips/store");
|
|
7
|
+
const core_1 = require("../trips/core");
|
|
8
|
+
const identity_1 = require("../heart/identity");
|
|
9
|
+
function trustAllowsTripAccess(ctx) {
|
|
10
|
+
const trustLevel = ctx?.context?.friend?.trustLevel;
|
|
11
|
+
return trustLevel === undefined || (0, types_1.isTrustedLevel)(trustLevel);
|
|
12
|
+
}
|
|
13
|
+
function isRecord(value) {
|
|
14
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
function parseJsonArg(raw, label) {
|
|
17
|
+
if (typeof raw !== "string")
|
|
18
|
+
throw new Error(`${label} must be a JSON string`);
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(raw);
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
throw new Error(`${label} is not valid JSON: ${error instanceof Error ? error.message : /* v8 ignore next -- JSON.parse only throws SyntaxError */ String(error)}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function validateTripRecord(value) {
|
|
27
|
+
if (!isRecord(value))
|
|
28
|
+
throw new Error("record must be a TripRecord object");
|
|
29
|
+
// Minimal structural validation — the agent is constructing the value but
|
|
30
|
+
// we still guard against the obvious shape mistakes that would break decrypt.
|
|
31
|
+
for (const field of ["tripId", "agentId", "ownerEmail", "name", "status", "createdAt", "updatedAt"]) {
|
|
32
|
+
if (typeof value[field] !== "string" || value[field].length === 0) {
|
|
33
|
+
throw new Error(`record.${field} must be a non-empty string`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (!Array.isArray(value.travellers))
|
|
37
|
+
throw new Error("record.travellers must be an array");
|
|
38
|
+
if (!Array.isArray(value.legs))
|
|
39
|
+
throw new Error("record.legs must be an array");
|
|
40
|
+
for (const leg of value.legs) {
|
|
41
|
+
if (!isRecord(leg))
|
|
42
|
+
throw new Error("each leg must be an object");
|
|
43
|
+
if (typeof leg.legId !== "string" || leg.legId.length === 0)
|
|
44
|
+
throw new Error("each leg requires a legId");
|
|
45
|
+
if (typeof leg.kind !== "string")
|
|
46
|
+
throw new Error("each leg requires a kind");
|
|
47
|
+
if (typeof leg.status !== "string")
|
|
48
|
+
throw new Error("each leg requires a status");
|
|
49
|
+
if (!Array.isArray(leg.evidence))
|
|
50
|
+
throw new Error(`leg ${leg.legId} requires an evidence array`);
|
|
51
|
+
for (const ev of leg.evidence) {
|
|
52
|
+
if (!isRecord(ev))
|
|
53
|
+
throw new Error(`leg ${leg.legId}: each evidence entry must be an object`);
|
|
54
|
+
if (typeof ev.messageId !== "string" || ev.messageId.length === 0)
|
|
55
|
+
throw new Error(`leg ${leg.legId}: evidence.messageId must be a non-empty string`);
|
|
56
|
+
if (typeof ev.discoveryMethod !== "string" || ev.discoveryMethod.length === 0)
|
|
57
|
+
throw new Error(`leg ${leg.legId}: evidence.discoveryMethod must be a non-empty string`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
function validateTripEvidence(value) {
|
|
63
|
+
if (!isRecord(value))
|
|
64
|
+
throw new Error("evidence must be a TripEvidence object");
|
|
65
|
+
for (const field of ["messageId", "reason", "recordedAt", "discoveryMethod"]) {
|
|
66
|
+
if (typeof value[field] !== "string" || value[field].length === 0) {
|
|
67
|
+
throw new Error(`evidence.${field} must be a non-empty string`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
function renderTripSummary(trip) {
|
|
73
|
+
const dateRange = trip.startDate && trip.endDate
|
|
74
|
+
? `${trip.startDate} → ${trip.endDate}`
|
|
75
|
+
: trip.startDate ?? trip.endDate ?? "(no dates)";
|
|
76
|
+
const lines = [
|
|
77
|
+
`- ${trip.tripId} :: "${trip.name}" [${trip.status}; ${dateRange}; legs: ${trip.legs.length}]`,
|
|
78
|
+
` travellers: ${trip.travellers.map((p) => p.name).join(", ") || "(none)"}`,
|
|
79
|
+
];
|
|
80
|
+
if (trip.notes)
|
|
81
|
+
lines.push(` notes: ${trip.notes}`);
|
|
82
|
+
return lines.join("\n");
|
|
83
|
+
}
|
|
84
|
+
exports.tripToolDefinitions = [
|
|
85
|
+
{
|
|
86
|
+
tool: {
|
|
87
|
+
type: "function",
|
|
88
|
+
function: {
|
|
89
|
+
name: "trip_ensure_ledger",
|
|
90
|
+
description: "Idempotently ensure this agent has a trip ledger keypair. Safe to call multiple times. Required once before any other trip_ tool.",
|
|
91
|
+
parameters: { type: "object", properties: {} },
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
handler: async (_args, ctx) => {
|
|
95
|
+
if (!trustAllowsTripAccess(ctx))
|
|
96
|
+
return "trip ledger is private; this tool is only available in trusted contexts.";
|
|
97
|
+
const result = (0, store_1.ensureAgentTripLedger)({ agentName: (0, identity_1.getAgentName)() });
|
|
98
|
+
const verb = result.added ? "created" : "already present";
|
|
99
|
+
return `trip ledger ${verb}: ledgerId=${result.ledger.ledgerId}, keyId=${result.ledger.keyId}, createdAt=${result.ledger.createdAt}`;
|
|
100
|
+
},
|
|
101
|
+
summaryKeys: [],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
tool: {
|
|
105
|
+
type: "function",
|
|
106
|
+
function: {
|
|
107
|
+
name: "trip_status",
|
|
108
|
+
description: "List the agent's trip ids in sorted order. Cheap overview before opening individual trips.",
|
|
109
|
+
parameters: { type: "object", properties: {} },
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
handler: async (_args, ctx) => {
|
|
113
|
+
if (!trustAllowsTripAccess(ctx))
|
|
114
|
+
return "trip ledger is private; this tool is only available in trusted contexts.";
|
|
115
|
+
const tripIds = (0, store_1.listTripIds)((0, identity_1.getAgentName)());
|
|
116
|
+
if (tripIds.length === 0)
|
|
117
|
+
return "no trips on the ledger yet.";
|
|
118
|
+
return `${tripIds.length} trip(s):\n${tripIds.map((id) => `- ${id}`).join("\n")}`;
|
|
119
|
+
},
|
|
120
|
+
summaryKeys: [],
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
tool: {
|
|
124
|
+
type: "function",
|
|
125
|
+
function: {
|
|
126
|
+
name: "trip_get",
|
|
127
|
+
description: "Read one trip record by id. Returns a structured summary plus the raw JSON for further reasoning.",
|
|
128
|
+
parameters: {
|
|
129
|
+
type: "object",
|
|
130
|
+
properties: {
|
|
131
|
+
tripId: { type: "string", description: "Canonical trip id (trip_<slug>_<fingerprint>)." },
|
|
132
|
+
},
|
|
133
|
+
required: ["tripId"],
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
handler: async (args, ctx) => {
|
|
138
|
+
if (!trustAllowsTripAccess(ctx))
|
|
139
|
+
return "trip ledger is private; this tool is only available in trusted contexts.";
|
|
140
|
+
const tripId = args.tripId;
|
|
141
|
+
if (typeof tripId !== "string" || tripId.length === 0)
|
|
142
|
+
return "tripId is required.";
|
|
143
|
+
try {
|
|
144
|
+
const trip = (0, store_1.readTripRecord)((0, identity_1.getAgentName)(), tripId);
|
|
145
|
+
return [
|
|
146
|
+
renderTripSummary(trip),
|
|
147
|
+
"",
|
|
148
|
+
"raw record (JSON):",
|
|
149
|
+
JSON.stringify(trip, null, 2),
|
|
150
|
+
].join("\n");
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
if (error instanceof store_1.TripNotFoundError)
|
|
154
|
+
return error.message;
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
summaryKeys: ["tripId"],
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
tool: {
|
|
162
|
+
type: "function",
|
|
163
|
+
function: {
|
|
164
|
+
name: "trip_upsert",
|
|
165
|
+
description: "Create or replace a TripRecord. Pass the full record as a JSON string in `record`. Every leg requires a legId and an evidence array (each evidence entry requires messageId + discoveryMethod). Returns the persisted tripId.",
|
|
166
|
+
parameters: {
|
|
167
|
+
type: "object",
|
|
168
|
+
properties: {
|
|
169
|
+
record: { type: "string", description: "Full TripRecord JSON. Must include tripId, agentId, ownerEmail, name, status, travellers[], legs[], createdAt, updatedAt." },
|
|
170
|
+
},
|
|
171
|
+
required: ["record"],
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
handler: async (args, ctx) => {
|
|
176
|
+
if (!trustAllowsTripAccess(ctx))
|
|
177
|
+
return "trip ledger is private; this tool is only available in trusted contexts.";
|
|
178
|
+
try {
|
|
179
|
+
const parsed = parseJsonArg(args.record, "record");
|
|
180
|
+
const trip = validateTripRecord(parsed);
|
|
181
|
+
(0, store_1.ensureAgentTripLedger)({ agentName: (0, identity_1.getAgentName)() });
|
|
182
|
+
(0, store_1.upsertTripRecord)((0, identity_1.getAgentName)(), trip);
|
|
183
|
+
return `trip upserted: ${trip.tripId} (${trip.legs.length} leg(s), status=${trip.status})`;
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
return `upsert failed: ${error instanceof Error ? error.message : /* v8 ignore next -- non-Error throw is unreachable from validateTripRecord/parseJsonArg */ String(error)}`;
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
summaryKeys: [],
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
tool: {
|
|
193
|
+
type: "function",
|
|
194
|
+
function: {
|
|
195
|
+
name: "trip_attach_evidence",
|
|
196
|
+
description: "Append a TripEvidence record to a specific leg's evidence array. Pass tripId, legId, and the evidence as a JSON string. Useful when extracting a fact from a single mail message and attaching it to an existing leg without re-uploading the whole record.",
|
|
197
|
+
parameters: {
|
|
198
|
+
type: "object",
|
|
199
|
+
properties: {
|
|
200
|
+
tripId: { type: "string", description: "Canonical trip id." },
|
|
201
|
+
legId: { type: "string", description: "Leg id within the trip." },
|
|
202
|
+
evidence: { type: "string", description: "TripEvidence JSON: { messageId, reason, recordedAt, discoveryMethod, excerpt? }." },
|
|
203
|
+
},
|
|
204
|
+
required: ["tripId", "legId", "evidence"],
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
handler: async (args, ctx) => {
|
|
209
|
+
if (!trustAllowsTripAccess(ctx))
|
|
210
|
+
return "trip ledger is private; this tool is only available in trusted contexts.";
|
|
211
|
+
const tripId = args.tripId;
|
|
212
|
+
const legId = args.legId;
|
|
213
|
+
if (typeof tripId !== "string" || tripId.length === 0)
|
|
214
|
+
return "tripId is required.";
|
|
215
|
+
if (typeof legId !== "string" || legId.length === 0)
|
|
216
|
+
return "legId is required.";
|
|
217
|
+
try {
|
|
218
|
+
const evidence = validateTripEvidence(parseJsonArg(args.evidence, "evidence"));
|
|
219
|
+
const trip = (0, store_1.readTripRecord)((0, identity_1.getAgentName)(), tripId);
|
|
220
|
+
const legIndex = trip.legs.findIndex((leg) => leg.legId === legId);
|
|
221
|
+
if (legIndex === -1)
|
|
222
|
+
return `leg ${legId} not found in trip ${tripId}.`;
|
|
223
|
+
const leg = trip.legs[legIndex];
|
|
224
|
+
const updatedLeg = {
|
|
225
|
+
...leg,
|
|
226
|
+
evidence: [...leg.evidence, evidence],
|
|
227
|
+
updatedAt: evidence.recordedAt,
|
|
228
|
+
};
|
|
229
|
+
const updated = {
|
|
230
|
+
...trip,
|
|
231
|
+
legs: [...trip.legs.slice(0, legIndex), updatedLeg, ...trip.legs.slice(legIndex + 1)],
|
|
232
|
+
updatedAt: evidence.recordedAt,
|
|
233
|
+
};
|
|
234
|
+
(0, store_1.upsertTripRecord)((0, identity_1.getAgentName)(), updated);
|
|
235
|
+
(0, runtime_1.emitNervesEvent)({
|
|
236
|
+
component: "trips",
|
|
237
|
+
event: "trips.evidence_attached",
|
|
238
|
+
message: "trip evidence attached to leg",
|
|
239
|
+
meta: { agentId: (0, identity_1.getAgentName)(), tripId, legId, discoveryMethod: evidence.discoveryMethod, messageId: evidence.messageId },
|
|
240
|
+
});
|
|
241
|
+
return `evidence attached to leg ${legId} in ${tripId}; leg now carries ${updatedLeg.evidence.length} evidence entries.`;
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
if (error instanceof store_1.TripNotFoundError)
|
|
245
|
+
return error.message;
|
|
246
|
+
return `attach failed: ${error instanceof Error ? error.message : /* v8 ignore next -- non-Error throw is unreachable from validateTripEvidence/parseJsonArg/store */ String(error)}`;
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
summaryKeys: ["tripId", "legId"],
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
tool: {
|
|
253
|
+
type: "function",
|
|
254
|
+
function: {
|
|
255
|
+
name: "trip_update_leg",
|
|
256
|
+
description: "Update specific fields of an existing leg in a trip. Pass tripId, legId, and a JSON object of field updates (e.g. {status:\"cancelled\", confirmationCode:\"PNR123\"}). Existing evidence is preserved unless explicitly overwritten. Use this instead of trip_upsert when you only need to change one leg without re-emitting the whole record. The leg's `kind` cannot be changed (changing kind means a new leg).",
|
|
257
|
+
parameters: {
|
|
258
|
+
type: "object",
|
|
259
|
+
properties: {
|
|
260
|
+
tripId: { type: "string", description: "Canonical trip id." },
|
|
261
|
+
legId: { type: "string", description: "Leg id within the trip." },
|
|
262
|
+
updates: { type: "string", description: "JSON object of leg fields to update. Cannot include `legId` or `kind`. Common fields: status, confirmationCode, vendor, amount, checkInDate, checkOutDate, departureTime, arrivalTime, etc." },
|
|
263
|
+
updatedAt: { type: "string", description: "ISO timestamp for the update. Used both for the leg's updatedAt and the trip's updatedAt." },
|
|
264
|
+
},
|
|
265
|
+
required: ["tripId", "legId", "updates", "updatedAt"],
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
handler: async (args, ctx) => {
|
|
270
|
+
if (!trustAllowsTripAccess(ctx))
|
|
271
|
+
return "trip ledger is private; this tool is only available in trusted contexts.";
|
|
272
|
+
const tripId = args.tripId;
|
|
273
|
+
const legId = args.legId;
|
|
274
|
+
const updatedAt = args.updatedAt;
|
|
275
|
+
if (typeof tripId !== "string" || tripId.length === 0)
|
|
276
|
+
return "tripId is required.";
|
|
277
|
+
if (typeof legId !== "string" || legId.length === 0)
|
|
278
|
+
return "legId is required.";
|
|
279
|
+
if (typeof updatedAt !== "string" || updatedAt.length === 0)
|
|
280
|
+
return "updatedAt is required.";
|
|
281
|
+
try {
|
|
282
|
+
const updates = parseJsonArg(args.updates, "updates");
|
|
283
|
+
if (!isRecord(updates))
|
|
284
|
+
return "updates must be a JSON object.";
|
|
285
|
+
// Reject identity-changing fields — those would silently break referential integrity.
|
|
286
|
+
if ("legId" in updates)
|
|
287
|
+
return "updates cannot change legId; create a new leg instead.";
|
|
288
|
+
if ("kind" in updates)
|
|
289
|
+
return "updates cannot change kind; create a new leg instead.";
|
|
290
|
+
if (Object.keys(updates).length === 0)
|
|
291
|
+
return "updates cannot be empty — pass at least one field.";
|
|
292
|
+
const trip = (0, store_1.readTripRecord)((0, identity_1.getAgentName)(), tripId);
|
|
293
|
+
const legIndex = trip.legs.findIndex((leg) => leg.legId === legId);
|
|
294
|
+
if (legIndex === -1)
|
|
295
|
+
return `leg ${legId} not found in trip ${tripId}.`;
|
|
296
|
+
const leg = trip.legs[legIndex];
|
|
297
|
+
const updatedLeg = {
|
|
298
|
+
...leg,
|
|
299
|
+
...updates,
|
|
300
|
+
legId: leg.legId,
|
|
301
|
+
kind: leg.kind,
|
|
302
|
+
updatedAt,
|
|
303
|
+
};
|
|
304
|
+
const updated = {
|
|
305
|
+
...trip,
|
|
306
|
+
legs: [...trip.legs.slice(0, legIndex), updatedLeg, ...trip.legs.slice(legIndex + 1)],
|
|
307
|
+
updatedAt,
|
|
308
|
+
};
|
|
309
|
+
(0, store_1.upsertTripRecord)((0, identity_1.getAgentName)(), updated);
|
|
310
|
+
(0, runtime_1.emitNervesEvent)({
|
|
311
|
+
component: "trips",
|
|
312
|
+
event: "trips.leg_updated",
|
|
313
|
+
message: "trip leg fields updated",
|
|
314
|
+
meta: { agentId: (0, identity_1.getAgentName)(), tripId, legId, fields: Object.keys(updates) },
|
|
315
|
+
});
|
|
316
|
+
const fieldList = Object.keys(updates).join(", ");
|
|
317
|
+
return `leg ${legId} updated in ${tripId}: ${fieldList}.`;
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
if (error instanceof store_1.TripNotFoundError)
|
|
321
|
+
return error.message;
|
|
322
|
+
return `update failed: ${error instanceof Error ? error.message : /* v8 ignore next -- non-Error throw is unreachable from parseJsonArg/store */ String(error)}`;
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
summaryKeys: ["tripId", "legId"],
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
tool: {
|
|
329
|
+
type: "function",
|
|
330
|
+
function: {
|
|
331
|
+
name: "trip_new_id",
|
|
332
|
+
description: "Compute a deterministic trip id from agentId + name + createdAt. Useful before constructing a new TripRecord so the id is stable and reproducible.",
|
|
333
|
+
parameters: {
|
|
334
|
+
type: "object",
|
|
335
|
+
properties: {
|
|
336
|
+
name: { type: "string", description: "Human-friendly trip name (e.g. \"Europe summer 2026\")." },
|
|
337
|
+
createdAt: { type: "string", description: "ISO timestamp the trip was first conceived. Pass `now` if just creating it." },
|
|
338
|
+
},
|
|
339
|
+
required: ["name", "createdAt"],
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
},
|
|
343
|
+
handler: async (args, ctx) => {
|
|
344
|
+
if (!trustAllowsTripAccess(ctx))
|
|
345
|
+
return "trip ledger is private; this tool is only available in trusted contexts.";
|
|
346
|
+
const name = args.name;
|
|
347
|
+
const createdAt = args.createdAt;
|
|
348
|
+
if (typeof name !== "string" || name.length === 0)
|
|
349
|
+
return "name is required.";
|
|
350
|
+
if (typeof createdAt !== "string" || createdAt.length === 0)
|
|
351
|
+
return "createdAt is required.";
|
|
352
|
+
return (0, core_1.newTripId)((0, identity_1.getAgentName)(), name, createdAt);
|
|
353
|
+
},
|
|
354
|
+
summaryKeys: ["name"],
|
|
355
|
+
},
|
|
356
|
+
];
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.userProfileToolDefinitions = void 0;
|
|
4
|
+
const user_profile_1 = require("./user-profile");
|
|
5
|
+
const credential_access_1 = require("./credential-access");
|
|
6
|
+
const runtime_1 = require("../nerves/runtime");
|
|
7
|
+
function requireFamilyContext(ctx) {
|
|
8
|
+
if (!ctx?.context?.friend?.id) {
|
|
9
|
+
return "no friend context — cannot access user profile.";
|
|
10
|
+
}
|
|
11
|
+
if (ctx.context.friend.trustLevel !== "family") {
|
|
12
|
+
return "user profile access requires family trust level.";
|
|
13
|
+
}
|
|
14
|
+
return { friendId: ctx.context.friend.id };
|
|
15
|
+
}
|
|
16
|
+
exports.userProfileToolDefinitions = [
|
|
17
|
+
{
|
|
18
|
+
tool: {
|
|
19
|
+
type: "function",
|
|
20
|
+
function: {
|
|
21
|
+
name: "user_profile_store",
|
|
22
|
+
description: "Store or update user profile fields (legal name, DOB, passport, etc.) in the agent's vault. Fields are merged with any existing profile. Requires family trust level.",
|
|
23
|
+
parameters: {
|
|
24
|
+
type: "object",
|
|
25
|
+
properties: {
|
|
26
|
+
fields: {
|
|
27
|
+
type: "string",
|
|
28
|
+
description: 'JSON object with profile fields to store/update. Keys: legalName, dateOfBirth, gender, nationality, passport, driverLicense, email, phone, addresses, loyaltyPrograms, preferences, emergencyContact.',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
required: ["fields"],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
handler: async (args, ctx) => {
|
|
36
|
+
(0, runtime_1.emitNervesEvent)({
|
|
37
|
+
component: "repertoire",
|
|
38
|
+
event: "repertoire.tool_user_profile_store",
|
|
39
|
+
message: "user_profile_store invoked",
|
|
40
|
+
meta: { tool: "user_profile_store" },
|
|
41
|
+
});
|
|
42
|
+
const guard = requireFamilyContext(ctx);
|
|
43
|
+
if (typeof guard === "string")
|
|
44
|
+
return guard;
|
|
45
|
+
let fields;
|
|
46
|
+
try {
|
|
47
|
+
fields = JSON.parse(args.fields);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return "invalid JSON in fields parameter.";
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const store = (0, credential_access_1.getCredentialStore)();
|
|
54
|
+
await (0, user_profile_1.updateUserProfileFields)(guard.friendId, fields, store);
|
|
55
|
+
return `profile fields stored for ${guard.friendId}.`;
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
/* v8 ignore next -- defensive: updateUserProfileFields errors are always Error instances @preserve */
|
|
59
|
+
return `failed to store profile: ${err instanceof Error ? err.message : String(err)}`;
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
summaryKeys: ["fields"],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
tool: {
|
|
66
|
+
type: "function",
|
|
67
|
+
function: {
|
|
68
|
+
name: "user_profile_get",
|
|
69
|
+
description: "Retrieve a specific field from a user's profile. Only returns the requested field, never the full profile. Requires family trust level.",
|
|
70
|
+
parameters: {
|
|
71
|
+
type: "object",
|
|
72
|
+
properties: {
|
|
73
|
+
field: {
|
|
74
|
+
type: "string",
|
|
75
|
+
description: "The profile field to retrieve: legalName, dateOfBirth, gender, nationality, passport, driverLicense, email, phone, addresses, loyaltyPrograms, preferences, emergencyContact.",
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
required: ["field"],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
handler: async (args, ctx) => {
|
|
83
|
+
(0, runtime_1.emitNervesEvent)({
|
|
84
|
+
component: "repertoire",
|
|
85
|
+
event: "repertoire.tool_user_profile_get",
|
|
86
|
+
message: "user_profile_get invoked",
|
|
87
|
+
meta: { tool: "user_profile_get", field: args.field },
|
|
88
|
+
});
|
|
89
|
+
const guard = requireFamilyContext(ctx);
|
|
90
|
+
if (typeof guard === "string")
|
|
91
|
+
return guard;
|
|
92
|
+
try {
|
|
93
|
+
const store = (0, credential_access_1.getCredentialStore)();
|
|
94
|
+
const value = await (0, user_profile_1.getUserProfileField)(guard.friendId, args.field, store);
|
|
95
|
+
if (value === undefined) {
|
|
96
|
+
return `field "${args.field}" is not set on the profile.`;
|
|
97
|
+
}
|
|
98
|
+
/* v8 ignore next -- platform-dependent v8 branch counting on ternary @preserve */
|
|
99
|
+
return typeof value === "string" ? value : JSON.stringify(value, null, 2);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
/* v8 ignore next -- defensive: getUserProfileField errors are always Error instances @preserve */
|
|
103
|
+
return `failed to get profile field: ${err instanceof Error ? err.message : String(err)}`;
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
summaryKeys: ["field"],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
tool: {
|
|
110
|
+
type: "function",
|
|
111
|
+
function: {
|
|
112
|
+
name: "user_profile_delete",
|
|
113
|
+
description: "Delete a user's entire profile from the vault. This is irreversible. Requires family trust level.",
|
|
114
|
+
parameters: {
|
|
115
|
+
type: "object",
|
|
116
|
+
properties: {},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
handler: async (_args, ctx) => {
|
|
121
|
+
(0, runtime_1.emitNervesEvent)({
|
|
122
|
+
component: "repertoire",
|
|
123
|
+
event: "repertoire.tool_user_profile_delete",
|
|
124
|
+
message: "user_profile_delete invoked",
|
|
125
|
+
meta: { tool: "user_profile_delete" },
|
|
126
|
+
});
|
|
127
|
+
const guard = requireFamilyContext(ctx);
|
|
128
|
+
if (typeof guard === "string")
|
|
129
|
+
return guard;
|
|
130
|
+
try {
|
|
131
|
+
const store = (0, credential_access_1.getCredentialStore)();
|
|
132
|
+
const deleted = await (0, user_profile_1.deleteUserProfile)(guard.friendId, store);
|
|
133
|
+
return deleted
|
|
134
|
+
? `profile deleted for ${guard.friendId}.`
|
|
135
|
+
: `no profile found for ${guard.friendId}.`;
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
/* v8 ignore next -- defensive: deleteUserProfile errors are always Error instances @preserve */
|
|
139
|
+
return `failed to delete profile: ${err instanceof Error ? err.message : String(err)}`;
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
summaryKeys: [],
|
|
143
|
+
},
|
|
144
|
+
];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.vaultToolDefinitions = void 0;
|
|
4
|
+
const identity_1 = require("../heart/identity");
|
|
5
|
+
const runtime_1 = require("../nerves/runtime");
|
|
6
|
+
exports.vaultToolDefinitions = [
|
|
7
|
+
{
|
|
8
|
+
tool: {
|
|
9
|
+
type: "function",
|
|
10
|
+
function: {
|
|
11
|
+
name: "vault_setup",
|
|
12
|
+
description: "Set up the agent's credential vault. Creates a Bitwarden account on the configured Vaultwarden server. One-time operation — idempotent if vault already exists.",
|
|
13
|
+
parameters: {
|
|
14
|
+
type: "object",
|
|
15
|
+
properties: {},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
handler: async () => {
|
|
20
|
+
const agentName = (0, identity_1.getAgentName)();
|
|
21
|
+
(0, runtime_1.emitNervesEvent)({
|
|
22
|
+
component: "repertoire",
|
|
23
|
+
event: "repertoire.vault_tool_call",
|
|
24
|
+
message: "vault_setup invoked",
|
|
25
|
+
meta: { tool: "vault_setup", agentName },
|
|
26
|
+
});
|
|
27
|
+
return [
|
|
28
|
+
"Vault setup is human-required.",
|
|
29
|
+
"",
|
|
30
|
+
"Why I cannot do it here:",
|
|
31
|
+
" Creating or unlocking a vault requires secret entry that must stay out of agent context.",
|
|
32
|
+
"",
|
|
33
|
+
"Do this in a terminal:",
|
|
34
|
+
` ouro vault create --agent ${agentName}`,
|
|
35
|
+
` ouro vault unlock --agent ${agentName}`,
|
|
36
|
+
].join("\n");
|
|
37
|
+
},
|
|
38
|
+
summaryKeys: [],
|
|
39
|
+
},
|
|
40
|
+
];
|