@vellumai/assistant 0.11.5 → 0.11.6-staging.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/AGENTS.md +5 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +118 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/ingress.ts +103 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +118 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/ingress.ts +103 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +70 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +16 -1
- package/node_modules/@vellumai/gateway-client/src/index.ts +6 -2
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +121 -61
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +118 -0
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +103 -0
- package/openapi.yaml +421 -15
- package/package.json +1 -1
- package/scripts/sync-web-search-catalog.ts +6 -0
- package/src/__tests__/app-pin-store.test.ts +149 -0
- package/src/__tests__/channel-availability-routes.test.ts +23 -1
- package/src/__tests__/channel-readiness-discord.test.ts +231 -0
- package/src/__tests__/channel-readiness-service.test.ts +126 -0
- package/src/__tests__/channel-readiness-slack-remote.test.ts +141 -0
- package/src/__tests__/channel-reply-delivery.test.ts +4 -4
- package/src/__tests__/client-os-metadata-persistence.test.ts +23 -10
- package/src/__tests__/conversation-delete-watch-timeline.test.ts +231 -0
- package/src/__tests__/conversation-error.test.ts +17 -0
- package/src/__tests__/conversation-seed-composer.test.ts +8 -0
- package/src/__tests__/conversation-slash-commands.test.ts +8 -0
- package/src/__tests__/disk-pressure-policy.test.ts +6 -0
- package/src/__tests__/gemini-provider.test.ts +138 -0
- package/src/__tests__/history-repair.test.ts +105 -3
- package/src/__tests__/identity-routes.test.ts +1 -0
- package/src/__tests__/llm-catalog-parity.test.ts +45 -0
- package/src/__tests__/migration-import-from-path.test.ts +349 -0
- package/src/__tests__/notification-telegram-adapter.test.ts +102 -0
- package/src/__tests__/oauth-commands-routes.test.ts +89 -0
- package/src/__tests__/oauth-provider-profiles.test.ts +7 -6
- package/src/__tests__/openai-provider.test.ts +18 -0
- package/src/__tests__/openai-responses-provider.test.ts +18 -0
- package/src/__tests__/platform-callback-registration.test.ts +184 -0
- package/src/__tests__/plugin-api-store-credential.test.ts +71 -3
- package/src/__tests__/pricing.test.ts +2 -2
- package/src/__tests__/public-ingress-urls.test.ts +36 -0
- package/src/__tests__/resolve-trust-class.test.ts +0 -48
- package/src/__tests__/sanitize-config-for-transfer.test.ts +28 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +49 -0
- package/src/__tests__/settings-routes.test.ts +85 -3
- package/src/__tests__/web-search-catalog-parity.test.ts +8 -0
- package/src/agent/history-repair/history-repair.ts +45 -14
- package/src/agent/loop.ts +4 -1
- package/src/api/constants/profile-config-validation.ts +60 -0
- package/src/api/events/tool-result.ts +6 -1
- package/src/api/events/watch-retro-completed.ts +52 -0
- package/src/api/index.ts +11 -0
- package/src/apps/app-pin-reconciler.ts +92 -0
- package/src/apps/app-pin-store.ts +125 -0
- package/src/channels/gateway-channel-socket-health.ts +32 -0
- package/src/channels/gateway-discord-admission.ts +32 -0
- package/src/channels/types.ts +20 -0
- package/src/cli/commands/__tests__/conversations-slack.test.ts +1 -1
- package/src/cli/commands/__tests__/inference-profiles.test.ts +16 -4
- package/src/cli/commands/__tests__/inference-providers.test.ts +67 -2
- package/src/cli/commands/channels/__tests__/channels.test.ts +85 -0
- package/src/cli/commands/channels/index.ts +45 -31
- package/src/cli/commands/inference-profiles.ts +56 -3
- package/src/cli/commands/inference-providers.ts +28 -2
- package/src/cli/commands/oauth/index.help.ts +7 -1
- package/src/cli/commands/oauth/request.test.ts +290 -0
- package/src/cli/commands/oauth/request.ts +57 -41
- package/src/cli/lib/bundled-marketplace.json +14 -1
- package/src/cli/lib/open-browser.test.ts +67 -0
- package/src/cli/lib/open-browser.ts +24 -5
- package/src/config/__tests__/profile-materialization.test.ts +26 -0
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +6 -0
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/feature-flag-registry.json +17 -1
- package/src/config/profile-materialization.ts +29 -0
- package/src/config/sanitize-for-transfer.ts +16 -0
- package/src/config/schemas/llm.ts +7 -0
- package/src/config/schemas/services.ts +6 -0
- package/src/context/outbound-sanitize.ts +6 -0
- package/src/daemon/__tests__/lifecycle-watch-timeline-sweep.test.ts +98 -0
- package/src/daemon/conversation-error.ts +24 -2
- package/src/daemon/conversation-slash.ts +6 -15
- package/src/daemon/daemon-control.ts +1 -0
- package/src/daemon/disk-pressure-policy.ts +7 -1
- package/src/daemon/handlers/__tests__/config-ingress-tunnel-records.test.ts +208 -0
- package/src/daemon/handlers/config-ingress.ts +115 -5
- package/src/daemon/lifecycle.ts +26 -0
- package/src/daemon/message-types/web-activity.ts +3 -2
- package/src/daemon/trust-context.ts +0 -37
- package/src/inbound/__tests__/tunnel-probe.test.ts +448 -0
- package/src/inbound/platform-callback-registration.ts +28 -2
- package/src/inbound/public-ingress-urls.ts +12 -0
- package/src/inbound/tunnel-probe.ts +261 -0
- package/src/live-voice/__tests__/live-voice-connection.test.ts +25 -0
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +8 -2
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +212 -10
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +5 -2
- package/src/live-voice/live-voice-connection.ts +46 -8
- package/src/live-voice/live-voice-manager.ts +25 -0
- package/src/live-voice/live-voice-session-manager.ts +318 -2
- package/src/live-voice/live-voice-session.ts +52 -2
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +126 -68
- package/src/messaging/providers/channel-transport.ts +64 -47
- package/src/messaging/providers/discord/send.test.ts +46 -1
- package/src/messaging/providers/discord/send.ts +51 -0
- package/src/messaging/providers/discord/transport.ts +26 -3
- package/src/messaging/providers/index.ts +22 -47
- package/src/messaging/providers/slack/send.test.ts +83 -26
- package/src/messaging/providers/slack/send.ts +120 -51
- package/src/messaging/providers/slack/stream-tasks.test.ts +26 -0
- package/src/messaging/providers/slack/stream-tasks.ts +39 -0
- package/src/messaging/providers/slack/transport.ts +24 -22
- package/src/messaging/providers/telegram-bot/send.test.ts +109 -12
- package/src/messaging/providers/telegram-bot/send.ts +43 -0
- package/src/messaging/providers/telegram-bot/transport.ts +25 -8
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +30 -7
- package/src/notifications/adapters/telegram.ts +48 -1
- package/src/notifications/assistant-reply-producer.ts +7 -7
- package/src/notifications/conversation-seed-composer.ts +7 -2
- package/src/oauth/byo-connection.test.ts +63 -0
- package/src/oauth/byo-connection.ts +16 -15
- package/src/oauth/connection.test.ts +111 -0
- package/src/oauth/connection.ts +142 -1
- package/src/oauth/platform-connection.test.ts +34 -0
- package/src/oauth/platform-connection.ts +28 -5
- package/src/oauth/seed-providers.ts +15 -1
- package/src/permissions/types.ts +3 -1
- package/src/persistence/conversation-crud.ts +46 -0
- package/src/persistence/conversation-types.ts +11 -9
- package/src/persistence/db-async-query.ts +2 -1
- package/src/persistence/db-maintenance.ts +15 -0
- package/src/persistence/embeddings/qdrant-manager.ts +1 -0
- package/src/persistence/migrations/367-create-watch-timeline-entries.ts +46 -0
- package/src/persistence/migrations/368-watch-timeline-screenshot-blob.ts +33 -0
- package/src/persistence/migrations/369-create-app-pins.ts +37 -0
- package/src/persistence/migrations/__tests__/367-create-watch-timeline-entries.test.ts +98 -0
- package/src/persistence/migrations/__tests__/368-watch-timeline-screenshot-blob.test.ts +98 -0
- package/src/persistence/schema/index.ts +1 -0
- package/src/persistence/schema/infrastructure.ts +17 -0
- package/src/persistence/schema/watch.ts +29 -0
- package/src/persistence/steps.ts +6 -0
- package/src/plugins/mtime-cache.ts +11 -0
- package/src/providers/__tests__/retry-network-error.test.ts +84 -0
- package/src/providers/connection-resolution.ts +23 -1
- package/src/providers/content-blocks.ts +9 -0
- package/src/providers/fetch-provider-catalog.ts +19 -0
- package/src/providers/gemini/client.ts +13 -5
- package/src/providers/inference/__tests__/endpoint-probe.test.ts +92 -0
- package/src/providers/inference/__tests__/profile-config-validation.test.ts +39 -0
- package/src/providers/inference/__tests__/profile-probe-classify.test.ts +66 -0
- package/src/providers/inference/adapter-factory.ts +0 -9
- package/src/providers/inference/credential-rotation.ts +61 -0
- package/src/providers/inference/endpoint-probe.ts +115 -0
- package/src/providers/inference/profile-probe.ts +256 -0
- package/src/providers/model-catalog.ts +170 -125
- package/src/providers/openai/__tests__/api-error-normalization.test.ts +17 -1
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +42 -60
- package/src/providers/openai/__tests__/connection-error-wrap.test.ts +44 -0
- package/src/providers/openai/__tests__/orphan-tool-result-guard.test.ts +34 -2
- package/src/providers/openai/api-error-normalization.ts +16 -2
- package/src/providers/openai/chat-completions-provider.ts +75 -29
- package/src/providers/openai/responses-provider.ts +5 -2
- package/src/providers/openrouter/client.ts +0 -1
- package/src/providers/provider-send-message.ts +11 -0
- package/src/providers/retry.ts +6 -0
- package/src/providers/search-provider-catalog.ts +20 -0
- package/src/providers/vercel-ai-gateway/client.ts +0 -1
- package/src/runtime/AGENTS.md +1 -0
- package/src/runtime/__tests__/desktop-presence.test.ts +27 -4
- package/src/runtime/__tests__/host-observe.test.ts +302 -0
- package/src/runtime/channel-readiness-service.ts +214 -14
- package/src/runtime/channel-readiness-types.ts +49 -2
- package/src/runtime/channel-reply-delivery.ts +2 -2
- package/src/runtime/desktop-presence.ts +24 -21
- package/src/runtime/host-observe.ts +246 -0
- package/src/runtime/http-server.ts +181 -1
- package/src/runtime/migrations/__tests__/staged-import-path.test.ts +104 -0
- package/src/runtime/migrations/staged-import-path.ts +116 -0
- package/src/runtime/routes/__tests__/app-pin-routes.test.ts +383 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +80 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +118 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +20 -0
- package/src/runtime/routes/__tests__/ingress-status-routes.test.ts +508 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +35 -56
- package/src/runtime/routes/__tests__/watch-routes-guardian-cache.test.ts +139 -0
- package/src/runtime/routes/__tests__/watch-routes.test.ts +598 -0
- package/src/runtime/routes/app-management-routes.ts +140 -29
- package/src/runtime/routes/channel-availability-routes.ts +1 -0
- package/src/runtime/routes/channel-readiness-routes.ts +14 -2
- package/src/runtime/routes/conversation-query-routes.ts +10 -0
- package/src/runtime/routes/guardian-approval-interception.ts +24 -33
- package/src/runtime/routes/host-cu-routes.ts +18 -0
- package/src/runtime/routes/identity-routes.ts +2 -0
- package/src/runtime/routes/inbound-message-handler.ts +10 -7
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +166 -308
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +158 -335
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-profiles-routes.ts +232 -31
- package/src/runtime/routes/inference-provider-connection-routes.ts +24 -4
- package/src/runtime/routes/ingress-status-routes.ts +180 -0
- package/src/runtime/routes/live-voice-routes.test.ts +40 -1
- package/src/runtime/routes/live-voice-routes.ts +34 -0
- package/src/runtime/routes/migration-routes.ts +218 -10
- package/src/runtime/routes/oauth-commands-routes.ts +23 -16
- package/src/runtime/routes/plugins-routes.ts +12 -28
- package/src/runtime/routes/question-routes.ts +6 -0
- package/src/runtime/routes/secret-routes.ts +7 -27
- package/src/runtime/routes/settings-routes.ts +9 -6
- package/src/runtime/routes/watch-routes.ts +807 -0
- package/src/runtime/slack-reply-session.test.ts +230 -121
- package/src/runtime/slack-reply-session.ts +113 -81
- package/src/runtime/{slack-task-progress.test.ts → task-progress.test.ts} +1 -28
- package/src/runtime/{slack-task-progress.ts → task-progress.ts} +30 -51
- package/src/security/__tests__/untrusted-content.test.ts +42 -0
- package/src/security/untrusted-content.ts +28 -9
- package/src/telemetry/__tests__/live-voice-funnel.test.ts +108 -0
- package/src/telemetry/live-voice-funnel.ts +75 -8
- package/src/tools/credentials/store.ts +18 -6
- package/src/tools/network/__tests__/firecrawl-compat.test.ts +77 -0
- package/src/tools/network/__tests__/web-fetch-fastcrw.test.ts +169 -0
- package/src/tools/network/__tests__/web-search.test.ts +97 -2
- package/src/tools/network/firecrawl-compat.ts +90 -0
- package/src/tools/network/web-fetch.ts +142 -62
- package/src/tools/network/web-search.ts +141 -55
- package/src/tools/types.ts +2 -1
- package/src/util/oauth-request-body.test.ts +74 -0
- package/src/util/oauth-request-body.ts +60 -0
- package/src/util/worker-process.ts +1 -0
- package/src/watch/__tests__/watch-retro.test.ts +665 -0
- package/src/watch/__tests__/watch-session-manager.test.ts +566 -0
- package/src/watch/__tests__/watch-timeline.test.ts +670 -0
- package/src/watch/watch-retro.ts +480 -0
- package/src/watch/watch-session-manager.ts +575 -0
- package/src/watch/watch-timeline.ts +848 -0
package/openapi.yaml
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
openapi: 3.1.0
|
|
4
4
|
info:
|
|
5
5
|
title: Vellum Assistant API
|
|
6
|
-
version: 0.11.
|
|
6
|
+
version: 0.11.6
|
|
7
7
|
description: Auto-generated OpenAPI specification for the Vellum Assistant runtime HTTP server.
|
|
8
8
|
servers:
|
|
9
9
|
- url: http://127.0.0.1:7821
|
|
@@ -790,6 +790,13 @@ paths:
|
|
|
790
790
|
type: string
|
|
791
791
|
origin:
|
|
792
792
|
type: string
|
|
793
|
+
description: '"workspace" or "plugin:<name>": where the app comes from'
|
|
794
|
+
pinSortPosition:
|
|
795
|
+
description: Sidebar order, ascending. Absent when the app is not pinned
|
|
796
|
+
type: number
|
|
797
|
+
pinColor:
|
|
798
|
+
description: Pin colour id; absent when no colour is set
|
|
799
|
+
type: string
|
|
793
800
|
required:
|
|
794
801
|
- id
|
|
795
802
|
- name
|
|
@@ -1025,6 +1032,62 @@ paths:
|
|
|
1025
1032
|
- html
|
|
1026
1033
|
- origin
|
|
1027
1034
|
additionalProperties: false
|
|
1035
|
+
/v1/apps/{id}/pin:
|
|
1036
|
+
post:
|
|
1037
|
+
operationId: apps_by_id_pin_post
|
|
1038
|
+
summary: Pin or unpin an app
|
|
1039
|
+
description:
|
|
1040
|
+
Pin an app to the sidebar, unpin it, or set the colour it is tinted with. Pin state is read back from the
|
|
1041
|
+
app list as `pinSortPosition` and `pinColor`.
|
|
1042
|
+
tags:
|
|
1043
|
+
- apps
|
|
1044
|
+
parameters:
|
|
1045
|
+
- name: id
|
|
1046
|
+
in: path
|
|
1047
|
+
required: true
|
|
1048
|
+
schema:
|
|
1049
|
+
type: string
|
|
1050
|
+
requestBody:
|
|
1051
|
+
required: true
|
|
1052
|
+
content:
|
|
1053
|
+
application/json:
|
|
1054
|
+
schema:
|
|
1055
|
+
type: object
|
|
1056
|
+
properties:
|
|
1057
|
+
pinned:
|
|
1058
|
+
description: Pin (true) or unpin (false). Omit to leave unchanged.
|
|
1059
|
+
type: boolean
|
|
1060
|
+
color:
|
|
1061
|
+
description: Colour id, or null to clear. Omit to leave unchanged.
|
|
1062
|
+
anyOf:
|
|
1063
|
+
- type: string
|
|
1064
|
+
- type: "null"
|
|
1065
|
+
responses:
|
|
1066
|
+
"200":
|
|
1067
|
+
description: Successful response
|
|
1068
|
+
content:
|
|
1069
|
+
application/json:
|
|
1070
|
+
schema:
|
|
1071
|
+
type: object
|
|
1072
|
+
properties:
|
|
1073
|
+
success:
|
|
1074
|
+
type: boolean
|
|
1075
|
+
appId:
|
|
1076
|
+
type: string
|
|
1077
|
+
pinSortPosition:
|
|
1078
|
+
anyOf:
|
|
1079
|
+
- type: number
|
|
1080
|
+
- type: "null"
|
|
1081
|
+
pinColor:
|
|
1082
|
+
anyOf:
|
|
1083
|
+
- type: string
|
|
1084
|
+
- type: "null"
|
|
1085
|
+
required:
|
|
1086
|
+
- success
|
|
1087
|
+
- appId
|
|
1088
|
+
- pinSortPosition
|
|
1089
|
+
- pinColor
|
|
1090
|
+
additionalProperties: false
|
|
1028
1091
|
/v1/apps/{id}/preview:
|
|
1029
1092
|
get:
|
|
1030
1093
|
operationId: apps_by_id_preview_get
|
|
@@ -4148,6 +4211,12 @@ paths:
|
|
|
4148
4211
|
type: string
|
|
4149
4212
|
chatType:
|
|
4150
4213
|
type: string
|
|
4214
|
+
conversationType:
|
|
4215
|
+
type: string
|
|
4216
|
+
enum:
|
|
4217
|
+
- dm
|
|
4218
|
+
- private
|
|
4219
|
+
- public
|
|
4151
4220
|
threadId:
|
|
4152
4221
|
type: string
|
|
4153
4222
|
channelName:
|
|
@@ -4360,7 +4429,17 @@ paths:
|
|
|
4360
4429
|
setupStatus:
|
|
4361
4430
|
anyOf:
|
|
4362
4431
|
- type: string
|
|
4432
|
+
enum:
|
|
4433
|
+
- not_configured
|
|
4434
|
+
- incomplete
|
|
4435
|
+
- ready
|
|
4363
4436
|
- type: "null"
|
|
4437
|
+
health:
|
|
4438
|
+
type: string
|
|
4439
|
+
enum:
|
|
4440
|
+
- ok
|
|
4441
|
+
- failing
|
|
4442
|
+
- unknown
|
|
4364
4443
|
checkedAt:
|
|
4365
4444
|
anyOf:
|
|
4366
4445
|
- type: number
|
|
@@ -4370,7 +4449,16 @@ paths:
|
|
|
4370
4449
|
reasons:
|
|
4371
4450
|
type: array
|
|
4372
4451
|
items:
|
|
4373
|
-
type:
|
|
4452
|
+
type: object
|
|
4453
|
+
properties:
|
|
4454
|
+
code:
|
|
4455
|
+
type: string
|
|
4456
|
+
text:
|
|
4457
|
+
type: string
|
|
4458
|
+
required:
|
|
4459
|
+
- code
|
|
4460
|
+
- text
|
|
4461
|
+
additionalProperties: false
|
|
4374
4462
|
localChecks:
|
|
4375
4463
|
type: array
|
|
4376
4464
|
items:
|
|
@@ -4384,6 +4472,13 @@ paths:
|
|
|
4384
4472
|
anyOf:
|
|
4385
4473
|
- type: string
|
|
4386
4474
|
- type: "null"
|
|
4475
|
+
indeterminate:
|
|
4476
|
+
type: boolean
|
|
4477
|
+
kind:
|
|
4478
|
+
type: string
|
|
4479
|
+
enum:
|
|
4480
|
+
- configuration
|
|
4481
|
+
- operational
|
|
4387
4482
|
required:
|
|
4388
4483
|
- name
|
|
4389
4484
|
- passed
|
|
@@ -4401,6 +4496,13 @@ paths:
|
|
|
4401
4496
|
anyOf:
|
|
4402
4497
|
- type: string
|
|
4403
4498
|
- type: "null"
|
|
4499
|
+
indeterminate:
|
|
4500
|
+
type: boolean
|
|
4501
|
+
kind:
|
|
4502
|
+
type: string
|
|
4503
|
+
enum:
|
|
4504
|
+
- configuration
|
|
4505
|
+
- operational
|
|
4404
4506
|
required:
|
|
4405
4507
|
- name
|
|
4406
4508
|
- passed
|
|
@@ -4482,7 +4584,17 @@ paths:
|
|
|
4482
4584
|
setupStatus:
|
|
4483
4585
|
anyOf:
|
|
4484
4586
|
- type: string
|
|
4587
|
+
enum:
|
|
4588
|
+
- not_configured
|
|
4589
|
+
- incomplete
|
|
4590
|
+
- ready
|
|
4485
4591
|
- type: "null"
|
|
4592
|
+
health:
|
|
4593
|
+
type: string
|
|
4594
|
+
enum:
|
|
4595
|
+
- ok
|
|
4596
|
+
- failing
|
|
4597
|
+
- unknown
|
|
4486
4598
|
checkedAt:
|
|
4487
4599
|
anyOf:
|
|
4488
4600
|
- type: number
|
|
@@ -4492,7 +4604,16 @@ paths:
|
|
|
4492
4604
|
reasons:
|
|
4493
4605
|
type: array
|
|
4494
4606
|
items:
|
|
4495
|
-
type:
|
|
4607
|
+
type: object
|
|
4608
|
+
properties:
|
|
4609
|
+
code:
|
|
4610
|
+
type: string
|
|
4611
|
+
text:
|
|
4612
|
+
type: string
|
|
4613
|
+
required:
|
|
4614
|
+
- code
|
|
4615
|
+
- text
|
|
4616
|
+
additionalProperties: false
|
|
4496
4617
|
localChecks:
|
|
4497
4618
|
type: array
|
|
4498
4619
|
items:
|
|
@@ -4506,6 +4627,13 @@ paths:
|
|
|
4506
4627
|
anyOf:
|
|
4507
4628
|
- type: string
|
|
4508
4629
|
- type: "null"
|
|
4630
|
+
indeterminate:
|
|
4631
|
+
type: boolean
|
|
4632
|
+
kind:
|
|
4633
|
+
type: string
|
|
4634
|
+
enum:
|
|
4635
|
+
- configuration
|
|
4636
|
+
- operational
|
|
4509
4637
|
required:
|
|
4510
4638
|
- name
|
|
4511
4639
|
- passed
|
|
@@ -4523,6 +4651,13 @@ paths:
|
|
|
4523
4651
|
anyOf:
|
|
4524
4652
|
- type: string
|
|
4525
4653
|
- type: "null"
|
|
4654
|
+
indeterminate:
|
|
4655
|
+
type: boolean
|
|
4656
|
+
kind:
|
|
4657
|
+
type: string
|
|
4658
|
+
enum:
|
|
4659
|
+
- configuration
|
|
4660
|
+
- operational
|
|
4526
4661
|
required:
|
|
4527
4662
|
- name
|
|
4528
4663
|
- passed
|
|
@@ -5067,6 +5202,8 @@ paths:
|
|
|
5067
5202
|
provider_connection:
|
|
5068
5203
|
type: string
|
|
5069
5204
|
minLength: 1
|
|
5205
|
+
allowUnlisted:
|
|
5206
|
+
type: boolean
|
|
5070
5207
|
status:
|
|
5071
5208
|
anyOf:
|
|
5072
5209
|
- $ref: "#/components/schemas/ProfileStatus"
|
|
@@ -12572,9 +12709,12 @@ paths:
|
|
|
12572
12709
|
type: boolean
|
|
12573
12710
|
retryLastTurn:
|
|
12574
12711
|
type: boolean
|
|
12712
|
+
appPins:
|
|
12713
|
+
type: boolean
|
|
12575
12714
|
required:
|
|
12576
12715
|
- memoryOptOut
|
|
12577
12716
|
- retryLastTurn
|
|
12717
|
+
- appPins
|
|
12578
12718
|
additionalProperties: false
|
|
12579
12719
|
profiler:
|
|
12580
12720
|
type: object
|
|
@@ -12774,9 +12914,12 @@ paths:
|
|
|
12774
12914
|
type: boolean
|
|
12775
12915
|
retryLastTurn:
|
|
12776
12916
|
type: boolean
|
|
12917
|
+
appPins:
|
|
12918
|
+
type: boolean
|
|
12777
12919
|
required:
|
|
12778
12920
|
- memoryOptOut
|
|
12779
12921
|
- retryLastTurn
|
|
12922
|
+
- appPins
|
|
12780
12923
|
additionalProperties: false
|
|
12781
12924
|
profiler:
|
|
12782
12925
|
type: object
|
|
@@ -14929,6 +15072,38 @@ paths:
|
|
|
14929
15072
|
description: Invalid fields, a profile that cannot serve requests, or attempt to edit a managed profile
|
|
14930
15073
|
"404":
|
|
14931
15074
|
description: Profile not found
|
|
15075
|
+
/v1/inference/profiles/{name}/validate:
|
|
15076
|
+
post:
|
|
15077
|
+
operationId: inference_profiles_by_name_validate_post
|
|
15078
|
+
summary: Probe a saved profile with one minimal request
|
|
15079
|
+
description:
|
|
15080
|
+
"Dispatch one minimal test request through the named profile's resolved model and connection, and classify
|
|
15081
|
+
any failure by which object the user should fix (the profile vs its provider connection). Advisory: the probe
|
|
15082
|
+
never mutates the profile. Returns a null check when there is no verdict to give (missing, disabled, managed, or
|
|
15083
|
+
routing-identity profiles, or a probe timeout). The probe spends one tiny request on the profile's own key."
|
|
15084
|
+
tags:
|
|
15085
|
+
- inference
|
|
15086
|
+
parameters:
|
|
15087
|
+
- name: name
|
|
15088
|
+
in: path
|
|
15089
|
+
required: true
|
|
15090
|
+
schema:
|
|
15091
|
+
type: string
|
|
15092
|
+
responses:
|
|
15093
|
+
"200":
|
|
15094
|
+
description: Successful response
|
|
15095
|
+
content:
|
|
15096
|
+
application/json:
|
|
15097
|
+
schema:
|
|
15098
|
+
type: object
|
|
15099
|
+
properties:
|
|
15100
|
+
check:
|
|
15101
|
+
anyOf:
|
|
15102
|
+
- $ref: "#/components/schemas/InferenceProfileCheck"
|
|
15103
|
+
- type: "null"
|
|
15104
|
+
required:
|
|
15105
|
+
- check
|
|
15106
|
+
additionalProperties: false
|
|
14932
15107
|
/v1/inference/provider-connections:
|
|
14933
15108
|
get:
|
|
14934
15109
|
operationId: inference_providerconnections_get
|
|
@@ -15010,7 +15185,7 @@ paths:
|
|
|
15010
15185
|
content:
|
|
15011
15186
|
application/json:
|
|
15012
15187
|
schema:
|
|
15013
|
-
$ref: "#/components/schemas/
|
|
15188
|
+
$ref: "#/components/schemas/SavedProviderConnection"
|
|
15014
15189
|
"400":
|
|
15015
15190
|
description: Invalid provider or auth schema
|
|
15016
15191
|
"409":
|
|
@@ -15121,7 +15296,7 @@ paths:
|
|
|
15121
15296
|
content:
|
|
15122
15297
|
application/json:
|
|
15123
15298
|
schema:
|
|
15124
|
-
$ref: "#/components/schemas/
|
|
15299
|
+
$ref: "#/components/schemas/SavedProviderConnection"
|
|
15125
15300
|
"400":
|
|
15126
15301
|
description: Invalid auth schema, or attempt to change auth on a managed connection
|
|
15127
15302
|
"404":
|
|
@@ -15468,6 +15643,67 @@ paths:
|
|
|
15468
15643
|
- localGatewayTarget
|
|
15469
15644
|
- success
|
|
15470
15645
|
additionalProperties: false
|
|
15646
|
+
/v1/integrations/ingress/status:
|
|
15647
|
+
get:
|
|
15648
|
+
operationId: integrations_ingress_status_get
|
|
15649
|
+
summary: Get ingress tunnel status
|
|
15650
|
+
description:
|
|
15651
|
+
Probe the configured public ingress URL and report whether a tunnel is serving this assistant.
|
|
15652
|
+
`unconfigured` means no tunnel has ever been recorded (or the ingress is managed for this assistant, as it is
|
|
15653
|
+
when platform-hosted or fronted by a Velay tunnel), `stopped` means a tunnel ran before and is not running now
|
|
15654
|
+
(callback ingress is explicitly switched off, or its URL is gone), `healthy` means the URL answers and fronts
|
|
15655
|
+
this assistant's web app, `unpairable` means it answers but does not serve that app, so a pairing link minted
|
|
15656
|
+
against it would not open, `unreachable` means it does not answer, and `foreign` means it answers for a
|
|
15657
|
+
different assistant. `lastTunnel` names the tunnel to restart, on the states where a recorded one applies to the
|
|
15658
|
+
configured URL.
|
|
15659
|
+
tags:
|
|
15660
|
+
- config
|
|
15661
|
+
responses:
|
|
15662
|
+
"200":
|
|
15663
|
+
description: Successful response
|
|
15664
|
+
content:
|
|
15665
|
+
application/json:
|
|
15666
|
+
schema:
|
|
15667
|
+
type: object
|
|
15668
|
+
properties:
|
|
15669
|
+
state:
|
|
15670
|
+
type: string
|
|
15671
|
+
enum:
|
|
15672
|
+
- unconfigured
|
|
15673
|
+
- stopped
|
|
15674
|
+
- healthy
|
|
15675
|
+
- unpairable
|
|
15676
|
+
- unreachable
|
|
15677
|
+
- foreign
|
|
15678
|
+
publicBaseUrl:
|
|
15679
|
+
description: The probed URL. Set for healthy, unpairable, unreachable, and foreign.
|
|
15680
|
+
type: string
|
|
15681
|
+
lastTunnel:
|
|
15682
|
+
description:
|
|
15683
|
+
The tunnel to restart. Set on stopped whenever one is recorded, and on unpairable, unreachable and foreign
|
|
15684
|
+
when the recorded tunnel fronted the configured URL.
|
|
15685
|
+
type: object
|
|
15686
|
+
properties:
|
|
15687
|
+
provider:
|
|
15688
|
+
type: string
|
|
15689
|
+
publicBaseUrl:
|
|
15690
|
+
type: string
|
|
15691
|
+
required:
|
|
15692
|
+
- provider
|
|
15693
|
+
- publicBaseUrl
|
|
15694
|
+
additionalProperties: false
|
|
15695
|
+
servingAssistantName:
|
|
15696
|
+
description: Name the edge serves under. Set for foreign when it reports one.
|
|
15697
|
+
type: string
|
|
15698
|
+
detail:
|
|
15699
|
+
description: Short failure reason, free of the URL. Set for unreachable, and for unpairable when the edge gave one.
|
|
15700
|
+
type: string
|
|
15701
|
+
checkedAt:
|
|
15702
|
+
description: ISO-8601 instant the probe finished. Set whenever one ran.
|
|
15703
|
+
type: string
|
|
15704
|
+
required:
|
|
15705
|
+
- state
|
|
15706
|
+
additionalProperties: false
|
|
15471
15707
|
/v1/integrations/oauth/start:
|
|
15472
15708
|
post:
|
|
15473
15709
|
operationId: integrations_oauth_start_post
|
|
@@ -17021,6 +17257,34 @@ paths:
|
|
|
17021
17257
|
required:
|
|
17022
17258
|
- status
|
|
17023
17259
|
additionalProperties: false
|
|
17260
|
+
/v1/live-voice/session/end:
|
|
17261
|
+
post:
|
|
17262
|
+
operationId: livevoice_session_end_post
|
|
17263
|
+
summary: End the active live voice session
|
|
17264
|
+
description:
|
|
17265
|
+
Release the assistant's single live-voice session slot, whichever client holds it. Reports whether a
|
|
17266
|
+
session was actually ended; a slot already tearing down reports false, since that teardown releases it on its
|
|
17267
|
+
own.
|
|
17268
|
+
tags:
|
|
17269
|
+
- live-voice
|
|
17270
|
+
responses:
|
|
17271
|
+
"200":
|
|
17272
|
+
description: Successful response
|
|
17273
|
+
content:
|
|
17274
|
+
application/json:
|
|
17275
|
+
schema:
|
|
17276
|
+
type: object
|
|
17277
|
+
properties:
|
|
17278
|
+
ended:
|
|
17279
|
+
type: boolean
|
|
17280
|
+
sessionId:
|
|
17281
|
+
anyOf:
|
|
17282
|
+
- type: string
|
|
17283
|
+
- type: "null"
|
|
17284
|
+
required:
|
|
17285
|
+
- ended
|
|
17286
|
+
- sessionId
|
|
17287
|
+
additionalProperties: false
|
|
17024
17288
|
/v1/llm-request-logs/{id}/context:
|
|
17025
17289
|
get:
|
|
17026
17290
|
operationId: llmrequestlogs_by_id_context_get
|
|
@@ -19054,6 +19318,7 @@ paths:
|
|
|
19054
19318
|
- tavily
|
|
19055
19319
|
- keenable
|
|
19056
19320
|
- firecrawl
|
|
19321
|
+
- fastcrw
|
|
19057
19322
|
resultCount:
|
|
19058
19323
|
type: number
|
|
19059
19324
|
durationMs:
|
|
@@ -19106,6 +19371,7 @@ paths:
|
|
|
19106
19371
|
enum:
|
|
19107
19372
|
- default
|
|
19108
19373
|
- firecrawl
|
|
19374
|
+
- fastcrw
|
|
19109
19375
|
status:
|
|
19110
19376
|
type: number
|
|
19111
19377
|
contentType:
|
|
@@ -19563,6 +19829,7 @@ paths:
|
|
|
19563
19829
|
- tavily
|
|
19564
19830
|
- keenable
|
|
19565
19831
|
- firecrawl
|
|
19832
|
+
- fastcrw
|
|
19566
19833
|
resultCount:
|
|
19567
19834
|
type: number
|
|
19568
19835
|
durationMs:
|
|
@@ -19615,6 +19882,7 @@ paths:
|
|
|
19615
19882
|
enum:
|
|
19616
19883
|
- default
|
|
19617
19884
|
- firecrawl
|
|
19885
|
+
- fastcrw
|
|
19618
19886
|
status:
|
|
19619
19887
|
type: number
|
|
19620
19888
|
contentType:
|
|
@@ -21083,8 +21351,9 @@ paths:
|
|
|
21083
21351
|
summary: Import a .vbundle archive
|
|
21084
21352
|
description:
|
|
21085
21353
|
Commit a .vbundle archive import to disk — destructive. Accepts the bundle as raw bytes
|
|
21086
|
-
(application/octet-stream), multipart/form-data,
|
|
21087
|
-
fetches
|
|
21354
|
+
(application/octet-stream), multipart/form-data, a JSON body with `{ url }` carrying a signed URL the daemon
|
|
21355
|
+
fetches, or a JSON body with `{ path }` pointing at a file staged under the workspace `.restore-staging`
|
|
21356
|
+
directory.
|
|
21088
21357
|
tags:
|
|
21089
21358
|
- migrations
|
|
21090
21359
|
requestBody:
|
|
@@ -21095,11 +21364,13 @@ paths:
|
|
|
21095
21364
|
type: object
|
|
21096
21365
|
properties:
|
|
21097
21366
|
url:
|
|
21367
|
+
description: A signed GCS URL pointing to the .vbundle archive (JSON body path only).
|
|
21098
21368
|
type: string
|
|
21099
21369
|
format: uri
|
|
21100
|
-
|
|
21101
|
-
|
|
21102
|
-
|
|
21370
|
+
path:
|
|
21371
|
+
description: Workspace-relative or absolute path to a staged .vbundle under .restore-staging (JSON body path only).
|
|
21372
|
+
type: string
|
|
21373
|
+
minLength: 1
|
|
21103
21374
|
responses:
|
|
21104
21375
|
"200":
|
|
21105
21376
|
description: Successful response
|
|
@@ -21182,9 +21453,23 @@ paths:
|
|
|
21182
21453
|
post:
|
|
21183
21454
|
operationId: migrations_importpreflight_post
|
|
21184
21455
|
summary: Dry-run import analysis
|
|
21185
|
-
description:
|
|
21456
|
+
description:
|
|
21457
|
+
Validate a .vbundle archive and return a report of what would change on import without modifying data.
|
|
21458
|
+
Accepts raw bytes, multipart form data, or JSON `{ path }` pointing at a file staged under the workspace
|
|
21459
|
+
`.restore-staging` directory.
|
|
21186
21460
|
tags:
|
|
21187
21461
|
- migrations
|
|
21462
|
+
requestBody:
|
|
21463
|
+
required: true
|
|
21464
|
+
content:
|
|
21465
|
+
application/json:
|
|
21466
|
+
schema:
|
|
21467
|
+
type: object
|
|
21468
|
+
properties:
|
|
21469
|
+
path:
|
|
21470
|
+
description: Workspace-relative or absolute path to a staged .vbundle under .restore-staging (JSON body path only).
|
|
21471
|
+
type: string
|
|
21472
|
+
minLength: 1
|
|
21188
21473
|
responses:
|
|
21189
21474
|
"200":
|
|
21190
21475
|
description: Successful response
|
|
@@ -24097,10 +24382,11 @@ paths:
|
|
|
24097
24382
|
summary: Disable a plugin
|
|
24098
24383
|
description:
|
|
24099
24384
|
Disable a plugin in this workspace by dropping a `.disabled` sentinel, mirroring the CLI's `assistant
|
|
24100
|
-
plugins disable <name>`.
|
|
24101
|
-
|
|
24102
|
-
refetch `GET /v1/plugins`. An already-disabled plugin returns
|
|
24103
|
-
(default plugins are stubbed on demand via the `default-`
|
|
24385
|
+
plugins disable <name>`. Awaits the same source reconcile enable uses so the plugin's shutdown hook runs. Tools,
|
|
24386
|
+
injectors, and hook gates also honor the sentinel at read time. Broadcasts a `sync_changed` invalidation
|
|
24387
|
+
carrying the `plugins:list` tag so other clients refetch `GET /v1/plugins`. An already-disabled plugin returns
|
|
24388
|
+
409; a user plugin with no directory returns 404 (default plugins are stubbed on demand via the `default-`
|
|
24389
|
+
prefix); a malformed name returns 400.
|
|
24104
24390
|
tags:
|
|
24105
24391
|
- plugins
|
|
24106
24392
|
parameters:
|
|
@@ -34445,6 +34731,10 @@ components:
|
|
|
34445
34731
|
- type: string
|
|
34446
34732
|
minLength: 1
|
|
34447
34733
|
- type: "null"
|
|
34734
|
+
allowUnlisted:
|
|
34735
|
+
anyOf:
|
|
34736
|
+
- type: boolean
|
|
34737
|
+
- type: "null"
|
|
34448
34738
|
status:
|
|
34449
34739
|
anyOf:
|
|
34450
34740
|
- anyOf:
|
|
@@ -35217,6 +35507,8 @@ components:
|
|
|
35217
35507
|
provider_connection:
|
|
35218
35508
|
type: string
|
|
35219
35509
|
minLength: 1
|
|
35510
|
+
allowUnlisted:
|
|
35511
|
+
type: boolean
|
|
35220
35512
|
status:
|
|
35221
35513
|
anyOf:
|
|
35222
35514
|
- $ref: "#/components/schemas/ProfileStatus"
|
|
@@ -35493,6 +35785,8 @@ components:
|
|
|
35493
35785
|
anyOf:
|
|
35494
35786
|
- $ref: "#/components/schemas/ProfileConnectionAvailability"
|
|
35495
35787
|
- type: "null"
|
|
35788
|
+
config_issue:
|
|
35789
|
+
$ref: "#/components/schemas/InferenceProfileConfigIssue"
|
|
35496
35790
|
required:
|
|
35497
35791
|
- name
|
|
35498
35792
|
- label
|
|
@@ -35521,6 +35815,21 @@ components:
|
|
|
35521
35815
|
required:
|
|
35522
35816
|
- status
|
|
35523
35817
|
additionalProperties: false
|
|
35818
|
+
InferenceProfileConfigIssue:
|
|
35819
|
+
type: object
|
|
35820
|
+
properties:
|
|
35821
|
+
code:
|
|
35822
|
+
type: string
|
|
35823
|
+
enum:
|
|
35824
|
+
- model_unknown
|
|
35825
|
+
- over_output_cap
|
|
35826
|
+
- no_input_room
|
|
35827
|
+
message:
|
|
35828
|
+
type: string
|
|
35829
|
+
required:
|
|
35830
|
+
- code
|
|
35831
|
+
- message
|
|
35832
|
+
additionalProperties: false
|
|
35524
35833
|
InferenceProfileWriteResult:
|
|
35525
35834
|
type: object
|
|
35526
35835
|
properties:
|
|
@@ -35561,11 +35870,36 @@ components:
|
|
|
35561
35870
|
anyOf:
|
|
35562
35871
|
- $ref: "#/components/schemas/ProfileConnectionAvailability"
|
|
35563
35872
|
- type: "null"
|
|
35873
|
+
config_issue:
|
|
35874
|
+
$ref: "#/components/schemas/InferenceProfileConfigIssue"
|
|
35564
35875
|
required:
|
|
35565
35876
|
- name
|
|
35566
35877
|
- entry
|
|
35567
35878
|
- availability
|
|
35568
35879
|
additionalProperties: false
|
|
35880
|
+
InferenceProfileCheck:
|
|
35881
|
+
type: object
|
|
35882
|
+
properties:
|
|
35883
|
+
ok:
|
|
35884
|
+
type: boolean
|
|
35885
|
+
blame:
|
|
35886
|
+
type: string
|
|
35887
|
+
enum:
|
|
35888
|
+
- profile
|
|
35889
|
+
- provider
|
|
35890
|
+
- transient
|
|
35891
|
+
- unknown
|
|
35892
|
+
reason:
|
|
35893
|
+
type: string
|
|
35894
|
+
detail:
|
|
35895
|
+
type: string
|
|
35896
|
+
connection:
|
|
35897
|
+
type: string
|
|
35898
|
+
message:
|
|
35899
|
+
type: string
|
|
35900
|
+
required:
|
|
35901
|
+
- ok
|
|
35902
|
+
additionalProperties: false
|
|
35569
35903
|
ProviderConnection:
|
|
35570
35904
|
type: object
|
|
35571
35905
|
properties:
|
|
@@ -35613,6 +35947,78 @@ components:
|
|
|
35613
35947
|
- updatedAt
|
|
35614
35948
|
- isManaged
|
|
35615
35949
|
additionalProperties: false
|
|
35950
|
+
SavedProviderConnection:
|
|
35951
|
+
type: object
|
|
35952
|
+
properties:
|
|
35953
|
+
name:
|
|
35954
|
+
type: string
|
|
35955
|
+
minLength: 1
|
|
35956
|
+
provider:
|
|
35957
|
+
$ref: "#/components/schemas/ConnectionProvider"
|
|
35958
|
+
auth:
|
|
35959
|
+
$ref: "#/components/schemas/AuthOutput"
|
|
35960
|
+
label:
|
|
35961
|
+
anyOf:
|
|
35962
|
+
- type: string
|
|
35963
|
+
minLength: 1
|
|
35964
|
+
- type: "null"
|
|
35965
|
+
baseUrl:
|
|
35966
|
+
anyOf:
|
|
35967
|
+
- type: string
|
|
35968
|
+
format: uri
|
|
35969
|
+
- type: "null"
|
|
35970
|
+
models:
|
|
35971
|
+
anyOf:
|
|
35972
|
+
- type: array
|
|
35973
|
+
items:
|
|
35974
|
+
$ref: "#/components/schemas/ConnectionModelOutput"
|
|
35975
|
+
- type: "null"
|
|
35976
|
+
createdAt:
|
|
35977
|
+
type: integer
|
|
35978
|
+
minimum: -9007199254740991
|
|
35979
|
+
maximum: 9007199254740991
|
|
35980
|
+
updatedAt:
|
|
35981
|
+
type: integer
|
|
35982
|
+
minimum: -9007199254740991
|
|
35983
|
+
maximum: 9007199254740991
|
|
35984
|
+
isManaged:
|
|
35985
|
+
type: boolean
|
|
35986
|
+
endpoint_check:
|
|
35987
|
+
$ref: "#/components/schemas/EndpointCheck"
|
|
35988
|
+
required:
|
|
35989
|
+
- name
|
|
35990
|
+
- provider
|
|
35991
|
+
- auth
|
|
35992
|
+
- label
|
|
35993
|
+
- baseUrl
|
|
35994
|
+
- models
|
|
35995
|
+
- createdAt
|
|
35996
|
+
- updatedAt
|
|
35997
|
+
- isManaged
|
|
35998
|
+
additionalProperties: false
|
|
35999
|
+
EndpointCheck:
|
|
36000
|
+
type: object
|
|
36001
|
+
properties:
|
|
36002
|
+
ok:
|
|
36003
|
+
type: boolean
|
|
36004
|
+
status:
|
|
36005
|
+
type: integer
|
|
36006
|
+
minimum: -9007199254740991
|
|
36007
|
+
maximum: 9007199254740991
|
|
36008
|
+
resolved_url:
|
|
36009
|
+
type: string
|
|
36010
|
+
error_class:
|
|
36011
|
+
type: string
|
|
36012
|
+
enum:
|
|
36013
|
+
- http_error
|
|
36014
|
+
- timeout
|
|
36015
|
+
- network
|
|
36016
|
+
hint:
|
|
36017
|
+
type: string
|
|
36018
|
+
required:
|
|
36019
|
+
- ok
|
|
36020
|
+
- resolved_url
|
|
36021
|
+
additionalProperties: false
|
|
35616
36022
|
ProcessEntry:
|
|
35617
36023
|
type: object
|
|
35618
36024
|
properties:
|
package/package.json
CHANGED
|
@@ -67,6 +67,12 @@ function projectProvider(
|
|
|
67
67
|
if (entry.privacyPolicyUrl !== undefined) {
|
|
68
68
|
projected.privacyPolicyUrl = entry.privacyPolicyUrl;
|
|
69
69
|
}
|
|
70
|
+
if (entry.supportsApiBase !== undefined) {
|
|
71
|
+
projected.supportsApiBase = entry.supportsApiBase;
|
|
72
|
+
}
|
|
73
|
+
if (entry.defaultApiBase !== undefined) {
|
|
74
|
+
projected.defaultApiBase = entry.defaultApiBase;
|
|
75
|
+
}
|
|
70
76
|
return projected;
|
|
71
77
|
}
|
|
72
78
|
|