@lerianstudio/matcher-mcp 5.0.0-beta.8 → 5.0.0-beta.80
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 +28 -13
- package/dist/auth/request-token.js +11 -69
- package/dist/auth/request-token.js.map +1 -1
- package/dist/config.js +6 -21
- package/dist/config.js.map +1 -1
- package/dist/copilot/agent.js +5 -9
- package/dist/copilot/agent.js.map +1 -1
- package/dist/copilot/provider-anthropic.js +75 -23
- package/dist/copilot/provider-anthropic.js.map +1 -1
- package/dist/copilot/provider-openrouter.js +5 -18
- package/dist/copilot/provider-openrouter.js.map +1 -1
- package/dist/copilot/provider-shared.js +11 -0
- package/dist/copilot/provider-shared.js.map +1 -1
- package/dist/copilot/speech-provider.js +84 -0
- package/dist/copilot/speech-provider.js.map +1 -0
- package/dist/copilot/sse.js +5 -0
- package/dist/copilot/sse.js.map +1 -1
- package/dist/copilot/tools.js +14 -65
- package/dist/copilot/tools.js.map +1 -1
- package/dist/copilot/transcribe-handler.js +8 -93
- package/dist/copilot/transcribe-handler.js.map +1 -1
- package/dist/copilot/turn-request.js +76 -0
- package/dist/copilot/turn-request.js.map +1 -0
- package/dist/copilot/turns-handler.js +11 -102
- package/dist/copilot/turns-handler.js.map +1 -1
- package/dist/matcher/client.js +14 -0
- package/dist/matcher/client.js.map +1 -1
- package/dist/matcher/idempotency.js +94 -0
- package/dist/matcher/idempotency.js.map +1 -0
- package/dist/observability/otel.js +7 -29
- package/dist/observability/otel.js.map +1 -1
- package/dist/server.js +12 -81
- package/dist/server.js.map +1 -1
- package/dist/spec/curated-operations.js +111 -95
- package/dist/spec/curated-operations.js.map +1 -1
- package/dist/spec/enum-policy.js +21 -26
- package/dist/spec/enum-policy.js.map +1 -1
- package/dist/spec/openapi.yaml +841 -56
- package/dist/spec/schema-parity.js +23 -28
- package/dist/spec/schema-parity.js.map +1 -1
- package/dist/tools/context/create.js +3 -2
- package/dist/tools/context/create.js.map +1 -1
- package/dist/tools/context/index.js +137 -17
- package/dist/tools/context/index.js.map +1 -1
- package/dist/tools/context/list.js +9 -35
- package/dist/tools/context/list.js.map +1 -1
- package/dist/tools/context/setup-progress.js +3 -2
- package/dist/tools/context/setup-progress.js.map +1 -1
- package/dist/tools/context/shared.js +7 -48
- package/dist/tools/context/shared.js.map +1 -1
- package/dist/tools/context/update.js +5 -5
- package/dist/tools/context/update.js.map +1 -1
- package/dist/tools/curated-tool.js +39 -0
- package/dist/tools/curated-tool.js.map +1 -0
- package/dist/tools/dashboard/index.js +124 -19
- package/dist/tools/dashboard/index.js.map +1 -1
- package/dist/tools/dashboard/shared.js +9 -68
- package/dist/tools/dashboard/shared.js.map +1 -1
- package/dist/tools/dispute/close.js +5 -5
- package/dist/tools/dispute/close.js.map +1 -1
- package/dist/tools/dispute/index.js +34 -6
- package/dist/tools/dispute/index.js.map +1 -1
- package/dist/tools/dispute/list.js +18 -47
- package/dist/tools/dispute/list.js.map +1 -1
- package/dist/tools/dispute/shared.js +4 -43
- package/dist/tools/dispute/shared.js.map +1 -1
- package/dist/tools/dispute/submit-evidence.js +5 -5
- package/dist/tools/dispute/submit-evidence.js.map +1 -1
- package/dist/tools/exception/add-comment.js +3 -2
- package/dist/tools/exception/add-comment.js.map +1 -1
- package/dist/tools/exception/adjust-entry.js +5 -5
- package/dist/tools/exception/adjust-entry.js.map +1 -1
- package/dist/tools/exception/bulk-assign.js +3 -2
- package/dist/tools/exception/bulk-assign.js.map +1 -1
- package/dist/tools/exception/bulk-dispatch.js +12 -4
- package/dist/tools/exception/bulk-dispatch.js.map +1 -1
- package/dist/tools/exception/bulk-resolve.js +3 -2
- package/dist/tools/exception/bulk-resolve.js.map +1 -1
- package/dist/tools/exception/dispatch.js +13 -5
- package/dist/tools/exception/dispatch.js.map +1 -1
- package/dist/tools/exception/force-match.js +3 -2
- package/dist/tools/exception/force-match.js.map +1 -1
- package/dist/tools/exception/history.js +8 -24
- package/dist/tools/exception/history.js.map +1 -1
- package/dist/tools/exception/index.js +88 -18
- package/dist/tools/exception/index.js.map +1 -1
- package/dist/tools/exception/list.js +14 -57
- package/dist/tools/exception/list.js.map +1 -1
- package/dist/tools/exception/open-dispute.js +3 -2
- package/dist/tools/exception/open-dispute.js.map +1 -1
- package/dist/tools/exception/shared.js +10 -46
- package/dist/tools/exception/shared.js.map +1 -1
- package/dist/tools/fee-rule/create.js +5 -5
- package/dist/tools/fee-rule/create.js.map +1 -1
- package/dist/tools/fee-rule/index.js +50 -8
- package/dist/tools/fee-rule/index.js.map +1 -1
- package/dist/tools/fee-rule/list.js +9 -29
- package/dist/tools/fee-rule/list.js.map +1 -1
- package/dist/tools/fee-rule/shared.js +5 -47
- package/dist/tools/fee-rule/shared.js.map +1 -1
- package/dist/tools/fee-rule/update.js +5 -5
- package/dist/tools/fee-rule/update.js.map +1 -1
- package/dist/tools/fee-schedule/create.js +8 -3
- package/dist/tools/fee-schedule/create.js.map +1 -1
- package/dist/tools/fee-schedule/index.js +62 -11
- package/dist/tools/fee-schedule/index.js.map +1 -1
- package/dist/tools/fee-schedule/list.js +8 -24
- package/dist/tools/fee-schedule/list.js.map +1 -1
- package/dist/tools/fee-schedule/shared.js +5 -44
- package/dist/tools/fee-schedule/shared.js.map +1 -1
- package/dist/tools/fee-schedule/simulate.js +5 -5
- package/dist/tools/fee-schedule/simulate.js.map +1 -1
- package/dist/tools/fee-schedule/update.js +5 -5
- package/dist/tools/fee-schedule/update.js.map +1 -1
- package/dist/tools/field-map/create.js +3 -2
- package/dist/tools/field-map/create.js.map +1 -1
- package/dist/tools/field-map/index.js +65 -11
- package/dist/tools/field-map/index.js.map +1 -1
- package/dist/tools/field-map/list.js +9 -29
- package/dist/tools/field-map/list.js.map +1 -1
- package/dist/tools/field-map/shared.js +6 -42
- package/dist/tools/field-map/shared.js.map +1 -1
- package/dist/tools/field-map/update.js +3 -2
- package/dist/tools/field-map/update.js.map +1 -1
- package/dist/tools/generic/invoke.js +16 -39
- package/dist/tools/generic/invoke.js.map +1 -1
- package/dist/tools/ingestion/index.js +100 -12
- package/dist/tools/ingestion/index.js.map +1 -1
- package/dist/tools/ingestion/job-transactions-list.js +10 -40
- package/dist/tools/ingestion/job-transactions-list.js.map +1 -1
- package/dist/tools/ingestion/jobs-list.js +9 -35
- package/dist/tools/ingestion/jobs-list.js.map +1 -1
- package/dist/tools/ingestion/shared.js +4 -41
- package/dist/tools/ingestion/shared.js.map +1 -1
- package/dist/tools/ingestion/transactions-search.js +9 -44
- package/dist/tools/ingestion/transactions-search.js.map +1 -1
- package/dist/tools/ingestion/upload-begin.js +5 -2
- package/dist/tools/ingestion/upload-begin.js.map +1 -1
- package/dist/tools/ingestion/upload.js +3 -2
- package/dist/tools/ingestion/upload.js.map +1 -1
- package/dist/tools/input-fields.js +51 -0
- package/dist/tools/input-fields.js.map +1 -0
- package/dist/tools/match-rule/index.js +130 -13
- package/dist/tools/match-rule/index.js.map +1 -1
- package/dist/tools/match-rule/list.js +9 -33
- package/dist/tools/match-rule/list.js.map +1 -1
- package/dist/tools/match-rule/shared.js +16 -46
- package/dist/tools/match-rule/shared.js.map +1 -1
- package/dist/tools/match-rule/update.js +7 -11
- package/dist/tools/match-rule/update.js.map +1 -1
- package/dist/tools/matching/get.js +5 -5
- package/dist/tools/matching/get.js.map +1 -1
- package/dist/tools/matching/groups.js +6 -14
- package/dist/tools/matching/groups.js.map +1 -1
- package/dist/tools/matching/index.js +77 -5
- package/dist/tools/matching/index.js.map +1 -1
- package/dist/tools/matching/list.js +9 -32
- package/dist/tools/matching/list.js.map +1 -1
- package/dist/tools/matching/shared.js +5 -46
- package/dist/tools/matching/shared.js.map +1 -1
- package/dist/tools/query-handler.js +9 -0
- package/dist/tools/query-handler.js.map +1 -0
- package/dist/tools/report/index.js +260 -30
- package/dist/tools/report/index.js.map +1 -1
- package/dist/tools/report/shared.js +24 -98
- package/dist/tools/report/shared.js.map +1 -1
- package/dist/tools/request-fields.js +17 -0
- package/dist/tools/request-fields.js.map +1 -0
- package/dist/tools/shared-dispatch.js +38 -0
- package/dist/tools/shared-dispatch.js.map +1 -0
- package/dist/tools/source/create.js +146 -23
- package/dist/tools/source/create.js.map +1 -1
- package/dist/tools/source/index.js +101 -13
- package/dist/tools/source/index.js.map +1 -1
- package/dist/tools/source/list.js +9 -32
- package/dist/tools/source/list.js.map +1 -1
- package/dist/tools/source/shared.js +5 -42
- package/dist/tools/source/shared.js.map +1 -1
- package/dist/tools/source/update.js +16 -33
- package/dist/tools/source/update.js.map +1 -1
- package/dist/tools/workspace/usage.js +12 -40
- package/dist/tools/workspace/usage.js.map +1 -1
- package/package.json +4 -4
- package/dist/tools/context/archive.js +0 -37
- package/dist/tools/context/archive.js.map +0 -1
- package/dist/tools/context/get.js +0 -31
- package/dist/tools/context/get.js.map +0 -1
- package/dist/tools/context/next-step.js +0 -99
- package/dist/tools/context/next-step.js.map +0 -1
- package/dist/tools/context/restore.js +0 -34
- package/dist/tools/context/restore.js.map +0 -1
- package/dist/tools/dashboard/aggregates.js +0 -37
- package/dist/tools/dashboard/aggregates.js.map +0 -1
- package/dist/tools/dashboard/cash-impact.js +0 -37
- package/dist/tools/dashboard/cash-impact.js.map +0 -1
- package/dist/tools/dashboard/match-rate.js +0 -37
- package/dist/tools/dashboard/match-rate.js.map +0 -1
- package/dist/tools/dashboard/metrics.js +0 -37
- package/dist/tools/dashboard/metrics.js.map +0 -1
- package/dist/tools/dashboard/sla.js +0 -34
- package/dist/tools/dashboard/sla.js.map +0 -1
- package/dist/tools/dashboard/source-breakdown.js +0 -37
- package/dist/tools/dashboard/source-breakdown.js.map +0 -1
- package/dist/tools/dashboard/volume.js +0 -37
- package/dist/tools/dashboard/volume.js.map +0 -1
- package/dist/tools/dispute/get.js +0 -27
- package/dist/tools/dispute/get.js.map +0 -1
- package/dist/tools/exception/delete-comment.js +0 -40
- package/dist/tools/exception/delete-comment.js.map +0 -1
- package/dist/tools/exception/get.js +0 -34
- package/dist/tools/exception/get.js.map +0 -1
- package/dist/tools/exception/list-comments.js +0 -35
- package/dist/tools/exception/list-comments.js.map +0 -1
- package/dist/tools/fee-rule/delete.js +0 -27
- package/dist/tools/fee-rule/delete.js.map +0 -1
- package/dist/tools/fee-rule/get.js +0 -27
- package/dist/tools/fee-rule/get.js.map +0 -1
- package/dist/tools/fee-schedule/delete.js +0 -32
- package/dist/tools/fee-schedule/delete.js.map +0 -1
- package/dist/tools/fee-schedule/get.js +0 -30
- package/dist/tools/fee-schedule/get.js.map +0 -1
- package/dist/tools/field-map/delete.js +0 -37
- package/dist/tools/field-map/delete.js.map +0 -1
- package/dist/tools/field-map/get.js +0 -43
- package/dist/tools/field-map/get.js.map +0 -1
- package/dist/tools/ingestion/job-errors-list.js +0 -45
- package/dist/tools/ingestion/job-errors-list.js.map +0 -1
- package/dist/tools/ingestion/job-get.js +0 -42
- package/dist/tools/ingestion/job-get.js.map +0 -1
- package/dist/tools/ingestion/transaction-ignore.js +0 -51
- package/dist/tools/ingestion/transaction-ignore.js.map +0 -1
- package/dist/tools/match-rule/create.js +0 -67
- package/dist/tools/match-rule/create.js.map +0 -1
- package/dist/tools/match-rule/delete.js +0 -35
- package/dist/tools/match-rule/delete.js.map +0 -1
- package/dist/tools/match-rule/get.js +0 -32
- package/dist/tools/match-rule/get.js.map +0 -1
- package/dist/tools/match-rule/reorder.js +0 -45
- package/dist/tools/match-rule/reorder.js.map +0 -1
- package/dist/tools/matching/start.js +0 -81
- package/dist/tools/matching/start.js.map +0 -1
- package/dist/tools/report/count-exceptions.js +0 -46
- package/dist/tools/report/count-exceptions.js.map +0 -1
- package/dist/tools/report/count-matched.js +0 -47
- package/dist/tools/report/count-matched.js.map +0 -1
- package/dist/tools/report/count-transactions.js +0 -45
- package/dist/tools/report/count-transactions.js.map +0 -1
- package/dist/tools/report/count-unmatched.js +0 -45
- package/dist/tools/report/count-unmatched.js.map +0 -1
- package/dist/tools/report/export-exceptions.js +0 -48
- package/dist/tools/report/export-exceptions.js.map +0 -1
- package/dist/tools/report/export-matched.js +0 -49
- package/dist/tools/report/export-matched.js.map +0 -1
- package/dist/tools/report/export-summary.js +0 -49
- package/dist/tools/report/export-summary.js.map +0 -1
- package/dist/tools/report/export-unmatched.js +0 -49
- package/dist/tools/report/export-unmatched.js.map +0 -1
- package/dist/tools/report/export-variance.js +0 -48
- package/dist/tools/report/export-variance.js.map +0 -1
- package/dist/tools/report/matched.js +0 -48
- package/dist/tools/report/matched.js.map +0 -1
- package/dist/tools/report/summary.js +0 -43
- package/dist/tools/report/summary.js.map +0 -1
- package/dist/tools/report/unmatched.js +0 -48
- package/dist/tools/report/unmatched.js.map +0 -1
- package/dist/tools/report/variance.js +0 -48
- package/dist/tools/report/variance.js.map +0 -1
- package/dist/tools/source/archive.js +0 -46
- package/dist/tools/source/archive.js.map +0 -1
- package/dist/tools/source/get.js +0 -57
- package/dist/tools/source/get.js.map +0 -1
- package/dist/tools/source/restore.js +0 -39
- package/dist/tools/source/restore.js.map +0 -1
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// back into the LLMProvider seam. Stateless per call.
|
|
7
7
|
import OpenAI from 'openai';
|
|
8
8
|
import { CopilotModelRequiredError, CopilotUnconfiguredError } from './provider-factory.js';
|
|
9
|
-
import {
|
|
9
|
+
import { buildTurnResult } from './provider-shared.js';
|
|
10
10
|
const OPENROUTER_BASE_URL = 'https://openrouter.ai/api/v1';
|
|
11
11
|
// The seam's LLMToolResult carries only { id, content }. OpenAI requires each
|
|
12
12
|
// role:'tool' message to answer an assistant message carrying a tool_call with
|
|
@@ -63,7 +63,7 @@ export function createOpenRouterProvider(config, streamFn) {
|
|
|
63
63
|
handlers.onTextDelta(delta.content);
|
|
64
64
|
}
|
|
65
65
|
for (const fragment of delta.tool_calls ?? []) {
|
|
66
|
-
const call = toolCalls.get(fragment.index) ?? { id: '', name: '',
|
|
66
|
+
const call = toolCalls.get(fragment.index) ?? { id: '', name: '', json: '' };
|
|
67
67
|
if (fragment.id !== undefined) {
|
|
68
68
|
call.id = fragment.id;
|
|
69
69
|
}
|
|
@@ -71,28 +71,15 @@ export function createOpenRouterProvider(config, streamFn) {
|
|
|
71
71
|
call.name = fragment.function.name;
|
|
72
72
|
}
|
|
73
73
|
if (fragment.function?.arguments !== undefined) {
|
|
74
|
-
call.
|
|
74
|
+
call.json += fragment.function.arguments;
|
|
75
75
|
}
|
|
76
76
|
toolCalls.set(fragment.index, call);
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
if (toolCalls.size === 0) {
|
|
80
|
-
// ponytail: turn-end is inferred from the absence of tool calls — we do
|
|
81
|
-
// NOT inspect finish_reason, so a length-truncated text answer renders as
|
|
82
|
-
// a clean end. Acceptable: 4096 tokens is ample for grounded config
|
|
83
|
-
// answers, and a truncated WRITE fails safe (partial tool JSON →
|
|
84
|
-
// parseToolInput → {} → assemble rejects → proposal_invalid). Upgrade
|
|
85
|
-
// path: capture finish_reason into the done label if operators hit it.
|
|
86
|
-
return { stop: 'end', ...(usage !== undefined ? { usage } : {}) };
|
|
87
|
-
}
|
|
88
79
|
const calls = [...toolCalls.entries()]
|
|
89
80
|
.sort(([a], [b]) => a - b)
|
|
90
|
-
.map(([, call]) =>
|
|
91
|
-
|
|
92
|
-
name: call.name,
|
|
93
|
-
input: parseToolInput(call.args),
|
|
94
|
-
}));
|
|
95
|
-
return { stop: 'tool_use', calls, ...(usage !== undefined ? { usage } : {}) };
|
|
81
|
+
.map(([, call]) => call);
|
|
82
|
+
return buildTurnResult(calls, usage);
|
|
96
83
|
},
|
|
97
84
|
};
|
|
98
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-openrouter.js","sourceRoot":"","sources":["../../src/copilot/provider-openrouter.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,iFAAiF;AACjF,sDAAsD;AAEtD,OAAO,MAAM,MAAM,QAAQ,CAAA;AAG3B,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAC3F,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"provider-openrouter.js","sourceRoot":"","sources":["../../src/copilot/provider-openrouter.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,iFAAiF;AACjF,sDAAsD;AAEtD,OAAO,MAAM,MAAM,QAAQ,CAAA;AAG3B,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAC3F,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAUtD,MAAM,mBAAmB,GAAG,8BAA8B,CAAA;AAE1D,8EAA8E;AAC9E,+EAA+E;AAC/E,gFAAgF;AAChF,iFAAiF;AACjF,mEAAmE;AACnE,mFAAmF;AACnF,MAAM,wBAAwB,GAAG,MAAM,CAAA;AAOvC;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,MAAc,EACd,QAAyB;IAEzB,MAAM,UAAU,GAAG,QAAQ,IAAI,uBAAuB,CAAC,MAAM,CAAC,CAAA;IAE9D,OAAO;QACL,KAAK,CAAC,UAAU,CACd,KAAmB,EACnB,QAA2B;YAE3B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;YAC3C,MAAM,MAAM,GAA+C;gBACzD,yEAAyE;gBACzE,qEAAqE;gBACrE,yEAAyE;gBACzE,iEAAiE;gBACjE,KAAK,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE;gBAChC,MAAM,EAAE,IAAI;gBACZ,uEAAuE;gBACvE,2DAA2D;gBAC3D,cAAc,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;gBACvC,QAAQ,EAAE,mBAAmB,CAAC,KAAK,CAAC;gBACpC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACvC,CAAA;YAED,yEAAyE;YACzE,kEAAkE;YAClE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAsD,CAAA;YAC/E,2EAA2E;YAC3E,IAAI,KAA2B,CAAA;YAE/B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7C,yEAAyE;gBACzE,mEAAmE;gBACnE,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;oBACxB,KAAK,GAAG;wBACN,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC;wBAC3C,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC;qBACjD,CAAA;gBACH,CAAC;gBACD,uDAAuD;gBACvD,yEAAyE;gBACzE,0DAA0D;gBAC1D,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAA;gBACvC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,SAAQ;gBACV,CAAC;gBACD,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;oBACtC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;gBACrC,CAAC;gBACD,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;oBAC9C,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAA;oBAC5E,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;wBAC9B,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAA;oBACvB,CAAC;oBACD,IAAI,QAAQ,CAAC,QAAQ,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;wBAC1C,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAA;oBACpC,CAAC;oBACD,IAAI,QAAQ,CAAC,QAAQ,EAAE,SAAS,KAAK,SAAS,EAAE,CAAC;wBAC/C,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAA;oBAC1C,CAAC;oBACD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;gBACrC,CAAC;YACH,CAAC;YAED,MAAM,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;iBACnC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;iBACzB,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAA;YAC1B,OAAO,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QACtC,CAAC;KACF,CAAA;AACH,CAAC;AAED,+FAA+F;AAC/F,SAAS,uBAAuB,CAAC,MAAc;IAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAA;IACtC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,wBAAwB,CAAC,YAAY,CAAC,CAAA;IAClD,CAAC;IACD,4EAA4E;IAC5E,wEAAwE;IACxE,uCAAuC;IACvC,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACtC,MAAM,IAAI,yBAAyB,CAAC,YAAY,CAAC,CAAA;IACnD,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAA;IACnE,wEAAwE;IACxE,6EAA6E;IAC7E,OAAO,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC,MAAM;QAClC,KAAK,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACrD,CAAC,CAAA;AACH,CAAC;AAED,SAAS,YAAY,CAAC,GAAe;IACnC,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE;YACR,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,UAAU,EAAE,GAAG,CAAC,WAAW;SAC5B;KACF,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,KAAmB;IAC9C,MAAM,QAAQ,GAAwC;QACpD,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE;QACzC,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;KACvF,CAAA;IAED,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpE,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC7C,EAAE,EAAE,MAAM,CAAC,EAAE;gBACb,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,EAAE,IAAI,EAAE,wBAAwB,EAAE,SAAS,EAAE,IAAI,EAAE;aAC9D,CAAC,CAAC;SACJ,CAAC,CAAA;QACF,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAA;QACnF,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
// Helpers shared by the Anthropic and OpenRouter LLMProvider adapters.
|
|
2
|
+
/** Normalize completed calls; each adapter owns ordering and usage accounting.
|
|
3
|
+
* Stop is inferred from calls, not provider finish reasons: truncated text still
|
|
4
|
+
* ends cleanly, while malformed tool JSON becomes {} for downstream validation.
|
|
5
|
+
*/
|
|
6
|
+
export function buildTurnResult(blocks, usage) {
|
|
7
|
+
const metering = usage !== undefined ? { usage } : {};
|
|
8
|
+
if (blocks.length === 0)
|
|
9
|
+
return { stop: 'end', ...metering };
|
|
10
|
+
const calls = blocks.map(({ id, name, json }) => ({ id, name, input: parseToolInput(json) }));
|
|
11
|
+
return { stop: 'tool_use', calls, ...metering };
|
|
12
|
+
}
|
|
2
13
|
/**
|
|
3
14
|
* Parse accumulated tool-call argument JSON into an input object. A blank or
|
|
4
15
|
* unparseable value resolves to `{}` so a malformed stream never crashes the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-shared.js","sourceRoot":"","sources":["../../src/copilot/provider-shared.ts"],"names":[],"mappings":"AAAA,uEAAuE;
|
|
1
|
+
{"version":3,"file":"provider-shared.js","sourceRoot":"","sources":["../../src/copilot/provider-shared.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAIvE;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAoD,EACpD,KAA2B;IAE3B,MAAM,QAAQ,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IACrD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAA;IAC5D,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;IAC7F,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAA;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;IAC1B,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;QACnB,OAAO,EAAE,CAAA;IACX,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC3C,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5E,OAAO,MAAiC,CAAA;QAC1C,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/** Thrown by the default transcriber when the endpoint answers badly. Carries a
|
|
2
|
+
* status only — never any part of the request or the response body. */
|
|
3
|
+
export class TranscriptionProviderError extends Error {
|
|
4
|
+
status;
|
|
5
|
+
constructor(status) {
|
|
6
|
+
super(status === undefined
|
|
7
|
+
? 'the transcription endpoint could not be reached'
|
|
8
|
+
: `the transcription endpoint answered ${status}`);
|
|
9
|
+
this.name = 'TranscriptionProviderError';
|
|
10
|
+
this.status = status;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** Raised when no transcription capability is configured on this deployment. */
|
|
14
|
+
export class SpeechUnconfiguredError extends Error {
|
|
15
|
+
constructor() {
|
|
16
|
+
super('no transcription capability is configured on this server');
|
|
17
|
+
this.name = 'SpeechUnconfiguredError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** Describe the capability for the console's pre-flight probe. */
|
|
21
|
+
export function describeSpeechCapability(config) {
|
|
22
|
+
return {
|
|
23
|
+
available: config.speechTranscriptionEndpoint !== undefined,
|
|
24
|
+
region: config.speechTranscriptionRegion,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The default transcriber: POST the raw bytes to the configured in-region
|
|
29
|
+
* endpoint with the region and locale as query parameters, and read back
|
|
30
|
+
* `{ "text": "…" }`. Deliberately generic — no vendor SDK, no vendor name. A
|
|
31
|
+
* concrete adapter replaces this behind the same seam once a provider is chosen.
|
|
32
|
+
*/
|
|
33
|
+
export function createHttpTranscriber(config) {
|
|
34
|
+
const endpoint = config.speechTranscriptionEndpoint;
|
|
35
|
+
if (endpoint === undefined) {
|
|
36
|
+
throw new SpeechUnconfiguredError();
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
async transcribe(audio, request) {
|
|
40
|
+
const url = new URL(endpoint);
|
|
41
|
+
url.searchParams.set('region', request.region);
|
|
42
|
+
if (request.locale !== undefined) {
|
|
43
|
+
url.searchParams.set('locale', request.locale);
|
|
44
|
+
}
|
|
45
|
+
const headers = { 'Content-Type': request.contentType };
|
|
46
|
+
if (config.speechTranscriptionApiKey !== undefined) {
|
|
47
|
+
headers.Authorization = `Bearer ${config.speechTranscriptionApiKey}`;
|
|
48
|
+
}
|
|
49
|
+
let response;
|
|
50
|
+
try {
|
|
51
|
+
// Bounded like every other outbound call this server makes: a hung
|
|
52
|
+
// provider must not pin the request — and the audio buffer with it —
|
|
53
|
+
// open indefinitely. The abort surfaces as the same generic provider
|
|
54
|
+
// error, so no transport detail reaches the caller.
|
|
55
|
+
response = await fetch(url, {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
headers,
|
|
58
|
+
body: audio,
|
|
59
|
+
signal: AbortSignal.timeout(config.timeoutMs),
|
|
60
|
+
// The configured endpoint is validated HTTPS-only, but a redirect is a
|
|
61
|
+
// second destination that validation never saw: a 307/308 would forward
|
|
62
|
+
// the recording — and the bearer key — wherever the provider points.
|
|
63
|
+
// Refuse redirects outright; the failure surfaces as the same generic
|
|
64
|
+
// provider error every other transport fault maps to.
|
|
65
|
+
redirect: 'error',
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// The transport error is swallowed on purpose: an undici/agent error can
|
|
70
|
+
// carry the request (headers, body) in its cause chain.
|
|
71
|
+
throw new TranscriptionProviderError();
|
|
72
|
+
}
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
throw new TranscriptionProviderError(response.status);
|
|
75
|
+
}
|
|
76
|
+
const payload = (await response.json());
|
|
77
|
+
if (typeof payload.text !== 'string') {
|
|
78
|
+
throw new TranscriptionProviderError(response.status);
|
|
79
|
+
}
|
|
80
|
+
return payload.text;
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=speech-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speech-provider.js","sourceRoot":"","sources":["../../src/copilot/speech-provider.ts"],"names":[],"mappings":"AAyBA;uEACuE;AACvE,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAC1C,MAAM,CAAoB;IAEnC,YAAY,MAAe;QACzB,KAAK,CACH,MAAM,KAAK,SAAS;YAClB,CAAC,CAAC,iDAAiD;YACnD,CAAC,CAAC,uCAAuC,MAAM,EAAE,CACpD,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAA;QACxC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;CACF;AAED,gFAAgF;AAChF,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAChD;QACE,KAAK,CAAC,0DAA0D,CAAC,CAAA;QACjE,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;IACvC,CAAC;CACF;AAQD,kEAAkE;AAClE,MAAM,UAAU,wBAAwB,CAAC,MAAc;IACrD,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,2BAA2B,KAAK,SAAS;QAC3D,MAAM,EAAE,MAAM,CAAC,yBAAyB;KACzC,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,MAAM,QAAQ,GAAG,MAAM,CAAC,2BAA2B,CAAA;IACnD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,uBAAuB,EAAE,CAAA;IACrC,CAAC;IACD,OAAO;QACL,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO;YAC7B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAA;YAC7B,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;YAC9C,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;YAChD,CAAC;YACD,MAAM,OAAO,GAA2B,EAAE,cAAc,EAAE,OAAO,CAAC,WAAW,EAAE,CAAA;YAC/E,IAAI,MAAM,CAAC,yBAAyB,KAAK,SAAS,EAAE,CAAC;gBACnD,OAAO,CAAC,aAAa,GAAG,UAAU,MAAM,CAAC,yBAAyB,EAAE,CAAA;YACtE,CAAC;YACD,IAAI,QAAkB,CAAA;YACtB,IAAI,CAAC;gBACH,mEAAmE;gBACnE,qEAAqE;gBACrE,qEAAqE;gBACrE,oDAAoD;gBACpD,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;oBAC1B,MAAM,EAAE,MAAM;oBACd,OAAO;oBACP,IAAI,EAAE,KAAK;oBACX,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC;oBAC7C,uEAAuE;oBACvE,wEAAwE;oBACxE,qEAAqE;oBACrE,sEAAsE;oBACtE,sDAAsD;oBACtD,QAAQ,EAAE,OAAO;iBAClB,CAAC,CAAA;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,yEAAyE;gBACzE,wDAAwD;gBACxD,MAAM,IAAI,0BAA0B,EAAE,CAAA;YACxC,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,0BAA0B,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;YACvD,CAAC;YACD,MAAM,OAAO,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuB,CAAA;YAC7D,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrC,MAAM,IAAI,0BAA0B,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;YACvD,CAAC;YACD,OAAO,OAAO,CAAC,IAAI,CAAA;QACrB,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/dist/copilot/sse.js
CHANGED
|
@@ -66,4 +66,9 @@ export function createSseSink(res) {
|
|
|
66
66
|
isClosed: () => closed,
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
|
+
/** End a failed turn without changing the sink's recoverable-error contract. */
|
|
70
|
+
export function finishWithError(sink, code, detail) {
|
|
71
|
+
sink.error(code, detail);
|
|
72
|
+
sink.done('end');
|
|
73
|
+
}
|
|
69
74
|
//# sourceMappingURL=sse.js.map
|
package/dist/copilot/sse.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/copilot/sse.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,8EAA8E;AAC9E,8EAA8E;AAC9E,+EAA+E;AAC/E,uEAAuE;AACvE,EAAE;AACF,8EAA8E;AAC9E,2EAA2E;AAC3E,UAAU;AAIV,8EAA8E;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAA;AAmClC;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,GAAmB;IAC/C,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,MAAM,GAAG,KAAK,CAAA;IAElB,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,IAAa,EAAQ,EAAE;QAClD,IAAI,MAAM;YAAE,OAAM;QAClB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,IAAI,CAAA;YACd,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACjB,cAAc,EAAE,mBAAmB;gBACnC,eAAe,EAAE,UAAU;gBAC3B,UAAU,EAAE,YAAY;aACzB,CAAC,CAAA;QACJ,CAAC;QACD,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,WAAW,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACjE,CAAC,CAAA;IAED,0EAA0E;IAC1E,2EAA2E;IAC3E,2EAA2E;IAC3E,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;QACjC,IAAI,MAAM,IAAI,CAAC,OAAO;YAAE,OAAM;QAC9B,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IACzB,CAAC,EAAE,YAAY,CAAC,CAAA;IAChB,2DAA2D;IAC3D,SAAS,CAAC,KAAK,EAAE,EAAE,CAAA;IAEnB,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,IAAI,MAAM;YAAE,OAAM;QAClB,MAAM,GAAG,IAAI,CAAA;QACb,aAAa,CAAC,SAAS,CAAC,CAAA;QACxB,GAAG,CAAC,GAAG,EAAE,CAAA;IACX,CAAC,CAAA;IAED,4DAA4D;IAC5D,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAEtB,OAAO;QACL,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC;QACxC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACtD,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC;QAChD,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACxD,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;YACb,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;YACtB,KAAK,EAAE,CAAA;QACT,CAAC;QACD,KAAK;QACL,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM;KACvB,CAAA;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/copilot/sse.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,8EAA8E;AAC9E,8EAA8E;AAC9E,+EAA+E;AAC/E,uEAAuE;AACvE,EAAE;AACF,8EAA8E;AAC9E,2EAA2E;AAC3E,UAAU;AAIV,8EAA8E;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAA;AAmClC;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,GAAmB;IAC/C,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,MAAM,GAAG,KAAK,CAAA;IAElB,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,IAAa,EAAQ,EAAE;QAClD,IAAI,MAAM;YAAE,OAAM;QAClB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,IAAI,CAAA;YACd,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACjB,cAAc,EAAE,mBAAmB;gBACnC,eAAe,EAAE,UAAU;gBAC3B,UAAU,EAAE,YAAY;aACzB,CAAC,CAAA;QACJ,CAAC;QACD,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,WAAW,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACjE,CAAC,CAAA;IAED,0EAA0E;IAC1E,2EAA2E;IAC3E,2EAA2E;IAC3E,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;QACjC,IAAI,MAAM,IAAI,CAAC,OAAO;YAAE,OAAM;QAC9B,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IACzB,CAAC,EAAE,YAAY,CAAC,CAAA;IAChB,2DAA2D;IAC3D,SAAS,CAAC,KAAK,EAAE,EAAE,CAAA;IAEnB,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,IAAI,MAAM;YAAE,OAAM;QAClB,MAAM,GAAG,IAAI,CAAA;QACb,aAAa,CAAC,SAAS,CAAC,CAAA;QACxB,GAAG,CAAC,GAAG,EAAE,CAAA;IACX,CAAC,CAAA;IAED,4DAA4D;IAC5D,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAEtB,OAAO;QACL,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC;QACxC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACtD,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC;QAChD,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACxD,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;YACb,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;YACtB,KAAK,EAAE,CAAA;QACT,CAAC;QACD,KAAK;QACL,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM;KACvB,CAAA;AACH,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,eAAe,CAAC,IAAa,EAAE,IAAY,EAAE,MAAc;IACzE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACxB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AAClB,CAAC"}
|
package/dist/copilot/tools.js
CHANGED
|
@@ -1,27 +1,9 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// 3. ADVISORY — one def per `ADVISORY_ALLOWLIST` member
|
|
8
|
-
// (`buildAdvisoryToolDefs`). POST-shaped operations that COMPUTE an answer and
|
|
9
|
-
// persist nothing, so they execute INLINE like a read: no proposal, no turn
|
|
10
|
-
// end. A confirmation click on "show me what this fee would compute" is
|
|
11
|
-
// friction with no safety value.
|
|
12
|
-
//
|
|
13
|
-
// The advisory list is enumerated BY HAND and never derived from a spec heuristic
|
|
14
|
-
// — "the summary says simulate" is not a safety property. Its whole risk is that a
|
|
15
|
-
// member which actually writes would write with NO human in the loop, so the
|
|
16
|
-
// widening ships with a behavioural guard rather than a textual one:
|
|
17
|
-
// `tests/integration/server/copilot_advisory_no_write_test.go` reads this list,
|
|
18
|
-
// invokes every member against a live matcher, and fails if any row count in the
|
|
19
|
-
// database moved. A positive control in the same test writes on purpose, so a
|
|
20
|
-
// broken snapshot cannot pass the guard vacuously.
|
|
21
|
-
//
|
|
22
|
-
// The index is parsed once and memoized (`getIndex`), mirroring server.ts's
|
|
23
|
-
// boot-index memo so the tool-list builder and the executor share one parse and
|
|
24
|
-
// importing this module never touches the filesystem.
|
|
1
|
+
// Copilot tools: GET reads execute inline; allowlisted writes become proposals
|
|
2
|
+
// requiring human confirmation; explicitly allowlisted non-persistent POSTs run
|
|
3
|
+
// inline as advisory tools. Never infer advisory safety from spec descriptions.
|
|
4
|
+
// tests/integration/server/copilot_advisory_no_write_test.go verifies every
|
|
5
|
+
// advisory operation leaves database row counts unchanged, with a writing control.
|
|
6
|
+
// The immutable operation index is loaded lazily and shared by builders/executors.
|
|
25
7
|
import { requireMatcherClient } from '../auth/request-token.js';
|
|
26
8
|
import { loadSpec } from '../spec/load.js';
|
|
27
9
|
import { InvokeError, Invoker } from '../tools/generic/invoke.js';
|
|
@@ -36,11 +18,8 @@ export function getIndex() {
|
|
|
36
18
|
return indexCache;
|
|
37
19
|
}
|
|
38
20
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* production path is built once; an injected index (tests) is memoized under its
|
|
42
|
-
* own identity, so it never returns another index's stale lists. The def-array
|
|
43
|
-
* synthesis is pure over the immutable index, so caching it is sound.
|
|
21
|
+
* Cache pure tool definitions by immutable index identity, never across distinct
|
|
22
|
+
* injected indexes. The production index is stable for the process lifetime.
|
|
44
23
|
*/
|
|
45
24
|
const toolDefsCache = new WeakMap();
|
|
46
25
|
export function getToolDefs(index) {
|
|
@@ -56,20 +35,9 @@ export function getToolDefs(index) {
|
|
|
56
35
|
return cached;
|
|
57
36
|
}
|
|
58
37
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* maps, and source bindings — across the create/update/delete/archive/restore/
|
|
63
|
-
* reorder/clone verbs the spec declares. This set is the write-barrier's positive
|
|
64
|
-
* gate: an operationId absent from it produces NO write tool def
|
|
65
|
-
* (`buildWriteToolDefs`) and the agent loop never routes a call to the proposal
|
|
66
|
-
* path — structurally unproposable, mirroring how a non-GET op is unreadable.
|
|
67
|
-
* Exception, match-run, ingestion, discovery, governance and scheduling
|
|
68
|
-
* mutations are deliberately excluded. The simulate/preview POST-shaped "reads"
|
|
69
|
-
* are excluded from THIS list for the opposite reason — they mutate nothing, so
|
|
70
|
-
* there is nothing to confirm; two of them (`proposeMapping`,
|
|
71
|
-
* `simulateFeeSchedule`) are advertised and executed inline through
|
|
72
|
-
* `ADVISORY_ALLOWLIST` below, and the rest are advertised nowhere.
|
|
38
|
+
* Configuration writes the agent may PROPOSE, never execute. Membership gates
|
|
39
|
+
* both advertised write tools and proposal routing. Other mutation families are
|
|
40
|
+
* excluded; non-persistent advisory operations have their own disjoint allowlist.
|
|
73
41
|
*/
|
|
74
42
|
export const WRITE_ALLOWLIST = new Set([
|
|
75
43
|
// match rules
|
|
@@ -106,28 +74,9 @@ export const WRITE_ALLOWLIST = new Set([
|
|
|
106
74
|
'deleteSourceBinding',
|
|
107
75
|
]);
|
|
108
76
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* - `proposeMapping` — the deterministic column-mapping engine. Refusing it does
|
|
114
|
-
* not remove the mapping decision, it moves it from an engine in production to
|
|
115
|
-
* a language model's reading of a pasted header, at the exact step where being
|
|
116
|
-
* wrong means reconciling the wrong column against money.
|
|
117
|
-
* - `simulateFeeSchedule` — computes a fee breakdown for a gross amount.
|
|
118
|
-
*
|
|
119
|
-
* MEMBERSHIP IS THE WHOLE RISK: an advisory member bypasses the proposal barrier,
|
|
120
|
-
* so a member that writes would write with no confirmation. Two rules follow, and
|
|
121
|
-
* both are asserted rather than documented — see this module's header for the
|
|
122
|
-
* behavioural database guard, and `tools.test.ts` for the disjointness assertion
|
|
123
|
-
* against `WRITE_ALLOWLIST`. Gate ORDERING in `runAgentTurn` is load-bearing:
|
|
124
|
-
* `WRITE_ALLOWLIST` is consulted first, so an id on both lists would take the
|
|
125
|
-
* proposal path and stop the turn — failing toward the human gate, but silently
|
|
126
|
-
* breaking this list's execute-inline contract. The disjointness assertion is
|
|
127
|
-
* what keeps that state unrepresentable rather than order-dependent.
|
|
128
|
-
*
|
|
129
|
-
* `suggestMatchRules` is NOT here and must not be: it persists a PENDING_REVIEW
|
|
130
|
-
* row, so it is a write. Advisory means genuinely non-persistent, not "low stakes".
|
|
77
|
+
* Inline advisory POSTs must persist nothing and remain disjoint from writes
|
|
78
|
+
* (tools.test.ts). The write gate runs first as a fail-safe, not a substitute for
|
|
79
|
+
* disjointness. `suggestMatchRules` persists PENDING_REVIEW and is not advisory.
|
|
131
80
|
*/
|
|
132
81
|
export const ADVISORY_ALLOWLIST = new Set([
|
|
133
82
|
'proposeMapping',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/copilot/tools.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/copilot/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,90 +27,10 @@
|
|
|
27
27
|
import { getRequestTenantId, requireMatcherClient, UnauthenticatedError, } from '../auth/request-token.js';
|
|
28
28
|
import { BodyTooLargeError, readBodyBytes } from '../transport/body-limit.js';
|
|
29
29
|
import { RateLimiter } from './rate-limit.js';
|
|
30
|
+
import { createHttpTranscriber, describeSpeechCapability, SpeechUnconfiguredError, TranscriptionProviderError, } from './speech-provider.js';
|
|
30
31
|
import { probeMatcherAuth } from './turns-handler.js';
|
|
31
|
-
|
|
32
|
-
*
|
|
33
|
-
export class TranscriptionProviderError extends Error {
|
|
34
|
-
status;
|
|
35
|
-
constructor(status) {
|
|
36
|
-
super(status === undefined
|
|
37
|
-
? 'the transcription endpoint could not be reached'
|
|
38
|
-
: `the transcription endpoint answered ${status}`);
|
|
39
|
-
this.name = 'TranscriptionProviderError';
|
|
40
|
-
this.status = status;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/** Raised when no transcription capability is configured on this deployment. */
|
|
44
|
-
export class SpeechUnconfiguredError extends Error {
|
|
45
|
-
constructor() {
|
|
46
|
-
super('no transcription capability is configured on this server');
|
|
47
|
-
this.name = 'SpeechUnconfiguredError';
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
/** Describe the capability for the console's pre-flight probe. */
|
|
51
|
-
export function describeSpeechCapability(config) {
|
|
52
|
-
return {
|
|
53
|
-
available: config.speechTranscriptionEndpoint !== undefined,
|
|
54
|
-
region: config.speechTranscriptionRegion,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* The default transcriber: POST the raw bytes to the configured in-region
|
|
59
|
-
* endpoint with the region and locale as query parameters, and read back
|
|
60
|
-
* `{ "text": "…" }`. Deliberately generic — no vendor SDK, no vendor name. A
|
|
61
|
-
* concrete adapter replaces this behind the same seam once a provider is chosen.
|
|
62
|
-
*/
|
|
63
|
-
export function createHttpTranscriber(config) {
|
|
64
|
-
const endpoint = config.speechTranscriptionEndpoint;
|
|
65
|
-
if (endpoint === undefined) {
|
|
66
|
-
throw new SpeechUnconfiguredError();
|
|
67
|
-
}
|
|
68
|
-
return {
|
|
69
|
-
async transcribe(audio, request) {
|
|
70
|
-
const url = new URL(endpoint);
|
|
71
|
-
url.searchParams.set('region', request.region);
|
|
72
|
-
if (request.locale !== undefined) {
|
|
73
|
-
url.searchParams.set('locale', request.locale);
|
|
74
|
-
}
|
|
75
|
-
const headers = { 'Content-Type': request.contentType };
|
|
76
|
-
if (config.speechTranscriptionApiKey !== undefined) {
|
|
77
|
-
headers.Authorization = `Bearer ${config.speechTranscriptionApiKey}`;
|
|
78
|
-
}
|
|
79
|
-
let response;
|
|
80
|
-
try {
|
|
81
|
-
// Bounded like every other outbound call this server makes: a hung
|
|
82
|
-
// provider must not pin the request — and the audio buffer with it —
|
|
83
|
-
// open indefinitely. The abort surfaces as the same generic provider
|
|
84
|
-
// error, so no transport detail reaches the caller.
|
|
85
|
-
response = await fetch(url, {
|
|
86
|
-
method: 'POST',
|
|
87
|
-
headers,
|
|
88
|
-
body: audio,
|
|
89
|
-
signal: AbortSignal.timeout(config.timeoutMs),
|
|
90
|
-
// The configured endpoint is validated HTTPS-only, but a redirect is a
|
|
91
|
-
// second destination that validation never saw: a 307/308 would forward
|
|
92
|
-
// the recording — and the bearer key — wherever the provider points.
|
|
93
|
-
// Refuse redirects outright; the failure surfaces as the same generic
|
|
94
|
-
// provider error every other transport fault maps to.
|
|
95
|
-
redirect: 'error',
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
catch {
|
|
99
|
-
// The transport error is swallowed on purpose: an undici/agent error can
|
|
100
|
-
// carry the request (headers, body) in its cause chain.
|
|
101
|
-
throw new TranscriptionProviderError();
|
|
102
|
-
}
|
|
103
|
-
if (!response.ok) {
|
|
104
|
-
throw new TranscriptionProviderError(response.status);
|
|
105
|
-
}
|
|
106
|
-
const payload = (await response.json());
|
|
107
|
-
if (typeof payload.text !== 'string') {
|
|
108
|
-
throw new TranscriptionProviderError(response.status);
|
|
109
|
-
}
|
|
110
|
-
return payload.text;
|
|
111
|
-
},
|
|
112
|
-
};
|
|
113
|
-
}
|
|
32
|
+
// Preserve the module's existing public imports while separating HTTP concerns.
|
|
33
|
+
export * from './speech-provider.js';
|
|
114
34
|
/**
|
|
115
35
|
* Per-tenant bound on transcription requests, sharing the copilot's configured
|
|
116
36
|
* rate. Each call spends money at an external provider, so an authenticated but
|
|
@@ -200,13 +120,11 @@ export async function handleTranscribe(config, req, res, deps = {}) {
|
|
|
200
120
|
}
|
|
201
121
|
const contentType = (req.headers['content-type'] ?? '').toLowerCase();
|
|
202
122
|
if (!contentType.startsWith('audio/')) {
|
|
203
|
-
fail(res, 415, 'unsupported_media_type', 'content-type must be an audio media type');
|
|
204
|
-
return;
|
|
123
|
+
return fail(res, 415, 'unsupported_media_type', 'content-type must be an audio media type');
|
|
205
124
|
}
|
|
206
125
|
const decision = (deps.rateLimiter ?? transcribeRateLimiter).check(getRequestTenantId() ?? RATE_LIMIT_ANON_KEY, config.copilotRateLimitPerMin, config.copilotRateLimitBurst);
|
|
207
126
|
if (!decision.allowed) {
|
|
208
|
-
fail(res, 429, 'rate_limited', `too many transcription requests; retry in ${decision.retryAfterSeconds}s`);
|
|
209
|
-
return;
|
|
127
|
+
return fail(res, 429, 'rate_limited', `too many transcription requests; retry in ${decision.retryAfterSeconds}s`);
|
|
210
128
|
}
|
|
211
129
|
let transcriber;
|
|
212
130
|
try {
|
|
@@ -214,8 +132,7 @@ export async function handleTranscribe(config, req, res, deps = {}) {
|
|
|
214
132
|
}
|
|
215
133
|
catch (err) {
|
|
216
134
|
if (err instanceof SpeechUnconfiguredError) {
|
|
217
|
-
fail(res, 503, 'speech_unconfigured', 'voice input is not available on this deployment');
|
|
218
|
-
return;
|
|
135
|
+
return fail(res, 503, 'speech_unconfigured', 'voice input is not available on this deployment');
|
|
219
136
|
}
|
|
220
137
|
throw err;
|
|
221
138
|
}
|
|
@@ -227,14 +144,12 @@ export async function handleTranscribe(config, req, res, deps = {}) {
|
|
|
227
144
|
if (err instanceof BodyTooLargeError) {
|
|
228
145
|
// The guard rejects before the over-limit chunk is retained, so the
|
|
229
146
|
// partial recording is already gone; the message carries byte counts only.
|
|
230
|
-
fail(res, 413, 'payload_too_large', 'the utterance is too long');
|
|
231
|
-
return;
|
|
147
|
+
return fail(res, 413, 'payload_too_large', 'the utterance is too long');
|
|
232
148
|
}
|
|
233
149
|
throw err;
|
|
234
150
|
}
|
|
235
151
|
if (audio.length === 0) {
|
|
236
|
-
fail(res, 400, 'bad_request', 'the request carried no audio');
|
|
237
|
-
return;
|
|
152
|
+
return fail(res, 400, 'bad_request', 'the request carried no audio');
|
|
238
153
|
}
|
|
239
154
|
const locale = req.headers['x-locale'];
|
|
240
155
|
const text = await transcriber.transcribe(audio, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcribe-handler.js","sourceRoot":"","sources":["../../src/copilot/transcribe-handler.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,8EAA8E;AAC9E,iFAAiF;AACjF,8EAA8E;AAC9E,iFAAiF;AACjF,gFAAgF;AAChF,2EAA2E;AAC3E,EAAE;AACF,6EAA6E;AAC7E,iFAAiF;AACjF,gFAAgF;AAChF,gFAAgF;AAChF,+EAA+E;AAC/E,8EAA8E;AAC9E,iFAAiF;AACjF,gFAAgF;AAChF,gFAAgF;AAChF,8CAA8C;AAC9C,EAAE;AACF,gFAAgF;AAChF,oEAAoE;AACpE,6EAA6E;AAC7E,gFAAgF;AAChF,4EAA4E;AAC5E,sBAAsB;AAItB,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,0BAA0B,CAAA;AAGjC,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC7E,OAAO,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"transcribe-handler.js","sourceRoot":"","sources":["../../src/copilot/transcribe-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The messages the agent loop receives. Browser-supplied `screenContext` is
|
|
3
|
+
* injected as a synthetic FIRST user message — the SAME (untrusted) trust tier as
|
|
4
|
+
* the operator's own input — rather than folded into the system prompt, so a
|
|
5
|
+
* crafted route/summary can never reach the higher-trust system tier. The label
|
|
6
|
+
* is a plain statement of fact, not an instruction.
|
|
7
|
+
*/
|
|
8
|
+
export function buildTurnMessages(request) {
|
|
9
|
+
const { screenContext } = request;
|
|
10
|
+
if (screenContext === undefined) {
|
|
11
|
+
return request.messages;
|
|
12
|
+
}
|
|
13
|
+
const parts = [`route ${screenContext.route}`];
|
|
14
|
+
if (screenContext.contextId !== undefined) {
|
|
15
|
+
parts.push(`reconciliation context ${screenContext.contextId}`);
|
|
16
|
+
}
|
|
17
|
+
if (screenContext.summary !== undefined) {
|
|
18
|
+
parts.push(screenContext.summary);
|
|
19
|
+
}
|
|
20
|
+
return [
|
|
21
|
+
{
|
|
22
|
+
role: 'user',
|
|
23
|
+
content: `[screen context] The operator is currently viewing: ${parts.join(' — ')}.`,
|
|
24
|
+
},
|
|
25
|
+
...request.messages,
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Validate an unknown parsed body as an `AgentTurnRequest`. Returns the typed
|
|
30
|
+
* request on success, or `undefined` when the shape is wrong (non-empty
|
|
31
|
+
* `messages` of `{role,content}` with role in {user,assistant}). A malformed
|
|
32
|
+
* `screenContext` is dropped rather than rejecting the turn.
|
|
33
|
+
*/
|
|
34
|
+
export function parseAgentTurnRequest(body) {
|
|
35
|
+
if (typeof body !== 'object' || body === null) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
const record = body;
|
|
39
|
+
const { messages } = record;
|
|
40
|
+
if (!Array.isArray(messages) || messages.length === 0) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
for (const message of messages) {
|
|
44
|
+
if (typeof message !== 'object' || message === null) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const { role, content } = message;
|
|
48
|
+
if (role !== 'user' && role !== 'assistant') {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
if (typeof content !== 'string') {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const screenContext = parseScreenContext(record.screenContext);
|
|
56
|
+
return {
|
|
57
|
+
messages: messages,
|
|
58
|
+
...(screenContext !== undefined ? { screenContext } : {}),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** Parse an optional `screenContext`; drops it unless it carries a string `route`. */
|
|
62
|
+
function parseScreenContext(raw) {
|
|
63
|
+
if (typeof raw !== 'object' || raw === null) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
const record = raw;
|
|
67
|
+
if (typeof record.route !== 'string') {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
route: record.route,
|
|
72
|
+
...(typeof record.contextId === 'string' ? { contextId: record.contextId } : {}),
|
|
73
|
+
...(typeof record.summary === 'string' ? { summary: record.summary } : {}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=turn-request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-request.js","sourceRoot":"","sources":["../../src/copilot/turn-request.ts"],"names":[],"mappings":"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"}
|